// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
pragma abicoder v2;
import "@openzeppelin/contracts/metatx/ERC2771Context.sol";
import "@openzeppelin/contracts/metatx/MinimalForwarder.sol";
import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol";
import "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol";
contract Registry is ERC2771Context {
event Registered(address indexed who, string name);
mapping(address => string) public names;
mapping(string => address) public owners;
ISwapRouter public immutable swapRouter;
//kovan addresses
address public constant DAI = 0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa; // kovan
address public constant WETH9 = 0xd0A1E359811322d97991E03f863a0C30C2cF029C; // kovan
//ignore for now
address public constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
// For this example, we will set the pool fee to 0.3%.
uint24 public constant poolFee = 3000;
constructor(
MinimalForwarder forwarder,
ISwapRouter _swapRouter // Initialize trusted forwarder
) ERC2771Context(address(forwarder)) {
swapRouter = _swapRouter;
}
function swapExactInputSingle(uint256 amountIn)
internal
returns (uint256 amountOut)
{
// msg.sender must approve this contract
// Transfer the specified amount of DAI to this contract.
TransferHelper.safeTransferFrom(
DAI,
msg.sender,
address(this),
amountIn
);
// Approve the router to spend DAI.
TransferHelper.safeApprove(DAI, address(swapRouter), amountIn);
// Naively set amountOutMinimum to 0. In production, use an oracle or other data source to choose a safer value for amountOutMinimum.
// We also set the sqrtPriceLimitx96 to be 0 to ensure we swap our exact input amount.
ISwapRouter.ExactInputSingleParams memory params = ISwapRouter
.ExactInputSingleParams({
tokenIn: DAI,
tokenOut: WETH9,
fee: poolFee,
recipient: msg.sender,
deadline: block.timestamp,
amountIn: amountIn,
amountOutMinimum: 0,
sqrtPriceLimitX96: 0
});
// The call to `exactInputSingle` executes the swap.
amountOut = swapRouter.exactInputSingle(params);
}
function register(string memory name) external {
require(owners[name] == address(0), "Name taken");
address owner = _msgSender(); // Changed from msg.sender
owners[name] = owner;
names[owner] = name;
swapExactInputSingle(10);
emit Registered(owner, name);
}
}
SO I modified the contract https://github.com/OpenZeppelin/workshops/tree/master/01-defender-meta-txs to include token swapping using UniswapV3 as a normal transaction, this works well, the swap and registration works fine but when I send it as a meta transaction, execution fails,
on the autotask, the transaction is successfully relayed
AUTOTASK START
2022-06-29T09:52:26.457Z INFO Relaying {
value: 0,
gas: 1000000,
nonce: '8',
to: '0x80071477cf8845F6917359e5Ae2132A966522a0E',
from: '0x84E5B4cf1B91EC15dD34E097B403B07175f72d35',
data: '0xf2c298be0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b5349474e45442054455354000000000000000000000000000000000000000000'
}
2022-06-29T09:52:31.389Z INFO Sent meta-tx: 0xcabf31a3c665e8e22825374cb2f36ea17b17a785f2982a1c8581c60ae7b4d535
END RequestId: 65010971-79dd-4525-a1f4-52b6a5d8a5a1
AUTOTASK COMPLETE.
but when I check the explorer, I get to see that it was reverted. here is the clone demo project -> https://github.com/Jeon316upzx/openZepDemo