import {PopulatedTransaction} from "@ethersproject/contracts"; import {step} from "mocha-steps"; import { bridgeTestPrivkey1, DEFAULT_TEST_TIMEOUT, expectFulfilled, getTestAmount, makeWalletSignerWithProvider } from "@tests/helpers"; import {Bridge, ChainId, Networks, Token, Tokens} from "@sdk"; import {TransactionDescription} from "@ethersproject/abi"; import {L1BridgeZapFactory, L2BridgeZapFactory} from "@contracts"; import {expect} from "chai"; import {BridgeSwapTestCase, makeBridgeSwapTestCase} from "./bridge_test_utils"; import {formatUnits} from "@ethersproject/units"; describe("SynapseBridge - buildBridgeTokenTransaction tests", function(this: Mocha.Suite) { interface Expected { wantFn: string, } type TestCase = BridgeSwapTestCase<Expected> const makeTestCase = ( t1: Token, t2: Token, c1: number, c2: number, wantFn: string, ): TestCase => { const expected: Expected = {wantFn}; return makeBridgeSwapTestCase(c1, t1, c2, t2, expected, getTestAmount(t1, c1)) } function makeTestName(tc: TestCase): string { let { args: { amountFrom, tokenFrom, tokenFrom: { symbol: tokFrom }, tokenTo: { symbol: tokTo }, chainIdFrom: chainFrom, chainIdTo: chainTo, }, expected: {wantFn} } = tc; const amt = formatUnits(amountFrom, tokenFrom.decimals(chainFrom)), netFrom = Networks.networkName(chainFrom), netTo = Networks.networkName(chainTo); const testPrefix: string = "buildBridgeTokenTransaction()", testParamsTitle: string = `with params ${tokFrom} on ${netFrom} -> ${tokTo} on ${netTo}`, testWant: string = `should be a transaction which calls ${wantFn}()`; return `${testPrefix} ${testParamsTitle} ${testWant}` } const redeem = "redeem", deposit = "deposit", depositETH = "depositETH", redeemAndSwap = "redeemAndSwap", redeemAndRemove = "redeemAndRemove", swapAndRedeemAndRemove = "swapAndRedeemAndRemove", swapETHAndRedeem = "swapETHAndRedeem", swapAndRedeem = "swapAndRedeem", swapETHAndRedeemAndSwap = "swapETHAndRedeemAndSwap", swapAndRedeemAndSwap = "swapAndRedeemAndSwap", zapAndDeposit = "zapAndDeposit", zapAndDepositAndSwap = "zapAndDepositAndSwap", depositAndSwap = "depositAndSwap", depositETHAndSwap = "depositETHAndSwap"; [ makeTestCase(Tokens.DAI, Tokens.USDC, ChainId.ETH, ChainId.BSC, zapAndDepositAndSwap), makeTestCase(Tokens.NETH, Tokens.ETH, ChainId.BOBA, ChainId.ETH, redeem), makeTestCase(Tokens.NETH, Tokens.NETH, ChainId.BOBA, ChainId.ETH, redeem), makeTestCase(Tokens.USDC, Tokens.NUSD, ChainId.BOBA, ChainId.BSC, swapAndRedeem), makeTestCase(Tokens.USDC, Tokens.USDT, ChainId.BSC, ChainId.BOBA, swapAndRedeemAndSwap), makeTestCase(Tokens.FRAX, Tokens.FRAX, ChainId.MOONRIVER, ChainId.ETH, redeem), makeTestCase(Tokens.FRAX, Tokens.FRAX, ChainId.ETH, ChainId.MOONRIVER, deposit), makeTestCase(Tokens.SYN, Tokens.SYN, ChainId.MOONRIVER, ChainId.ETH, redeem), makeTestCase(Tokens.SYN, Tokens.SYN, ChainId.ETH, ChainId.MOONRIVER, redeem), makeTestCase(Tokens.ETH, Tokens.NETH, ChainId.OPTIMISM, ChainId.ETH, swapETHAndRedeem), makeTestCase(Tokens.ETH, Tokens.NETH, ChainId.ETH, ChainId.AVALANCHE, depositETH), makeTestCase(Tokens.WETH_E, Tokens.ETH, ChainId.AVALANCHE, ChainId.ETH, swapAndRedeem), makeTestCase(Tokens.WETH_E, Tokens.ETH, ChainId.AVALANCHE, ChainId.ARBITRUM, swapAndRedeemAndSwap), makeTestCase(Tokens.ETH, Tokens.WETH_E, ChainId.ETH, ChainId.AVALANCHE, depositETHAndSwap), makeTestCase(Tokens.NUSD, Tokens.DAI, ChainId.AVALANCHE, ChainId.ETH, redeemAndRemove), makeTestCase(Tokens.DAI, Tokens.DAI, ChainId.AVALANCHE, ChainId.ETH, swapAndRedeemAndRemove), makeTestCase(Tokens.NUSD, Tokens.DAI, ChainId.AVALANCHE, ChainId.POLYGON, redeemAndSwap), makeTestCase(Tokens.DOG, Tokens.DOG, ChainId.POLYGON, ChainId.ETH, redeem), makeTestCase(Tokens.ETH, Tokens.ETH, ChainId.ARBITRUM, ChainId.OPTIMISM, swapETHAndRedeemAndSwap), makeTestCase(Tokens.NETH, Tokens.ETH, ChainId.ARBITRUM, ChainId.OPTIMISM, redeemAndSwap), makeTestCase(Tokens.JUMP, Tokens.JUMP, ChainId.FANTOM, ChainId.BSC, deposit), makeTestCase(Tokens.GOHM, Tokens.GOHM, ChainId.AVALANCHE, ChainId.OPTIMISM, redeem), makeTestCase(Tokens.GOHM, Tokens.GOHM, ChainId.ETH, ChainId.AVALANCHE, deposit), makeTestCase(Tokens.GOHM, Tokens.GOHM, ChainId.HARMONY, ChainId.MOONRIVER, redeem), makeTestCase(Tokens.GOHM, Tokens.GOHM, ChainId.ETH, ChainId.AVALANCHE, deposit), makeTestCase(Tokens.USDC, Tokens.USDC, ChainId.AURORA, ChainId.AVALANCHE, swapAndRedeemAndSwap), makeTestCase(Tokens.USDC, Tokens.NUSD, ChainId.BSC, ChainId.AURORA, swapAndRedeem), makeTestCase(Tokens.USDC, Tokens.NUSD, ChainId.AURORA, ChainId.ETH, swapAndRedeem), makeTestCase(Tokens.USDC, Tokens.NUSD, ChainId.ETH, ChainId.AURORA, zapAndDeposit), makeTestCase(Tokens.WETH, Tokens.WETH_E, ChainId.ETH, ChainId.AVALANCHE, depositETHAndSwap), makeTestCase(Tokens.NUSD, Tokens.NUSD, ChainId.ETH, ChainId.AVALANCHE, deposit), makeTestCase(Tokens.WETH_E, Tokens.WETH, ChainId.AVALANCHE, ChainId.OPTIMISM, swapAndRedeemAndSwap), makeTestCase(Tokens.WETH, Tokens.ONE_ETH, ChainId.ETH, ChainId.HARMONY, depositETHAndSwap), makeTestCase(Tokens.ONE_ETH, Tokens.WETH_E, ChainId.HARMONY, ChainId.AVALANCHE, swapAndRedeemAndSwap), makeTestCase(Tokens.HIGH, Tokens.HIGH, ChainId.BSC, ChainId.ETH, redeem), makeTestCase(Tokens.JUMP, Tokens.JUMP, ChainId.BSC, ChainId.FANTOM, redeem), makeTestCase(Tokens.DOG, Tokens.DOG, ChainId.BSC, ChainId.POLYGON, redeem), makeTestCase(Tokens.NFD, Tokens.NFD, ChainId.POLYGON, ChainId.AVALANCHE, deposit), makeTestCase(Tokens.GMX, Tokens.GMX, ChainId.ARBITRUM, ChainId.AVALANCHE, deposit), makeTestCase(Tokens.GMX, Tokens.GMX, ChainId.AVALANCHE, ChainId.ARBITRUM, redeem), makeTestCase(Tokens.SOLAR, Tokens.SOLAR, ChainId.MOONRIVER, ChainId.MOONBEAM, deposit), makeTestCase(Tokens.WAVAX, Tokens.AVAX, ChainId.MOONBEAM, ChainId.AVALANCHE, redeem), makeTestCase(Tokens.AVAX, Tokens.WAVAX, ChainId.AVALANCHE, ChainId.MOONBEAM, depositETH), makeTestCase(Tokens.WMOVR, Tokens.MOVR, ChainId.MOONBEAM, ChainId.MOONRIVER, redeem), makeTestCase(Tokens.MOVR, Tokens.WMOVR, ChainId.MOONRIVER, ChainId.MOONBEAM, depositETH), makeTestCase(Tokens.FTM_ETH, Tokens.WETH, ChainId.FANTOM, ChainId.ETH, swapAndRedeem), makeTestCase(Tokens.FTM_ETH, Tokens.ETH, ChainId.FANTOM, ChainId.ETH, swapAndRedeem), makeTestCase(Tokens.FTM_ETH, Tokens.WETH_E, ChainId.FANTOM, ChainId.AVALANCHE, swapAndRedeemAndSwap), makeTestCase(Tokens.WETH_E, Tokens.FTM_ETH, ChainId.AVALANCHE, ChainId.FANTOM, swapAndRedeemAndSwap), makeTestCase(Tokens.ETH, Tokens.FTM_ETH, ChainId.ETH, ChainId.FANTOM, depositETHAndSwap), makeTestCase(Tokens.WETH, Tokens.FTM_ETH, ChainId.ETH, ChainId.FANTOM, depositETHAndSwap), makeTestCase(Tokens.ETH, Tokens.WETH_E, ChainId.ARBITRUM, ChainId.AVALANCHE, swapETHAndRedeemAndSwap), makeTestCase(Tokens.WETH, Tokens.WETH_E, ChainId.ARBITRUM, ChainId.AVALANCHE, swapETHAndRedeemAndSwap), makeTestCase(Tokens.WETH_E, Tokens.ETH, ChainId.AVALANCHE, ChainId.ARBITRUM, swapAndRedeemAndSwap), makeTestCase(Tokens.WETH_E, Tokens.WETH, ChainId.AVALANCHE, ChainId.ARBITRUM, swapAndRedeemAndSwap), makeTestCase(Tokens.USDC, Tokens.DAI, ChainId.BSC, ChainId.ETH, swapAndRedeemAndRemove), makeTestCase(Tokens.NUSD, Tokens.DAI, ChainId.BSC, ChainId.ETH, redeemAndRemove), makeTestCase(Tokens.NUSD, Tokens.USDC, ChainId.ETH, ChainId.BSC, depositAndSwap), makeTestCase(Tokens.NUSD, Tokens.NUSD, ChainId.BSC, ChainId.POLYGON, redeem), makeTestCase(Tokens.NUSD, Tokens.NUSD, ChainId.POLYGON, ChainId.BSC, redeem), makeTestCase(Tokens.UST, Tokens.UST, ChainId.BSC, ChainId.POLYGON, redeem), makeTestCase(Tokens.UST, Tokens.UST, ChainId.POLYGON, ChainId.ETH, redeem), makeTestCase(Tokens.NEWO, Tokens.NEWO, ChainId.ARBITRUM, ChainId.AVALANCHE, redeem), makeTestCase(Tokens.NEWO, Tokens.NEWO, ChainId.ETH, ChainId.AVALANCHE, deposit), makeTestCase(Tokens.NEWO, Tokens.NEWO, ChainId.AVALANCHE, ChainId.ETH, redeem), makeTestCase(Tokens.SDT, Tokens.SDT, ChainId.ETH, ChainId.FANTOM, deposit), makeTestCase(Tokens.SDT, Tokens.SDT, ChainId.AVALANCHE, ChainId.HARMONY, redeem), makeTestCase(Tokens.SDT, Tokens.SDT, ChainId.FANTOM, ChainId.HARMONY, redeem), makeTestCase(Tokens.SDT, Tokens.SDT, ChainId.AVALANCHE, ChainId.FANTOM, redeem), makeTestCase(Tokens.LUNA, Tokens.LUNA, ChainId.ARBITRUM, ChainId.OPTIMISM, redeem), makeTestCase(Tokens.LUNA, Tokens.LUNA, ChainId.OPTIMISM, ChainId.ARBITRUM, redeem), makeTestCase(Tokens.METIS_ETH, Tokens.WETH_E, ChainId.METIS, ChainId.AVALANCHE, swapAndRedeemAndSwap), makeTestCase(Tokens.ETH, Tokens.METIS_ETH, ChainId.ETH, ChainId.METIS, depositETHAndSwap), makeTestCase(Tokens.NETH, Tokens.WETH_E, ChainId.METIS, ChainId.AVALANCHE, redeemAndSwap), ].forEach((tc: TestCase) => { const testTitle = makeTestName(tc); describe(testTitle, function(this: Mocha.Suite) { let builtTxn: PopulatedTransaction; const amountTo = tc.args.amountFrom.sub(5); step("build transaction", async function(this: Mocha.Context) { this.timeout(DEFAULT_TEST_TIMEOUT); let {args: { chainIdFrom }, args} = tc; const bridgeInstance = new Bridge.SynapseBridge({ network: chainIdFrom }), addressTo: string = makeWalletSignerWithProvider(chainIdFrom, bridgeTestPrivkey1).address; let prom = bridgeInstance.buildBridgeTokenTransaction({...args, amountTo, addressTo}); Promise.resolve(prom).then(built => builtTxn = built); return (await expectFulfilled(prom)) }) let txnInfo: TransactionDescription; const l1BridgeZapInterface = L1BridgeZapFactory.createInterface(), l2BridgeZapInterface = L2BridgeZapFactory.createInterface(); step(`tx should be a call to function ${tc.expected.wantFn}()`, function(this: Mocha.Context) { txnInfo = tc.args.chainIdFrom === ChainId.ETH ? l1BridgeZapInterface.parseTransaction({data: builtTxn.data || ""}) : l2BridgeZapInterface.parseTransaction({data: builtTxn.data || ""}); expect(txnInfo.name).to.equal(tc.expected.wantFn); }); }); }); });