Hey folks,
I've been experimenting with calling uniswapV3 using encoded data and the functionCallWithValue() function doesn't seem to be working properly for me. I'm sure I'm doing something wrong, but could someone please help me out?
I've deployed 2 mock tokens called Weth and USDC on Arbitrum testnet, and initialized the uniswap pool and added liquidity for those two specific tokens. I can provide additonal information on how I initialized and added liquidity to those pools if necessary, but I don't think that's the problem.
I'm experimenting using the functionCallWithValue because eventually in my project I need the simpleSwap contract to cause another contract to call the uniswap trade function
I also have the transaction hash of the failed transaction on arbiscan here: https://goerli.arbiscan.io/tx/0x6f12b37f2683ff73ccf6efde529195e5f22b40d98032af49bdfcc2e5fa024b0e (the affected contract is simpleSwapTest.sol)
Code to reproduce
SimpleSwapTest.sol
pragma solidity ^0.8.0;
pragma experimental ABIEncoderV2;
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { Address } from "@openzeppelin/contracts/utils/Address.sol";
import { AddressArrayUtils } from "../../../lib/AddressArrayUtils.sol";
import { IWETH } from "../../../interfaces/external/IWETH.sol";
import { ISwapRouter } from "../../../interfaces/external/ISwapRouter.sol";
import "hardhat/console.sol";
contract SimpleSwapTest {
using Address for address;
string internal constant SWAP_EXACT_OUTPUT = "exactOutputSingle((address,address,uint24,address,uint256,uint256,uint256,uint160))";
string internal constant SWAP_EXACT_INPUT = "exactInputSingle((address,address,uint24,address,uint256,uint256,uint256,uint160))";
IWETH public weth; // Weth contract address
IERC20 public usdc;
address public uniswapRouter;
constructor(
IWETH _weth,
IERC20 _usdc,
address _uniswapRouter
)
public
{
weth = _weth;
usdc = _usdc;
uniswapRouter = _uniswapRouter;
}
function trade(
address _sellComponent,
address _buyComponent,
uint256 _amount
) public {
uint256 approveAmount = 2**256 - 1;
IERC20(weth).approve(uniswapRouter, approveAmount);
IERC20(usdc).approve(uniswapRouter, approveAmount);
bytes memory callData = abi.encodeWithSignature(
SWAP_EXACT_OUTPUT,
ISwapRouter.ExactInputSingleParams(
_sellComponent,
_buyComponent,
3000,
address(this),
block.timestamp,
_amount,
1000,
0
)
);
uniswapRouter.functionCallWithValue(callData, 0);
}
}
JS testing script
const simpleSwapAddress = "0x807B64A0F3dBD76B6D36EE0C809cE8C175a815Bf"; //arbitrum goerli
const simpleSwapModuleInterface = await hre.ethers.getContractAt("SimpleSwapTest", simpleSwapAddress);
await simpleSwapModuleInterface.trade(wethAddress, usdcAddress, true,
ethers.utils.parseEther("1"));
console.log('simple swap trade completed');
Environment
Using: Hardhat on Arbitrum Goerli (testnet).