Hi,I am trying to swap the two tokens using universal router Address = "0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD" in Sepolia test Network.
here is the code ,i used
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.17;
// Import the interface of the universal router contract
import 'https://github.com/Uniswap/universal-router/blob/main/contracts/interfaces/IUniversalRouter.sol';
import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol';
contract SwapDAIUSDC {
// Define the address of the universal router contract
address private UNIVERSAL_ROUTER = 0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD;
// Define the address of the DAI token
address private constant DAI = 0xb1452d2ee842f67a80F7286d5C0636B377D9F1d4;
// Define the address of the USDC token
address private constant USDC = 0x3AAe6DC6449AD4603B9fCeD099FA062EdFcE6c1e;
// Create a variable to store the instance of the universal router contract
IUniversalRouter public universalRouter;
constructor() {
// Initialize the universal router contract
universalRouter = IUniversalRouter(UNIVERSAL_ROUTER);
}
// A function to swap DAI for USDC
function swapDAIUSDC(uint256 daiAmount, uint256 usdcAmount) external {
uint256 deadline = block.timestamp + 10;
// Approve the router contract to spend DAI
IERC20(DAI).approve(UNIVERSAL_ROUTER, daiAmount);
// Create an array of commands
bytes memory commands = new bytes(1);
// The command is to swap DAI for USDC on Uniswap V2
commands[0] = 0x09; // The command value for V2_SWAP_EXACT_IN
// Create an array of inputs
bytes[] memory inputs = new bytes[](1);
// The input for the command is the token amount, the minimum output amount, the path of the token pair, and the recipient address
inputs[0] = abi.encode(daiAmount, usdcAmount, [DAI, USDC], msg.sender);
// Call the execute function of the universal router contract
universalRouter.execute(commands, inputs, deadline);
}
}
when i tried to call the swapDAIUSDC function ,it throws gas estimation error.
can anyone help me on this.
And in case you're worried that this is a recent change on GitHub only but not in the deployed contract, you can see these exact same constant values in the contract's verified code on etherscan.
Well, conceptually, you should not input usdcAmount from the outside, but rather, calculate that amount internally in your function, by calling the pool contract's getAmountsOut function.
So you need to import the IUniswapV2Router02 interface, and hard-code the address of that pool contract just as you do with the other hard-coded addresses.
I'm not sure if the payer is also the user in your case, so you should fill that up accordingly.
You might also need to replace [DAI, USDC], which is a static array of 2 addresses, with a dynamic array which consists of the same 2 addresses; here is how you can initialize such an array:
NP, note the additional stuff that I gradually added in the answer above.
Also, keep in mind that the value of usdcAmount specifies the minimum return of USDC.
If the swap returns less than that, then the transaction will revert, hence I have previously pointed out that you should obtain this value internally in your function, rather than receiving it as input in this function.
Thanks mate,But i tried this again i got the gas estimation problem mate,
here is my updated Code
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.17;
// Import the interface of the universal router contract
import 'https://github.com/Uniswap/universal-router/blob/main/contracts/interfaces/IUniversalRouter.sol';
import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol';
contract SwapDAIUSDC {
// Define the address of the universal router contract
address private UNIVERSAL_ROUTER = 0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD;
// Define the address of the DAI token
address private constant DAI = 0xb1452d2ee842f67a80F7286d5C0636B377D9F1d4;
// Define the address of the USDC token
address private constant USDC = 0x3AAe6DC6449AD4603B9fCeD099FA062EdFcE6c1e;
// Create a variable to store the instance of the universal router contract
IUniversalRouter public universalRouter;
constructor() {
// Initialize the universal router contract
universalRouter = IUniversalRouter(UNIVERSAL_ROUTER);
}
// A function to swap DAI for USDC
function swapDAIUSDC(uint256 daiAmount, uint256 usdcAmount,bool payerIsUser) external {
uint256 deadline = block.timestamp + 10;
// Approve the router contract to spend DAI
IERC20(DAI).approve(UNIVERSAL_ROUTER, daiAmount);
// Create an array of commands
bytes memory commands = new bytes(1);
// The command is to swap DAI for USDC on Uniswap V3
commands[0] = 0x00; // The command value for V3_SWAP_EXACT_IN
// Create an array of inputs
bytes[] memory inputs = new bytes[](1);
address[] memory path = new address[](2);
path[0] = DAI;
path[1] = USDC;
// The input for the command is the token amount, the minimum output amount, the path of the token pair, and the recipient address
// inputs[0] = abi.encode(daiAmount, usdcAmount, [DAI, USDC], address(this));
inputs[0] = abi.encode(address(this), daiAmount, usdcAmount, [DAI, USDC], payerIsUser);
// Call the execute function of the universal router contract
universalRouter.execute(commands, inputs, deadline);
}
}
The order of the encoded parameters which I gave you in above was for V2_SWAP_EXACT_IN (0x08), which is what you have originally used, now you're changing it "on the fly" to V3_SWAP_EXACT_IN (0x0)???
And that's coming after you've started with 0x09 instead of 0x08, which is something which you could have easily figured out beforehand!
Dude, please organize your research in a proper manner, and request for help only after you have gathered all the details correctly, WITHOUT changing these details during the session, otherwise the entire effort (of yourself, and more importantly - of the person who's trying to help you out) is wasted!
Sorry Mate, I didn't know this before, As per your guidance I tried 0x8, But I aim to do uniswapV3 after I did some research I got some documentation info, that I got to know for V3 it is 0x00, so only I used that.
I must note that your process of asking this question has been extremely sloppy; several things which I've pointed out to you throughout this thread were outright obvious mistakes, which you could have easily noticed if you had been even slightly more meticulous!!!
Sorry for the confusion mate,I know this is USDT and USDTs, Actually i deployed two ERC20 token for testing purpose,by using this i created a pair. For name sake only i gave the DAI and USDC in the Smart contract function.But actual name is USDT and USDTs.
What I suggest, is that instead of trying to execute the swap through the router, which ultimately executes it through the pool, you try to execute it directly through the pool yourself.
If it works, then the problem lies with how you interact with the router (i.e., the problem is in the input that you pass when you call universalRouter.execute).
If it doesn't work, then either there's a problem with the tokens that you've created, or there's a problem with the pool (pair) that you've created, preventing a successful swap.
For example, if there is no liquidity on that pool, then it will not be able to send anything in return.
Or perhaps one of your tokens implement a fee-on-transfer mechanism which causes the pool's swap function to revert upon detecting that fee.