From c9ed84496e03594bda36d85c420adfbb9c378795 Mon Sep 17 00:00:00 2001 From: mikeyrf <23126274+mikeyrf@users.noreply.github.com> Date: Fri, 27 Oct 2023 15:41:33 -0400 Subject: [PATCH 01/15] init router v2 avalanche integration tests --- ...ynapseRouterV2.Integration.Avalanche.t.sol | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol diff --git a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol new file mode 100644 index 000000000..1104ff0a2 --- /dev/null +++ b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.17; + +import {Action, ActionLib, BridgeToken, DefaultParams, DestRequest, LimitedToken, SwapQuery} from "../../../../contracts/router/libs/Structs.sol"; +import {UniversalTokenLib} from "../../../../contracts/router/libs/UniversalToken.sol"; +import {IBridgeModule} from "../../../../contracts/router/interfaces/IBridgeModule.sol"; + +import {SynapseRouterV2IntegrationTest} from "./SynapseRouterV2.Integration.sol"; +import {SynapseRouterV2BridgeUtils} from "./SynapseRouterV2.BridgeUtils.sol"; +import {SynapseRouterV2CCTPUtils} from "./SynapseRouterV2.CCTPUtils.sol"; + +import {console} from "forge-std/Test.sol"; + +contract SynapseRouterV2AvalancheIntegrationTestFork is + SynapseRouterV2IntegrationTest, + SynapseRouterV2BridgeUtils, + SynapseRouterV2CCTPUtils +{ + uint256 public constant AVAX_BLOCK_NUMBER = 36998332; // 10-27-2023 + + address private constant AVAX_SWAP_QUOTER = 0x40d9dDE17D776bF057083E156578d2443685851C; + address private constant AVAX_SYN_ROUTER_V1 = 0x7E7A0e201FD38d3ADAA9523Da6C109a07118C96a; + address private constant AVAX_SYN_BRIDGE = 0xC05e61d0E7a63D27546389B7aD62FdFf5A91aACE; + address private constant AVAX_SYN_CCTP = 0xfB2Bfc368a7edfD51aa2cbEC513ad50edEa74E84; + address private constant AVAX_STABLE_POOL = 0xED2a7edd7413021d440b09D654f3b87712abAB66; + + // bridge tokens + address private constant NUSD = 0xCFc37A6AB183dd4aED08C204D1c2773c0b1BDf46; + address private constant SYN = 0x1f1E7c893855525b303f99bDF5c3c05Be09ca251; + address private constant NETH = 0x19E1ae0eE35c0404f835521146206595d37981ae; + address private constant WSOHM = 0x240E332Cd26AaE10622B24160D23425A17256F5d; + address private constant NFD = 0xf1293574EE43950E7a8c9F1005Ff097A9A713959; + address private constant GOHM = 0x321E7092a180BB43555132ec53AaA65a5bF84251; + address private constant WAVAX = 0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7; + address private constant GMX = 0x62edc0692BD897D2295872a9FFCac5425011c661; + address private constant UST = 0xE97097dE8d6A17Be3c39d53AE63347706dCf8f43; + address private constant NEWO = 0x4Bfc90322dD638F81F034517359BD447f8E0235a; + address private constant BTC_B = 0x152b9d0FdC40C096757F570A51E494bd4b943E50; + address private constant SDT = 0xCCBf7c451F81752F7d2237F2c18C371E6e089E69; + address private constant JEWEL = 0x997Ddaa07d716995DE90577C123Db411584E5E46; + address private constant SFI = 0xc2Bf0A1f7D8Da50D608bc96CF701110d4A438312; + address private constant H2O = 0xC6b11a4Fd833d1117E9D312c02865647cd961107; + + // supported tokens (for adapter swaps) + address private constant USDC_E = 0xA7D7079b0FEaD91F3e65f86E8915Cb59c1a4C664; + address private constant DAI_E = 0xd586E7F844cEa2F87f50152665BCbc2C279D8d70; + address private constant USDT_E = 0xc7198437980c041c805A1EDcbA50c1Ce5db95118; + address private constant AVWETH = 0x53f7c5869a859F0AeC3D334ee8B4Cf01E3492f21; + + constructor() SynapseRouterV2IntegrationTest("avalanche", AVAX_BLOCK_NUMBER, AVAX_SWAP_QUOTER) {} + + function afterBlockchainForked() public virtual override { + synapseLocalBridgeConfig = AVAX_SYN_ROUTER_V1; + synapseBridge = AVAX_SYN_BRIDGE; + synapseCCTP = AVAX_SYN_CCTP; + } + + function addExpectedTokens() public virtual override { + addExpectedToken(NUSD, "nUSD"); + addExpectedToken(USDC_E, "USDC.e"); + addExpectedToken(DAI_E, "DAI.e"); + addExpectedToken(USDT_E, "USDT.e"); + addExpectedToken(NETH, "nETH"); + addExpectedToken(AVWETH, "avWETH"); + } + + // testing CCTP, synapse bridge + function addExpectedModules() public virtual override { + // bridgeModules[0] = SynapseBridgeModule + deploySynapseBridgeModule(); + addExpectedModule(synapseBridgeModule, "SynapseBridgeModule"); + + // bridgeModules[1] = SynapseCCTPModule + deploySynapseCCTPModule(); + addExpectedModule(synapseCCTPModule, "SynapseCCTPModule"); + } + + function addExpectedBridgeTokens() public virtual override {} +} From 5a1f6243eaf5d7ebe0e6ca417fecd5b9925cf923 Mon Sep 17 00:00:00 2001 From: mikeyrf <23126274+mikeyrf@users.noreply.github.com> Date: Fri, 27 Oct 2023 16:29:45 -0400 Subject: [PATCH 02/15] test router v2 avax integration getBridgeTokens --- ...ynapseRouterV2.Integration.Avalanche.t.sol | 74 ++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol index 1104ff0a2..60d84ea41 100644 --- a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol +++ b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol @@ -40,6 +40,7 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is address private constant JEWEL = 0x997Ddaa07d716995DE90577C123Db411584E5E46; address private constant SFI = 0xc2Bf0A1f7D8Da50D608bc96CF701110d4A438312; address private constant H2O = 0xC6b11a4Fd833d1117E9D312c02865647cd961107; + address private constant USDC = 0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E; // supported tokens (for adapter swaps) address private constant USDC_E = 0xA7D7079b0FEaD91F3e65f86E8915Cb59c1a4C664; @@ -60,6 +61,7 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is addExpectedToken(USDC_E, "USDC.e"); addExpectedToken(DAI_E, "DAI.e"); addExpectedToken(USDT_E, "USDT.e"); + addExpectedToken(USDC, "CCTP.USDC"); addExpectedToken(NETH, "nETH"); addExpectedToken(AVWETH, "avWETH"); } @@ -75,5 +77,75 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is addExpectedModule(synapseCCTPModule, "SynapseCCTPModule"); } - function addExpectedBridgeTokens() public virtual override {} + function addExpectedBridgeTokens() public virtual override { + // add synapse bridge module bridge tokens + address[] memory originTokensBridgeStables = new address[](4); + originTokensBridgeStables[0] = NUSD; + originTokensBridgeStables[1] = DAI_E; + originTokensBridgeStables[2] = USDC_E; + originTokensBridgeStables[3] = USDT_E; + + address[] memory destinationTokensBridgeStables = new address[](4); + destinationTokensBridgeStables[0] = NUSD; + destinationTokensBridgeStables[1] = DAI_E; + destinationTokensBridgeStables[2] = USDC_E; + destinationTokensBridgeStables[3] = USDT_E; + + addExpectedBridgeToken( + BridgeToken({symbol: "nUSD", token: NUSD}), + originTokensBridgeStables, + destinationTokensBridgeStables + ); + + // add synapse bridge module bridge tokens for ETH + address[] memory originTokensBridgeETH = new address[](2); + originTokensBridgeETH[0] = NETH; + originTokensBridgeETH[1] = AVWETH; + + address[] memory destinationTokensBridgeETH = new address[](2); + destinationTokensBridgeETH[0] = NETH; + destinationTokensBridgeETH[1] = AVWETH; + + addExpectedBridgeToken( + BridgeToken({symbol: "nETH", token: NETH}), + originTokensBridgeETH, + destinationTokensBridgeETH + ); + + // add synapse cctp module bridge tokens + address[] memory originTokensCCTP = new address[](2); + originTokensCCTP[0] = USDC; + originTokensCCTP[1] = USDC_E; + + address[] memory destinationTokensCCTP = new address[](2); + destinationTokensCCTP[0] = USDC; + destinationTokensCCTP[1] = USDC_E; + + addExpectedBridgeToken( + BridgeToken({symbol: "CCTP.USDC", token: USDC}), + originTokensCCTP, + destinationTokensCCTP + ); + } + + function testGetBridgeTokens() public { + BridgeToken[] memory bridgeTokens = new BridgeToken[](16); + bridgeTokens[0] = BridgeToken({token: NUSD, symbol: "nUSD"}); + bridgeTokens[1] = BridgeToken({token: SYN, symbol: "SYN"}); + bridgeTokens[2] = BridgeToken({token: NETH, symbol: "nETH"}); + bridgeTokens[3] = BridgeToken({token: WSOHM, symbol: "wsOHM"}); + bridgeTokens[4] = BridgeToken({token: NFD, symbol: "NFD"}); + bridgeTokens[5] = BridgeToken({token: GOHM, symbol: "gOHM"}); + bridgeTokens[6] = BridgeToken({token: WAVAX, symbol: "AVAX"}); + bridgeTokens[7] = BridgeToken({token: GMX, symbol: "GMX"}); + bridgeTokens[8] = BridgeToken({token: UST, symbol: "UST"}); + bridgeTokens[9] = BridgeToken({token: NEWO, symbol: "NEWO"}); + bridgeTokens[10] = BridgeToken({token: BTC_B, symbol: "BTCB"}); + bridgeTokens[11] = BridgeToken({token: SDT, symbol: "SDT"}); + bridgeTokens[12] = BridgeToken({token: JEWEL, symbol: "JEWEL"}); + bridgeTokens[13] = BridgeToken({token: SFI, symbol: "SFI"}); + bridgeTokens[14] = BridgeToken({token: H2O, symbol: "H2O"}); + bridgeTokens[15] = BridgeToken({token: USDC, symbol: "CCTP.USDC"}); + checkBridgeTokenArrays(router.getBridgeTokens(), bridgeTokens); + } } From 5f369e1fceaeff2f8c309fe2f02d5d75d1cca62f Mon Sep 17 00:00:00 2001 From: mikeyrf <23126274+mikeyrf@users.noreply.github.com> Date: Mon, 30 Oct 2023 14:30:12 -0400 Subject: [PATCH 03/15] test router v2 avax getSupportedTokens --- ...ynapseRouterV2.Integration.Avalanche.t.sol | 73 ++++++++++++++++--- .../SynapseRouterV2.Integration.sol | 1 + 2 files changed, 65 insertions(+), 9 deletions(-) diff --git a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol index 60d84ea41..219336c2b 100644 --- a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol +++ b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol @@ -46,7 +46,8 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is address private constant USDC_E = 0xA7D7079b0FEaD91F3e65f86E8915Cb59c1a4C664; address private constant DAI_E = 0xd586E7F844cEa2F87f50152665BCbc2C279D8d70; address private constant USDT_E = 0xc7198437980c041c805A1EDcbA50c1Ce5db95118; - address private constant AVWETH = 0x53f7c5869a859F0AeC3D334ee8B4Cf01E3492f21; + address private constant WETH_E = 0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB; + address private constant USDT = 0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7; constructor() SynapseRouterV2IntegrationTest("avalanche", AVAX_BLOCK_NUMBER, AVAX_SWAP_QUOTER) {} @@ -63,7 +64,7 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is addExpectedToken(USDT_E, "USDT.e"); addExpectedToken(USDC, "CCTP.USDC"); addExpectedToken(NETH, "nETH"); - addExpectedToken(AVWETH, "avWETH"); + addExpectedToken(WETH_E, "WETH.e"); } // testing CCTP, synapse bridge @@ -79,11 +80,12 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is function addExpectedBridgeTokens() public virtual override { // add synapse bridge module bridge tokens - address[] memory originTokensBridgeStables = new address[](4); + address[] memory originTokensBridgeStables = new address[](5); originTokensBridgeStables[0] = NUSD; originTokensBridgeStables[1] = DAI_E; originTokensBridgeStables[2] = USDC_E; originTokensBridgeStables[3] = USDT_E; + originTokensBridgeStables[4] = USDC; address[] memory destinationTokensBridgeStables = new address[](4); destinationTokensBridgeStables[0] = NUSD; @@ -100,11 +102,11 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is // add synapse bridge module bridge tokens for ETH address[] memory originTokensBridgeETH = new address[](2); originTokensBridgeETH[0] = NETH; - originTokensBridgeETH[1] = AVWETH; + originTokensBridgeETH[1] = WETH_E; address[] memory destinationTokensBridgeETH = new address[](2); destinationTokensBridgeETH[0] = NETH; - destinationTokensBridgeETH[1] = AVWETH; + destinationTokensBridgeETH[1] = WETH_E; addExpectedBridgeToken( BridgeToken({symbol: "nETH", token: NETH}), @@ -113,13 +115,19 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is ); // add synapse cctp module bridge tokens - address[] memory originTokensCCTP = new address[](2); + address[] memory originTokensCCTP = new address[](5); originTokensCCTP[0] = USDC; - originTokensCCTP[1] = USDC_E; + originTokensCCTP[1] = NUSD; + originTokensCCTP[2] = USDC_E; + originTokensCCTP[3] = DAI_E; + originTokensCCTP[4] = USDT_E; - address[] memory destinationTokensCCTP = new address[](2); + address[] memory destinationTokensCCTP = new address[](5); destinationTokensCCTP[0] = USDC; - destinationTokensCCTP[1] = USDC_E; + destinationTokensCCTP[1] = NUSD; + destinationTokensCCTP[2] = USDC_E; + destinationTokensCCTP[3] = DAI_E; + destinationTokensCCTP[4] = USDT_E; addExpectedBridgeToken( BridgeToken({symbol: "CCTP.USDC", token: USDC}), @@ -148,4 +156,51 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is bridgeTokens[15] = BridgeToken({token: USDC, symbol: "CCTP.USDC"}); checkBridgeTokenArrays(router.getBridgeTokens(), bridgeTokens); } + + function testGetSupportedTokens() public { + address[] memory supportedTokens = new address[](22); + supportedTokens[0] = NUSD; + supportedTokens[1] = DAI_E; + supportedTokens[2] = USDC_E; + supportedTokens[3] = USDT_E; + supportedTokens[4] = NETH; + supportedTokens[5] = WETH_E; + supportedTokens[6] = USDC; + supportedTokens[7] = USDT; + supportedTokens[8] = SYN; + supportedTokens[9] = WSOHM; + supportedTokens[10] = NFD; + supportedTokens[11] = GOHM; + supportedTokens[12] = WAVAX; + supportedTokens[13] = GMX; + supportedTokens[14] = UST; + supportedTokens[15] = NEWO; + supportedTokens[16] = BTC_B; + supportedTokens[17] = SDT; + supportedTokens[18] = JEWEL; + supportedTokens[19] = SFI; + supportedTokens[20] = H2O; + supportedTokens[21] = UniversalTokenLib.ETH_ADDRESS; // AVAX + checkAddressArrays(router.getSupportedTokens(), supportedTokens); + } + + function testGetOriginBridgeTokens() public { + for (uint256 i = 0; i < expectedTokens.length; i++) { + console.log("tokenIn %s: %s [%s]", i, expectedTokens[i], tokenNames[expectedTokens[i]]); + checkBridgeTokenArrays( + router.getOriginBridgeTokens(expectedTokens[i]), + expectedOriginBridgeTokens[expectedTokens[i]] + ); + } + } + + function testGetDestinationBridgeTokens() public { + for (uint256 i = 0; i < expectedTokens.length; i++) { + console.log("tokenOut %s: %s [%s]", i, expectedTokens[i], tokenNames[expectedTokens[i]]); + checkBridgeTokenArrays( + router.getDestinationBridgeTokens(expectedTokens[i]), + expectedDestinationBridgeTokens[expectedTokens[i]] + ); + } + } } diff --git a/test/router/v2/integration/SynapseRouterV2.Integration.sol b/test/router/v2/integration/SynapseRouterV2.Integration.sol index 72fe4d11e..1796c1c75 100644 --- a/test/router/v2/integration/SynapseRouterV2.Integration.sol +++ b/test/router/v2/integration/SynapseRouterV2.Integration.sol @@ -293,6 +293,7 @@ abstract contract SynapseRouterV2IntegrationTest is IntegrationUtils { function checkAddressArrays(address[] memory actual, address[] memory expect) public { assertEq(actual.length, expect.length); for (uint256 i = 0; i < actual.length; i++) { + console.log("%s: %s", i, actual[i]); assertTrue(expect.contains(actual[i])); } } From 181dd5dec699e6eba992740225340294642ac785 Mon Sep 17 00:00:00 2001 From: mikeyrf <23126274+mikeyrf@users.noreply.github.com> Date: Mon, 30 Oct 2023 15:25:19 -0400 Subject: [PATCH 04/15] test router v2 integration avax getOriginAmountOut for stables --- ...ynapseRouterV2.Integration.Avalanche.t.sol | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol index 219336c2b..62e377472 100644 --- a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol +++ b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol @@ -203,4 +203,50 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is ); } } + + function testGetOriginAmountOut_inUSDCe_outNUSD() public { + address tokenIn = USDC_E; + string memory tokenSymbol = "nUSD"; + uint256 amountIn = getTestAmount(USDC_E); + + address pool = AVAX_STABLE_POOL; + uint8 indexFrom = 2; + uint8 indexTo = 0; + uint256 amountOut = calculateSwap(pool, indexFrom, indexTo, amountIn); + + SwapQuery memory query = router.getOriginAmountOut(tokenIn, tokenSymbol, amountIn); + assertEq(query.routerAdapter, address(router)); + assertEq(query.tokenOut, NUSD); + assertEq(query.minAmountOut, amountOut); + assertEq(query.deadline, type(uint256).max); + assertEq(query.rawParams, getSwapParams(pool, indexFrom, indexTo)); + } + + function testGetOriginAmountOut_inNUSD_outNUSD() public { + address tokenIn = NUSD; + string memory tokenSymbol = "nUSD"; + uint256 amountIn = getTestAmount(NUSD); + + uint256 amountOut = amountIn; + SwapQuery memory query = router.getOriginAmountOut(tokenIn, tokenSymbol, amountIn); + assertEq(query.routerAdapter, address(0)); + assertEq(query.tokenOut, NUSD); + assertEq(query.minAmountOut, amountOut); + assertEq(query.deadline, type(uint256).max); + assertEq(query.rawParams, bytes("")); + } + + /// @dev UNI not supported so amount out should produce zero + function testGetOriginAmountOut_inUSDCe_outUNI() public { + address tokenIn = USDC_E; + string memory tokenSymbol = "UNI"; + uint256 amountIn = getTestAmount(USDC_E); + + SwapQuery memory query = router.getOriginAmountOut(tokenIn, tokenSymbol, amountIn); + assertEq(query.routerAdapter, address(0)); + assertEq(query.tokenOut, address(0)); + assertEq(query.minAmountOut, 0); + assertEq(query.deadline, 0); + assertEq(query.rawParams, bytes("")); + } } From cf08af214c8a02a86c703ba049de5e57317b33ab Mon Sep 17 00:00:00 2001 From: mikeyrf <23126274+mikeyrf@users.noreply.github.com> Date: Tue, 31 Oct 2023 14:00:16 -0400 Subject: [PATCH 05/15] test router v2 integration avax getOriginAmountOut WETH --- ...ynapseRouterV2.Integration.Avalanche.t.sol | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol index 62e377472..8fcf4f4c4 100644 --- a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol +++ b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol @@ -65,6 +65,7 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is addExpectedToken(USDC, "CCTP.USDC"); addExpectedToken(NETH, "nETH"); addExpectedToken(WETH_E, "WETH.e"); + // TODO: WAVAX } // testing CCTP, synapse bridge @@ -249,4 +250,42 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is assertEq(query.deadline, 0); assertEq(query.rawParams, bytes("")); } + + function testGetOriginAmountOut_inUSDCe_outUSDC() public { + address tokenIn = USDC_E; + string memory tokenSymbol = "CCTP.USDC"; + uint256 amountIn = 990000000000; // 990K USDC + + address pool = 0x9A2Dea7B81cfe3e0011D44D41c5c5142b8d9abdF; // LinkedPool + uint8 indexFrom = 4; + uint8 indexTo = 0; + uint256 amountOut = calculateSwap(pool, indexFrom, indexTo, amountIn); + + SwapQuery memory query = router.getOriginAmountOut(tokenIn, tokenSymbol, amountIn); + assertEq(query.routerAdapter, address(router)); + assertEq(query.tokenOut, USDC); + assertEq(query.minAmountOut, amountOut); + assertEq(query.deadline, type(uint256).max); + assertEq(query.rawParams, getSwapParams(pool, indexFrom, indexTo)); + } + + /// @dev not enough liquidity to test CCTP max bridged amount out + + function testGetOriginAmountOut_inWETHe_outNETH() public { + address tokenIn = WETH_E; + string memory tokenSymbol = "nETH"; + uint256 amountIn = 10e18; + + address pool = 0xdd60483Ace9B215a7c019A44Be2F22Aa9982652E; // Aave swap wrapper + uint8 indexFrom = 1; + uint8 indexTo = 0; + uint256 amountOut = calculateSwap(pool, indexFrom, indexTo, amountIn); + + SwapQuery memory query = router.getOriginAmountOut(tokenIn, tokenSymbol, amountIn); + assertEq(query.routerAdapter, address(router)); + assertEq(query.tokenOut, NETH); + assertEq(query.minAmountOut, amountOut); + assertEq(query.deadline, type(uint256).max); + assertEq(query.rawParams, getSwapParams(pool, indexFrom, indexTo)); + } } From 2ca2e5e58aa3420fc4fe156b6737e18c55633617 Mon Sep 17 00:00:00 2001 From: mikeyrf <23126274+mikeyrf@users.noreply.github.com> Date: Tue, 31 Oct 2023 14:59:08 -0400 Subject: [PATCH 06/15] test router v2 integration avax getDestinationAmountOut --- ...ynapseRouterV2.Integration.Avalanche.t.sol | 65 ++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol index 8fcf4f4c4..0f54039cc 100644 --- a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol +++ b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol @@ -65,7 +65,7 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is addExpectedToken(USDC, "CCTP.USDC"); addExpectedToken(NETH, "nETH"); addExpectedToken(WETH_E, "WETH.e"); - // TODO: WAVAX + // TODO: WAVAX, GMX } // testing CCTP, synapse bridge @@ -288,4 +288,67 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is assertEq(query.deadline, type(uint256).max); assertEq(query.rawParams, getSwapParams(pool, indexFrom, indexTo)); } + + // TODO: testGetOriginAmountOut_inGMX_outGMX() + + function testGetDestinationAmountOut_inNUSD_outUSDCe() public { + uint256 amountIn = 10000 * 1e18; // @dev need larger amount to be larger than fee amount + DestRequest memory request = DestRequest({symbol: "nUSD", amountIn: amountIn}); + + address tokenOut = USDC_E; + address pool = AVAX_STABLE_POOL; + uint8 indexFrom = 0; + uint8 indexTo = 2; + + uint256 fee = (amountIn * 0.0008e10) / 10**10; + uint256 amountInLessBridgeFees = amountIn - fee; + uint256 amountOut = calculateSwap(pool, indexFrom, indexTo, amountInLessBridgeFees); + + SwapQuery memory query = router.getDestinationAmountOut(request, tokenOut); + assertEq(query.routerAdapter, address(router)); + assertEq(query.tokenOut, tokenOut); + assertEq(query.minAmountOut, amountOut); + assertEq(query.deadline, type(uint256).max); + assertEq(query.rawParams, getSwapParams(pool, indexFrom, indexTo)); + } + + function testGetDestinationAmountOut_inNUSD_outNUSD() public { + uint256 amountIn = 10000 * 1e18; // @dev need larger amount to be larger than fee amount + DestRequest memory request = DestRequest({symbol: "nUSD", amountIn: amountIn}); + + address tokenOut = NUSD; + uint256 fee = (amountIn * 0.0008e10) / 10**10; + uint256 amountInLessBridgeFees = amountIn - fee; + uint256 amountOut = amountInLessBridgeFees; + + SwapQuery memory query = router.getDestinationAmountOut(request, tokenOut); + assertEq(query.routerAdapter, address(0)); + assertEq(query.tokenOut, tokenOut); + assertEq(query.minAmountOut, amountOut); + assertEq(query.deadline, type(uint256).max); + assertEq(query.rawParams, bytes("")); + } + + function testGetDestinationAmountOut_inNETH_outWETHe() public { + uint256 amountIn = 10000 * 1e18; // @dev need larger amount to be larger than fee amount + DestRequest memory request = DestRequest({symbol: "nETH", amountIn: amountIn}); + + address tokenOut = WETH_E; + uint256 fee = (amountIn * 0.0006e10) / 10**10; + + address pool = 0xdd60483Ace9B215a7c019A44Be2F22Aa9982652E; // Aave swap wrapper + uint8 indexFrom = 0; + uint8 indexTo = 1; + uint256 amountInLessBridgeFees = amountIn - fee; + uint256 amountOut = calculateSwap(pool, indexFrom, indexTo, amountInLessBridgeFees); + + SwapQuery memory query = router.getDestinationAmountOut(request, tokenOut); + assertEq(query.routerAdapter, address(router)); + assertEq(query.tokenOut, tokenOut); + assertEq(query.minAmountOut, amountOut); + assertEq(query.deadline, type(uint256).max); + assertEq(query.rawParams, getSwapParams(pool, indexFrom, indexTo)); + } + + // TODO: testGetDestinationAmountOut_inGMX_outGMX() public {} } From babbd9a4ed4ba939ae0474df29043f301fa91f3d Mon Sep 17 00:00:00 2001 From: mikeyrf <23126274+mikeyrf@users.noreply.github.com> Date: Tue, 31 Oct 2023 15:13:47 -0400 Subject: [PATCH 07/15] add GMX, WAVAX to expected tokens for router v2 avax integration tests --- ...ynapseRouterV2.Integration.Avalanche.t.sol | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol index 0f54039cc..a6229ccc2 100644 --- a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol +++ b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol @@ -65,7 +65,8 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is addExpectedToken(USDC, "CCTP.USDC"); addExpectedToken(NETH, "nETH"); addExpectedToken(WETH_E, "WETH.e"); - // TODO: WAVAX, GMX + addExpectedToken(WAVAX, "WAVAX"); + addExpectedToken(GMX, "GMX"); } // testing CCTP, synapse bridge @@ -115,6 +116,34 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is destinationTokensBridgeETH ); + // add synapse bridge module bridge tokens for WAVAX + address[] memory originTokensBridgeWAVAX = new address[](2); + originTokensBridgeWAVAX[0] = WAVAX; + originTokensBridgeWAVAX[1] = UniversalTokenLib.ETH_ADDRESS; + + address[] memory destinationTokensBridgeWAVAX = new address[](2); + destinationTokensBridgeWAVAX[0] = WAVAX; + destinationTokensBridgeWAVAX[1] = UniversalTokenLib.ETH_ADDRESS; + + addExpectedBridgeToken( + BridgeToken({symbol: "AVAX", token: WAVAX}), + originTokensBridgeWAVAX, + destinationTokensBridgeWAVAX + ); + + // add synapse bridge module bridge tokens for GMX + address[] memory originTokensBridgeGMX = new address[](1); + originTokensBridgeGMX[0] = GMX; + + address[] memory destinationTokensBridgeGMX = new address[](1); + destinationTokensBridgeGMX[0] = GMX; + + addExpectedBridgeToken( + BridgeToken({symbol: "GMX", token: GMX}), + originTokensBridgeGMX, + destinationTokensBridgeGMX + ); + // add synapse cctp module bridge tokens address[] memory originTokensCCTP = new address[](5); originTokensCCTP[0] = USDC; From 2014e67de8679cc78acd0d5318f1532a3993f419 Mon Sep 17 00:00:00 2001 From: mikeyrf <23126274+mikeyrf@users.noreply.github.com> Date: Tue, 31 Oct 2023 15:45:39 -0400 Subject: [PATCH 08/15] test router v2 getOriginAmountOut, getDestinationAmountOut for GMX, WAVAX --- ...ynapseRouterV2.Integration.Avalanche.t.sol | 107 +++++++++++++++++- 1 file changed, 105 insertions(+), 2 deletions(-) diff --git a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol index a6229ccc2..1c4a9febb 100644 --- a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol +++ b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol @@ -318,7 +318,54 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is assertEq(query.rawParams, getSwapParams(pool, indexFrom, indexTo)); } - // TODO: testGetOriginAmountOut_inGMX_outGMX() + function testGetOriginAmountOut_inWAVAX_outWAVAX() public { + address tokenIn = WAVAX; + string memory tokenSymbol = "AVAX"; + uint256 amountIn = getTestAmount(WAVAX); + + uint256 amountOut = amountIn; + SwapQuery memory query = router.getOriginAmountOut(tokenIn, tokenSymbol, amountIn); + assertEq(query.routerAdapter, address(0)); + assertEq(query.tokenOut, WAVAX); + assertEq(query.minAmountOut, amountOut); + assertEq(query.deadline, type(uint256).max); + assertEq(query.rawParams, bytes("")); + } + + function testGetOriginAmountOut_inAVAX_outWAVAX() public { + address tokenIn = UniversalTokenLib.ETH_ADDRESS; + string memory tokenSymbol = "AVAX"; + uint256 amountIn = getTestAmount(WAVAX); + + DefaultParams memory params = DefaultParams({ + action: Action.HandleEth, + pool: address(0), + tokenIndexFrom: type(uint8).max, + tokenIndexTo: type(uint8).max + }); + + uint256 amountOut = amountIn; + SwapQuery memory query = router.getOriginAmountOut(tokenIn, tokenSymbol, amountIn); + assertEq(query.routerAdapter, address(router)); + assertEq(query.tokenOut, WAVAX); + assertEq(query.minAmountOut, amountOut); + assertEq(query.deadline, type(uint256).max); + assertEq(query.rawParams, abi.encode(params)); + } + + function testGetOriginAmountOut_inGMX_outGMX() public { + address tokenIn = GMX; + string memory tokenSymbol = "GMX"; + uint256 amountIn = getTestAmount(GMX); + + uint256 amountOut = amountIn; + SwapQuery memory query = router.getOriginAmountOut(tokenIn, tokenSymbol, amountIn); + assertEq(query.routerAdapter, address(0)); + assertEq(query.tokenOut, GMX); + assertEq(query.minAmountOut, amountOut); + assertEq(query.deadline, type(uint256).max); + assertEq(query.rawParams, bytes("")); + } function testGetDestinationAmountOut_inNUSD_outUSDCe() public { uint256 amountIn = 10000 * 1e18; // @dev need larger amount to be larger than fee amount @@ -379,5 +426,61 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is assertEq(query.rawParams, getSwapParams(pool, indexFrom, indexTo)); } - // TODO: testGetDestinationAmountOut_inGMX_outGMX() public {} + function testGetDestinationAmountOut_inWAVAX_outWAVAX() public { + uint256 amountIn = 1000 * 1e18; // @dev need larger amount to be larger than fee amount + DestRequest memory request = DestRequest({symbol: "AVAX", amountIn: amountIn}); + + address tokenOut = WAVAX; + uint256 fee = (amountIn * 0.0004e10) / 10**10; + uint256 amountInLessBridgeFees = amountIn - fee; + uint256 amountOut = amountInLessBridgeFees; + + SwapQuery memory query = router.getDestinationAmountOut(request, tokenOut); + assertEq(query.routerAdapter, address(0)); + assertEq(query.tokenOut, tokenOut); + assertEq(query.minAmountOut, amountOut); + assertEq(query.deadline, type(uint256).max); + assertEq(query.rawParams, bytes("")); + } + + function testGetDestinationAmountOut_inWAVAX_outAVAX() public { + uint256 amountIn = 1000 * 1e18; // @dev need larger amount to be larger than fee amount + DestRequest memory request = DestRequest({symbol: "AVAX", amountIn: amountIn}); + + address tokenOut = UniversalTokenLib.ETH_ADDRESS; + uint256 fee = (amountIn * 0.0004e10) / 10**10; + uint256 amountInLessBridgeFees = amountIn - fee; + uint256 amountOut = amountInLessBridgeFees; + + DefaultParams memory params = DefaultParams({ + action: Action.HandleEth, + pool: address(0), + tokenIndexFrom: type(uint8).max, + tokenIndexTo: type(uint8).max + }); + + SwapQuery memory query = router.getDestinationAmountOut(request, tokenOut); + assertEq(query.routerAdapter, address(router)); + assertEq(query.tokenOut, tokenOut); + assertEq(query.minAmountOut, amountOut); + assertEq(query.deadline, type(uint256).max); + assertEq(query.rawParams, abi.encode(params)); + } + + function testGetDestinationAmountOut_inGMX_outGMX() public { + uint256 amountIn = 1000 * 1e18; // @dev need larger amount to be larger than fee amount + DestRequest memory request = DestRequest({symbol: "GMX", amountIn: amountIn}); + + address tokenOut = GMX; + uint256 fee = (amountIn * 0.0005e10) / 10**10; + uint256 amountInLessBridgeFees = amountIn - fee; + uint256 amountOut = amountInLessBridgeFees; + + SwapQuery memory query = router.getDestinationAmountOut(request, tokenOut); + assertEq(query.routerAdapter, address(0)); + assertEq(query.tokenOut, tokenOut); + assertEq(query.minAmountOut, amountOut); + assertEq(query.deadline, type(uint256).max); + assertEq(query.rawParams, bytes("")); + } } From 4dd71b05988d1eb8b25478bd722a772750b3a50b Mon Sep 17 00:00:00 2001 From: mikeyrf <23126274+mikeyrf@users.noreply.github.com> Date: Tue, 31 Oct 2023 16:13:30 -0400 Subject: [PATCH 09/15] test router v2 integration avax synapseBridge --- ...ynapseRouterV2.Integration.Avalanche.t.sol | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol index 1c4a9febb..b39b637bf 100644 --- a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol +++ b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol @@ -483,4 +483,84 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is assertEq(query.deadline, type(uint256).max); assertEq(query.rawParams, bytes("")); } + + function testSynapseBridge_avalancheToEthereum_inNUSD_outNUSD() public { + address module = expectedModules[0]; // Synapse bridge module + + SwapQuery memory originQuery; + SwapQuery memory destQuery; + + redeemEvent = RedeemEvent({to: recipient, chainId: 1, token: NUSD, amount: getTestAmount(NUSD)}); + initiateBridge( + expectRedeemEvent, + 1, // mainnet + module, + NUSD, + originQuery, + destQuery + ); + } + + function testSynapseBridge_avalancheToEthereum_inUSDCe_outNUSD() public { + address module = expectedModules[0]; + + address pool = AVAX_STABLE_POOL; + DefaultParams memory params = DefaultParams({ + action: Action.Swap, + pool: pool, // stableswap pool on arbitrum + tokenIndexFrom: 2, + tokenIndexTo: 0 + }); + SwapQuery memory originQuery = SwapQuery({ + routerAdapter: address(router), + tokenOut: NUSD, + minAmountOut: 0, + deadline: type(uint256).max, + rawParams: abi.encode(params) + }); + SwapQuery memory destQuery; + + uint256 amount = calculateSwap(pool, 2, 0, getTestAmount(USDC_E)); + redeemEvent = RedeemEvent({to: recipient, chainId: 1, token: NUSD, amount: amount}); + initiateBridge( + expectRedeemEvent, + 1, // mainnet + module, + USDC_E, + originQuery, + destQuery + ); + } + + function testSynapseBridge_avalancheToEthereum_inWETHe_outNETH() public { + address module = expectedModules[0]; // Synapse bridge module + + address pool = 0xdd60483Ace9B215a7c019A44Be2F22Aa9982652E; // Aave swap wrapper + DefaultParams memory params = DefaultParams({ + action: Action.Swap, + pool: pool, // linked pool + tokenIndexFrom: 1, + tokenIndexTo: 0 + }); + SwapQuery memory originQuery = SwapQuery({ + routerAdapter: address(router), + tokenOut: NETH, + minAmountOut: 0, + deadline: type(uint256).max, + rawParams: abi.encode(params) + }); + SwapQuery memory destQuery; + + uint256 amount = getTestAmount(WETH_E); + uint256 amountOut = calculateSwap(pool, 1, 0, amount); + redeemEvent = RedeemEvent({to: recipient, chainId: 1, token: NETH, amount: amountOut}); + initiateBridge( + expectRedeemEvent, + 1, // mainnet + module, + WETH_E, + originQuery, + destQuery + ); + } } From c244c54131cb1ecf9842deb0343206a1f4262e2c Mon Sep 17 00:00:00 2001 From: mikeyrf <23126274+mikeyrf@users.noreply.github.com> Date: Tue, 31 Oct 2023 17:01:00 -0400 Subject: [PATCH 10/15] test router v2 integration avax synapseBridge --- ...ynapseRouterV2.Integration.Avalanche.t.sol | 162 ++++++++++++++++-- 1 file changed, 149 insertions(+), 13 deletions(-) diff --git a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol index b39b637bf..5bae61f47 100644 --- a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol +++ b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol @@ -532,33 +532,169 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is ); } - function testSynapseBridge_avalancheToEthereum_inWETHe_outNETH() public { - address module = expectedModules[0]; // Synapse bridge module + function testSynapseBridge_avalancheToEthereum_inNUSD_outUSDC() public { + address module = expectedModules[0]; - address pool = 0xdd60483Ace9B215a7c019A44Be2F22Aa9982652E; // Aave swap wrapper - DefaultParams memory params = DefaultParams({ + SwapQuery memory originQuery; + DefaultParams memory destParams = DefaultParams({ + action: Action.RemoveLiquidity, + pool: 0x1116898DdA4015eD8dDefb84b6e8Bc24528Af2d8, // stableswap pool on mainnet + tokenIndexFrom: 0, + tokenIndexTo: 1 + }); + SwapQuery memory destQuery = SwapQuery({ + routerAdapter: 0x1116898DdA4015eD8dDefb84b6e8Bc24528Af2d8, // irrelevant for test + tokenOut: 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48, // USDC on mainnet + minAmountOut: 0, + deadline: type(uint256).max, + rawParams: abi.encode(destParams) + }); + + redeemAndRemoveEvent = RedeemAndRemoveEvent({ + to: recipient, + chainId: 1, + token: NUSD, + amount: getTestAmount(NUSD), + swapTokenIndex: 1, + swapMinAmount: 0, + swapDeadline: type(uint256).max + }); + initiateBridge( + expectRedeemAndRemoveEvent, + 1, // mainnet + module, + NUSD, + originQuery, + destQuery + ); + } + + function testSynapseBridge_avalancheToEthereum_inUSDCe_outUSDC() public { + address module = expectedModules[0]; + + address pool = AVAX_STABLE_POOL; + uint256 amount = calculateSwap(pool, 2, 0, getTestAmount(USDC_E)); + + DefaultParams memory originParams = DefaultParams({ action: Action.Swap, - pool: pool, // linked pool - tokenIndexFrom: 1, + pool: pool, // stableswap pool on arbitrum + tokenIndexFrom: 2, tokenIndexTo: 0 }); SwapQuery memory originQuery = SwapQuery({ routerAdapter: address(router), - tokenOut: NETH, + tokenOut: NUSD, + minAmountOut: amount, + deadline: type(uint256).max, + rawParams: abi.encode(originParams) + }); + + DefaultParams memory destParams = DefaultParams({ + action: Action.RemoveLiquidity, + pool: 0x1116898DdA4015eD8dDefb84b6e8Bc24528Af2d8, // stableswap pool on mainnet + tokenIndexFrom: 0, + tokenIndexTo: 1 + }); + SwapQuery memory destQuery = SwapQuery({ + routerAdapter: 0x1116898DdA4015eD8dDefb84b6e8Bc24528Af2d8, // irrelevant for test + tokenOut: 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48, // USDC on mainnet minAmountOut: 0, deadline: type(uint256).max, - rawParams: abi.encode(params) + rawParams: abi.encode(destParams) + }); + + redeemAndRemoveEvent = RedeemAndRemoveEvent({ + to: recipient, + chainId: 1, + token: NUSD, + amount: originQuery.minAmountOut, + swapTokenIndex: 1, + swapMinAmount: 0, + swapDeadline: type(uint256).max + }); + initiateBridge( + expectRedeemAndRemoveEvent, + 1, // mainnet + module, + USDC_E, + originQuery, + destQuery + ); + } + + function testSynapseBridge_avalancheToEthereum_inGMX_outGMX() public { + address module = expectedModules[0]; // Synapse bridge module + + SwapQuery memory originQuery; + SwapQuery memory destQuery; + + depositEvent = DepositEvent({ + to: recipient, + chainId: 1, // mainnet + token: GMX, + amount: getTestAmount(GMX) }); + initiateBridge( + expectDepositEvent, + 1, // mainnet + module, + GMX, + originQuery, + destQuery + ); + } + + function testSynapseBridge_avalancheToEthereum_inWAVAX_outWAVAX() public { + address module = expectedModules[0]; // Synapse bridge module + + SwapQuery memory originQuery; SwapQuery memory destQuery; - uint256 amount = getTestAmount(WETH_E); - uint256 amountOut = calculateSwap(pool, 1, 0, amount); - redeemEvent = RedeemEvent({to: recipient, chainId: 1, token: NETH, amount: amountOut}); + depositEvent = DepositEvent({ + to: recipient, + chainId: 1, // mainnet + token: WAVAX, + amount: getTestAmount(WAVAX) + }); initiateBridge( - expectRedeemEvent, + expectDepositEvent, + 1, // mainnet + module, + WAVAX, + originQuery, + destQuery + ); + } + + function testSynapseBridge_avalancheToEthereum_inAVAX_outWAVAX() public { + address module = expectedModules[0]; // Synapse bridge module + + DefaultParams memory originParams = DefaultParams({ + action: Action.HandleEth, + pool: address(0), + tokenIndexFrom: type(uint8).max, + tokenIndexTo: type(uint8).max + }); + SwapQuery memory originQuery = SwapQuery({ + routerAdapter: address(router), + tokenOut: WAVAX, + minAmountOut: 0, + deadline: type(uint256).max, + rawParams: abi.encode(originParams) + }); + SwapQuery memory destQuery; + + depositEvent = DepositEvent({ + to: recipient, + chainId: 1, // mainnet + token: WAVAX, + amount: getTestAmount(WAVAX) + }); + initiateBridge( + expectDepositEvent, 1, // mainnet module, - WETH_E, + UniversalTokenLib.ETH_ADDRESS, originQuery, destQuery ); From 17a785797635738abfa5abf90b3b44e9b938fd2c Mon Sep 17 00:00:00 2001 From: mikeyrf <23126274+mikeyrf@users.noreply.github.com> Date: Tue, 31 Oct 2023 18:15:18 -0400 Subject: [PATCH 11/15] test router v2 integration avax synapseCCTP USDC, USDCe to USDC --- ...ynapseRouterV2.Integration.Avalanche.t.sol | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol index 5bae61f47..c99bddced 100644 --- a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol +++ b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol @@ -622,6 +622,7 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is ); } + // TODO: fix bridge module for this edge case function testSynapseBridge_avalancheToEthereum_inGMX_outGMX() public { address module = expectedModules[0]; // Synapse bridge module @@ -699,4 +700,107 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is destQuery ); } + + function testSynapseCCTP_avalancheToEthereum_inUSDC_outUSDC() public { + address module = expectedModules[1]; // Synapse CCTP module + + SwapQuery memory originQuery; + SwapQuery memory destQuery; + + uint32 requestVersion = getRequestVersion(true); + bytes memory swapParams = bytes(""); + + uint32 originDomain = 1; + uint32 destDomain = 0; + uint64 nonce = getNextAvailableNonce(); + + bytes memory formattedRequest = formatRequest( + requestVersion, + originDomain, + nonce, + USDC, + getTestAmount(USDC), + recipient, + swapParams + ); + bytes32 expectedRequestID = getExpectedRequestID(formattedRequest, destDomain, requestVersion); + + requestSentEvent = CircleRequestSentEvent({ + chainId: 1, + sender: msg.sender, + nonce: nonce, + token: USDC, + amount: getTestAmount(USDC), + requestVersion: requestVersion, + formattedRequest: formattedRequest, + requestID: expectedRequestID + }); + initiateBridge( + expectCircleRequestSentEvent, + 1, // mainnet + module, + USDC, + originQuery, + destQuery + ); + } + + function testSynapseCCTP_avalancheToEthereum_inUSDCe_outUSDC() public { + address module = expectedModules[1]; // Synapse CCTP module + + address pool = 0x9A2Dea7B81cfe3e0011D44D41c5c5142b8d9abdF; // LinkedPool + DefaultParams memory originParams = DefaultParams({ + action: Action.Swap, + pool: pool, + tokenIndexFrom: 4, + tokenIndexTo: 0 + }); + SwapQuery memory originQuery = SwapQuery({ + routerAdapter: address(router), + tokenOut: USDC, + minAmountOut: 0, + deadline: type(uint256).max, + rawParams: abi.encode(originParams) + }); + uint256 amountIn = calculateSwap(pool, 4, 0, getTestAmount(USDC_E)); + + SwapQuery memory destQuery; + + uint32 requestVersion = getRequestVersion(true); + bytes memory swapParams = bytes(""); + + uint32 originDomain = 1; + uint32 destDomain = 0; + uint64 nonce = getNextAvailableNonce(); + + bytes memory formattedRequest = formatRequest( + requestVersion, + originDomain, + nonce, + USDC, + amountIn, + recipient, + swapParams + ); + bytes32 expectedRequestID = getExpectedRequestID(formattedRequest, destDomain, requestVersion); + + requestSentEvent = CircleRequestSentEvent({ + chainId: 1, + sender: msg.sender, + nonce: nonce, + token: USDC, + amount: amountIn, + requestVersion: requestVersion, + formattedRequest: formattedRequest, + requestID: expectedRequestID + }); + initiateBridge( + expectCircleRequestSentEvent, + 1, // mainnet + module, + USDC_E, + originQuery, + destQuery + ); + } } From 1f338c96798814ac447c5ea4031714af4e995bac Mon Sep 17 00:00:00 2001 From: mikeyrf <23126274+mikeyrf@users.noreply.github.com> Date: Thu, 2 Nov 2023 08:59:03 -0400 Subject: [PATCH 12/15] fix test router v2 avax integration synapseBridge GMX --- .../SynapseRouterV2.Integration.Avalanche.t.sol | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol index c99bddced..869c7a453 100644 --- a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol +++ b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol @@ -48,6 +48,7 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is address private constant USDT_E = 0xc7198437980c041c805A1EDcbA50c1Ce5db95118; address private constant WETH_E = 0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB; address private constant USDT = 0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7; + address private constant GMX_WRAPPER = 0x20A9DC684B4d0407EF8C9A302BEAaA18ee15F656; constructor() SynapseRouterV2IntegrationTest("avalanche", AVAX_BLOCK_NUMBER, AVAX_SWAP_QUOTER) {} @@ -622,21 +623,15 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is ); } - // TODO: fix bridge module for this edge case function testSynapseBridge_avalancheToEthereum_inGMX_outGMX() public { address module = expectedModules[0]; // Synapse bridge module SwapQuery memory originQuery; SwapQuery memory destQuery; - depositEvent = DepositEvent({ - to: recipient, - chainId: 1, // mainnet - token: GMX, - amount: getTestAmount(GMX) - }); + redeemEvent = RedeemEvent({to: recipient, chainId: 1, token: GMX_WRAPPER, amount: getTestAmount(GMX)}); initiateBridge( - expectDepositEvent, + expectRedeemEvent, 1, // mainnet module, GMX, From 2de2100d0ff3ad37f02e6da5d9751ccaf9843794 Mon Sep 17 00:00:00 2001 From: mikeyrf <23126274+mikeyrf@users.noreply.github.com> Date: Thu, 2 Nov 2023 09:16:15 -0400 Subject: [PATCH 13/15] remaining router v2 integration avax synapseCCTP tests --- ...ynapseRouterV2.Integration.Avalanche.t.sol | 144 ++++++++++++++++++ ...SynapseRouterV2.Integration.Ethereum.t.sol | 2 +- 2 files changed, 145 insertions(+), 1 deletion(-) diff --git a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol index 869c7a453..6331e62b3 100644 --- a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol +++ b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol @@ -798,4 +798,148 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is destQuery ); } + + function testSynapseCCTP_avalancheToArbitrum_inUSDC_outUSDCe() public { + address module = expectedModules[1]; // Synapse CCTP module + + SwapQuery memory originQuery; + + DefaultParams memory destParams = DefaultParams({ + action: Action.Swap, + pool: 0xC40BF702aBebB494842e2a1751bCf6D8C5be2Fa9, // stableswap pool on arbitrum + tokenIndexFrom: 0, + tokenIndexTo: 1 + }); + SwapQuery memory destQuery = SwapQuery({ + routerAdapter: 0xC40BF702aBebB494842e2a1751bCf6D8C5be2Fa9, + tokenOut: 0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8, // USDCe on arbitrum + minAmountOut: 0, + deadline: type(uint256).max, + rawParams: abi.encode(destParams) + }); + + uint32 requestVersion = getRequestVersion(false); + bytes memory swapParams = formatSwapParams({ + tokenIndexFrom: 0, + tokenIndexTo: 1, + deadline: type(uint256).max, + minAmountOut: 0 + }); + + uint32 originDomain = 1; + uint32 destDomain = 3; + uint64 nonce = getNextAvailableNonce(); + + bytes memory formattedRequest = formatRequest( + requestVersion, + originDomain, + nonce, + USDC, + getTestAmount(USDC), + recipient, + swapParams + ); + bytes32 expectedRequestID = getExpectedRequestID(formattedRequest, destDomain, requestVersion); + + requestSentEvent = CircleRequestSentEvent({ + chainId: 42161, + sender: msg.sender, + nonce: nonce, + token: USDC, + amount: getTestAmount(USDC), + requestVersion: requestVersion, + formattedRequest: formattedRequest, + requestID: expectedRequestID + }); + initiateBridge( + expectCircleRequestSentEvent, + 42161, // arbitrum + module, + USDC, + originQuery, + destQuery + ); + } + + function testSynapseCCTP_avalancheToArbitrum_inUSDCe_outUSDCe() public { + address module = expectedModules[1]; // Synapse CCTP module + + address pool = 0x9A2Dea7B81cfe3e0011D44D41c5c5142b8d9abdF; // LinkedPool + + uint256 amountIn = calculateSwap(pool, 4, 0, getTestAmount(USDC_E)); + + SwapQuery memory originQuery; + SwapQuery memory destQuery; + { + DefaultParams memory originParams = DefaultParams({ + action: Action.Swap, + pool: pool, + tokenIndexFrom: 4, + tokenIndexTo: 0 + }); + originQuery = SwapQuery({ + routerAdapter: address(router), + tokenOut: USDC, + minAmountOut: 0, + deadline: type(uint256).max, + rawParams: abi.encode(originParams) + }); + + DefaultParams memory destParams = DefaultParams({ + action: Action.Swap, + pool: 0xC40BF702aBebB494842e2a1751bCf6D8C5be2Fa9, // stableswap pool on arbitrum + tokenIndexFrom: 0, + tokenIndexTo: 1 + }); + destQuery = SwapQuery({ + routerAdapter: 0xC40BF702aBebB494842e2a1751bCf6D8C5be2Fa9, + tokenOut: 0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8, // USDCe on arbitrum + minAmountOut: 0, + deadline: type(uint256).max, + rawParams: abi.encode(destParams) + }); + } + + uint32 requestVersion = getRequestVersion(false); + bytes memory swapParams = formatSwapParams({ + tokenIndexFrom: 0, + tokenIndexTo: 1, + deadline: type(uint256).max, + minAmountOut: 0 + }); + + uint32 originDomain = 1; + uint32 destDomain = 3; + uint64 nonce = getNextAvailableNonce(); + + bytes memory formattedRequest = formatRequest( + requestVersion, + originDomain, + nonce, + USDC, + amountIn, + recipient, + swapParams + ); + bytes32 expectedRequestID = getExpectedRequestID(formattedRequest, destDomain, requestVersion); + + requestSentEvent = CircleRequestSentEvent({ + chainId: 42161, + sender: msg.sender, + nonce: nonce, + token: USDC, + amount: amountIn, + requestVersion: requestVersion, + formattedRequest: formattedRequest, + requestID: expectedRequestID + }); + initiateBridge( + expectCircleRequestSentEvent, + 42161, // arbitrum + module, + USDC_E, + originQuery, + destQuery + ); + } } diff --git a/test/router/v2/integration/SynapseRouterV2.Integration.Ethereum.t.sol b/test/router/v2/integration/SynapseRouterV2.Integration.Ethereum.t.sol index 6df244629..6a1c089e3 100644 --- a/test/router/v2/integration/SynapseRouterV2.Integration.Ethereum.t.sol +++ b/test/router/v2/integration/SynapseRouterV2.Integration.Ethereum.t.sol @@ -901,7 +901,7 @@ contract SynapseRouterV2EthereumIntegrationTestFork is }); initiateBridge( expectCircleRequestSentEvent, - 42161, // mainnet + 42161, // arbitrum module, USDC, originQuery, From 7c5091da59621b23400aabf7b6094c8ed223a22d Mon Sep 17 00:00:00 2001 From: mikeyrf <23126274+mikeyrf@users.noreply.github.com> Date: Thu, 2 Nov 2023 10:13:33 -0400 Subject: [PATCH 14/15] test router v2 avax integration adapter swap --- ...ynapseRouterV2.Integration.Avalanche.t.sol | 36 +++++++++++++++++++ .../SynapseRouterV2.Integration.sol | 2 +- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol index 6331e62b3..527b330cd 100644 --- a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol +++ b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol @@ -942,4 +942,40 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is destQuery ); } + + function testSwap_avalanche_inUSDCe_outUSDTe() public { + address pool = AVAX_STABLE_POOL; + DefaultParams memory params = DefaultParams({ + action: Action.Swap, + pool: pool, // stableswap pool on arbitrum + tokenIndexFrom: 2, + tokenIndexTo: 3 + }); + SwapQuery memory query = SwapQuery({ + routerAdapter: address(router), + tokenOut: USDT_E, + minAmountOut: calculateSwap(pool, 2, 3, getTestAmount(USDC_E)), + deadline: type(uint256).max, + rawParams: abi.encode(params) + }); + initiateSwap(recipient, USDC_E, getTestAmount(USDC_E), query); + } + + function testSwap_avalanche_inWETHe_outNETH() public { + address pool = 0xdd60483Ace9B215a7c019A44Be2F22Aa9982652E; // Aave swap wrapper + DefaultParams memory params = DefaultParams({ + action: Action.Swap, + pool: pool, // stableswap pool on arbitrum + tokenIndexFrom: 1, + tokenIndexTo: 0 + }); + SwapQuery memory query = SwapQuery({ + routerAdapter: address(router), + tokenOut: NETH, + minAmountOut: calculateSwap(pool, 1, 0, getTestAmount(WETH_E)), + deadline: type(uint256).max, + rawParams: abi.encode(params) + }); + initiateSwap(recipient, WETH_E, getTestAmount(WETH_E), query); + } } diff --git a/test/router/v2/integration/SynapseRouterV2.Integration.sol b/test/router/v2/integration/SynapseRouterV2.Integration.sol index 1796c1c75..fda560ff4 100644 --- a/test/router/v2/integration/SynapseRouterV2.Integration.sol +++ b/test/router/v2/integration/SynapseRouterV2.Integration.sol @@ -214,7 +214,7 @@ abstract contract SynapseRouterV2IntegrationTest is IntegrationUtils { console.log(" Expecting: %s -> %s", amount, amountOut); // check expected amount out matches router amount out - assertEq(amountOut, expectedAmountOut); + assertApproxEqAbs(amountOut, expectedAmountOut, 1); // 1 wei abs diff tol // check balances after swap assertEq( From b7b19ccae40295a54764e936193012e64364bea9 Mon Sep 17 00:00:00 2001 From: mikeyrf <23126274+mikeyrf@users.noreply.github.com> Date: Mon, 6 Nov 2023 09:42:42 -0500 Subject: [PATCH 15/15] router v2 avax integration tests for native usdt --- ...ynapseRouterV2.Integration.Avalanche.t.sol | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol index 527b330cd..dfb02c876 100644 --- a/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol +++ b/test/router/v2/integration/SynapseRouterV2.Integration.Avalanche.t.sol @@ -64,6 +64,7 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is addExpectedToken(DAI_E, "DAI.e"); addExpectedToken(USDT_E, "USDT.e"); addExpectedToken(USDC, "CCTP.USDC"); + addExpectedToken(USDT, "USDT"); addExpectedToken(NETH, "nETH"); addExpectedToken(WETH_E, "WETH.e"); addExpectedToken(WAVAX, "WAVAX"); @@ -83,12 +84,13 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is function addExpectedBridgeTokens() public virtual override { // add synapse bridge module bridge tokens - address[] memory originTokensBridgeStables = new address[](5); + address[] memory originTokensBridgeStables = new address[](6); originTokensBridgeStables[0] = NUSD; originTokensBridgeStables[1] = DAI_E; originTokensBridgeStables[2] = USDC_E; originTokensBridgeStables[3] = USDT_E; originTokensBridgeStables[4] = USDC; + originTokensBridgeStables[5] = USDT; address[] memory destinationTokensBridgeStables = new address[](4); destinationTokensBridgeStables[0] = NUSD; @@ -146,19 +148,21 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is ); // add synapse cctp module bridge tokens - address[] memory originTokensCCTP = new address[](5); + address[] memory originTokensCCTP = new address[](6); originTokensCCTP[0] = USDC; originTokensCCTP[1] = NUSD; originTokensCCTP[2] = USDC_E; originTokensCCTP[3] = DAI_E; originTokensCCTP[4] = USDT_E; + originTokensCCTP[5] = USDT; - address[] memory destinationTokensCCTP = new address[](5); + address[] memory destinationTokensCCTP = new address[](6); destinationTokensCCTP[0] = USDC; destinationTokensCCTP[1] = NUSD; destinationTokensCCTP[2] = USDC_E; destinationTokensCCTP[3] = DAI_E; destinationTokensCCTP[4] = USDT_E; + destinationTokensCCTP[5] = USDT; addExpectedBridgeToken( BridgeToken({symbol: "CCTP.USDC", token: USDC}), @@ -300,6 +304,18 @@ contract SynapseRouterV2AvalancheIntegrationTestFork is } /// @dev not enough liquidity to test CCTP max bridged amount out + function testGetOriginAmountOut_inUSDC_outUSDC_overMaxBridgedAmount() public { + address tokenIn = USDC; + string memory tokenSymbol = "CCTP.USDC"; + uint256 amountIn = 10**12 + 1; + + SwapQuery memory query = router.getOriginAmountOut(tokenIn, tokenSymbol, amountIn); + assertEq(query.routerAdapter, address(0)); + assertEq(query.tokenOut, address(0)); + assertEq(query.minAmountOut, 0); + assertEq(query.deadline, 0); + assertEq(query.rawParams, bytes("")); + } function testGetOriginAmountOut_inWETHe_outNETH() public { address tokenIn = WETH_E;