Nesse artigo iremos aprender a como utilizar o Uniswap V3.
Exemplos de troca com Uniswap V3
// SPDX-License-Identifier: MITpragma solidity ^0.8.13;contract UniswapV3SwapExamples {ISwapRouter constant router =ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564);function swapExactInputSingleHop(address tokenIn,address tokenOut,uint24 poolFee,uint amountIn) external returns (uint amountOut) {IERC20(tokenIn).transferFrom(msg.sender, address(this), amountIn);IERC20(tokenIn).approve(address(router), amountIn);ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({tokenIn: tokenIn,tokenOut: tokenOut,fee: poolFee,recipient: msg.sender,deadline: block.timestamp,amountIn: amountIn,amountOutMinimum: 0,sqrtPriceLimitX96: 0});amountOut = router.exactInputSingle(params);}function swapExactInputMultiHop(bytes calldata path,address tokenIn,uint amountIn) external returns (uint amountOut) {IERC20(tokenIn).transferFrom(msg.sender, address(this), amountIn);IERC20(tokenIn).approve(address(router), amountIn);ISwapRouter.ExactInputParams memory params = ISwapRouter.ExactInputParams({path: path,recipient: msg.sender,deadline: block.timestamp,amountIn: amountIn,amountOutMinimum: 0});amountOut = router.exactInput(params);}}interface ISwapRouter {struct ExactInputSingleParams {address tokenIn;address tokenOut;uint24 fee;address recipient;uint deadline;uint amountIn;uint amountOutMinimum;uint160 sqrtPriceLimitX96;}/// @notice Troca o valor de um token pelo máximo possível de outro token/// @param params Os parâmetros necessários para a troca, codificados como ExactInputSingleParams em calldata/// @return amountOut O valor do token recebidofunction exactInputSingle(ExactInputSingleParams calldata params)externalpayablereturns (uint amountOut);struct ExactInputParams {bytes path;address recipient;uint deadline;uint amountIn;uint amountOutMinimum;}/// @notice Troca o valor de um token pelo máximo possível de outro ao longo do caminho especificado/// @param params Os parâmetros necessários para a troca multi-hop, codificados como ExactInputParams em calldata/// @return amountOut O valor do token recebidofunction exactInput(ExactInputParams calldata params)externalpayablereturns (uint amountOut);}interface IERC20 {function totalSupply() external view returns (uint);function balanceOf(address account) external view returns (uint);function transfer(address recipient, uint amount) external returns (bool);function allowance(address owner, address spender) external view returns (uint);function approve(address spender, uint amount) external returns (bool);function transferFrom(address sender,address recipient,uint amount) external returns (bool);event Transfer(address indexed from, address indexed to, uint value);event Approval(address indexed owner, address indexed spender, uint value);}interface IWETH is IERC20 {function deposit() external payable;function withdraw(uint amount) external;}
Testes com Foundry
Siga os passos abaixo:
- Copie e cole o código na pasta
test
do seu projeto Foundry
// SPDX-License-Identifier: MITpragma solidity ^0.8.13;import "forge-std/Test.sol";import "forge-std/console.sol";import "../src/UniswapV3SwapExamples.sol";address constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;address constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;address constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;contract UniV3Test is Test {IWETH private weth = IWETH(WETH);IERC20 private dai = IERC20(DAI);IERC20 private usdc = IERC20(USDC);UniswapV3SwapExamples private uni = new UniswapV3SwapExamples();function setUp() public {}function testSingleHop() public {weth.deposit{value: 1e18}();weth.approve(address(uni), 1e18);uint amountOut = uni.swapExactInputSingleHop(WETH, DAI, 3000, 1e18);console.log("DAI", amountOut);}function testMultiHop() public {weth.deposit{value: 1e18}();weth.approve(address(uni), 1e18);bytes memory path = abi.encodePacked(WETH,uint24(3000),USDC,uint24(100),DAI);uint amountOut = uni.swapExactInputMultiHop(path, WETH, 1e18);console.log("DAI", amountOut);}}
- Execute os seguintes comandos para executar o teste
FORK_URL=https://eth-mainnet.g.alchemy.com/v2/vtqCl_WPHwVu683HSlNFlL36pTaaWIJwforge test -vv --gas-report --fork-url $FORK_URL --match-path test/UniswapV3SwapExamples.test.sol
Links úteis: