Skip to content

Commit

Permalink
add tests for SwapRouter02
Browse files Browse the repository at this point in the history
  • Loading branch information
charlesjhongc committed Sep 10, 2023
1 parent f01552c commit b4fdf37
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 0 deletions.
50 changes: 50 additions & 0 deletions contracts/interfaces/IUniswapSwapRouter02.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

interface ISwapRouter02 {
function swapExactTokensForTokens(uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to) external payable returns (uint256 amountOut);

function swapTokensForExactTokens(uint256 amountOut, uint256 amountInMax, address[] calldata path, address to) external payable returns (uint256 amountIn);

struct ExactInputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 amountIn;
uint256 amountOutMinimum;
uint160 sqrtPriceLimitX96;
}

function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);

struct ExactInputParams {
bytes path;
address recipient;
uint256 amountIn;
uint256 amountOutMinimum;
}

function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);

struct ExactOutputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 amountOut;
uint256 amountInMaximum;
uint160 sqrtPriceLimitX96;
}

function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn);

struct ExactOutputParams {
bytes path;
address recipient;
uint256 amountOut;
uint256 amountInMaximum;
}

function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn);
}
73 changes: 73 additions & 0 deletions test/forkMainnet/UniAgent/SwapRouter02.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import { ISwapRouter02 } from "contracts/interfaces/IUniswapSwapRouter02.sol";
import { IUniswapRouterV2 } from "contracts/interfaces/IUniswapRouterV2.sol";
import { IUniswapV3Quoter } from "contracts/interfaces/IUniswapV3Quoter.sol";
import { IUniAgent } from "contracts/interfaces/IUniAgent.sol";
import { UniswapV3 } from "contracts/libraries/UniswapV3.sol";
import { BalanceSnapshot, Snapshot } from "test/utils/BalanceSnapshot.sol";
import { UniAgentTest } from "test/forkMainnet/UniAgent/Setup.t.sol";

contract SwapRouter02Test is UniAgentTest {
using BalanceSnapshot for Snapshot;

IUniswapRouterV2 v2Router = IUniswapRouterV2(UNISWAP_V2_ADDRESS);
IUniswapV3Quoter v3Quoter = IUniswapV3Quoter(UNISWAP_V3_QUOTER_ADDRESS);
uint256 defaultOutputAmount;
uint24 defaultFee = 3000;
uint24[] v3Fees = [defaultFee];

function setUp() public override {
super.setUp();
}

function testV2SwapExactTokensForTokens() public {
// USDT -> CRV
Snapshot memory userInputToken = BalanceSnapshot.take({ owner: user, token: defaultInputToken });
Snapshot memory recvOutputToken = BalanceSnapshot.take({ owner: recipient, token: defaultOutputToken });

uint256[] memory amounts = v2Router.getAmountsOut(defaultInputAmount, defaultPath);
uint256 outputAmount = amounts[amounts.length - 1];
uint256 minOutputAmount = (defaultOutputAmount * 95) / 100; // default 5% slippage tolerance
bytes memory payload = abi.encodeCall(ISwapRouter02.swapExactTokensForTokens, (defaultInputAmount, minOutputAmount, defaultPath, recipient));

vm.prank(user);
uniAgent.swap(IUniAgent.RouterType.SwapRouter02, defaultInputToken, defaultInputAmount, payload, defaultUserPermit);

userInputToken.assertChange(-int256(defaultInputAmount));
// recipient should receive exact amount of quote from Uniswap
recvOutputToken.assertChange(int256(outputAmount));
}

function testV3ExactInputSingle() public {
// USDT -> CRV
Snapshot memory userInputToken = BalanceSnapshot.take({ owner: user, token: defaultInputToken });
Snapshot memory recvOutputToken = BalanceSnapshot.take({ owner: recipient, token: defaultOutputToken });

bytes memory encodedPath = UniswapV3.encodePath(defaultPath, v3Fees);
defaultOutputAmount = v3Quoter.quoteExactInput(encodedPath, defaultInputAmount);
uint256 minOutputAmount = (defaultOutputAmount * 95) / 100; // default 5% slippage tolerance
bytes memory payload = abi.encodeCall(
ISwapRouter02.exactInputSingle,
(
ISwapRouter02.ExactInputSingleParams({
tokenIn: defaultInputToken,
tokenOut: defaultOutputToken,
fee: defaultFee,
recipient: recipient,
amountIn: defaultInputAmount,
amountOutMinimum: minOutputAmount,
sqrtPriceLimitX96: 0
})
)
);

vm.prank(user);
uniAgent.swap(IUniAgent.RouterType.SwapRouter02, defaultInputToken, defaultInputAmount, payload, defaultUserPermit);

userInputToken.assertChange(-int256(defaultInputAmount));
// recipient should receive exact amount of quote from Uniswap
recvOutputToken.assertChange(int256(defaultOutputAmount));
}
}

0 comments on commit b4fdf37

Please sign in to comment.