Skip to content

Commit

Permalink
isRouteSupported unit test suite (wormhole-foundation#2149)
Browse files Browse the repository at this point in the history
* fix circular dependency

* beginning basic route supported unit tests

* fix imports

* unit tests covering every route isRouteSupported

* a few more test cases

* WSOL

* for some reason this fails in CI lol
  • Loading branch information
artursapek authored May 31, 2024
1 parent 854a421 commit 070ee06
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 14 deletions.
2 changes: 1 addition & 1 deletion wormhole-connect/src/routes/ntt/nttBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import { WormholeTransceiver, getMessageEvm } from './chains/evm';
import { NttManagerSolana, getMessageSolana } from './chains/solana';
import { formatGasFee } from 'routes/utils';
import { NO_INPUT } from 'utils/style';
import { estimateAverageGasFee } from 'utils/gas';
import { estimateAverageGasFee } from '../utils';
import config from 'config';
import {
getNttGroupKey,
Expand Down
2 changes: 1 addition & 1 deletion wormhole-connect/src/routes/porticoBridge/porticoBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ import {
} from './utils';
import { PorticoBridgeState, PorticoSwapAmounts } from 'store/porticoBridge';
import { TokenPrices } from 'store/tokenPrices';
import { estimateAverageGasFee } from 'utils/gas';
import { estimateAverageGasFee } from '../utils';

export abstract class PorticoBridge extends BaseRoute {
readonly NATIVE_GAS_DROPOFF_SUPPORTED: boolean = false;
Expand Down
12 changes: 11 additions & 1 deletion wormhole-connect/src/routes/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
ParsedMessage as SdkParsedMessage,
ParsedRelayerMessage as SdkParsedRelayerMessage,
} from '@wormhole-foundation/wormhole-connect-sdk';
import { BigNumber, utils } from 'ethers';
import { BigNumber, BigNumberish, utils } from 'ethers';
import config from 'config';
import { toFixedDecimals } from 'utils/balance';
import {
Expand Down Expand Up @@ -122,3 +122,13 @@ export const isIlliquidDestToken = (
export const isNttRoute = (route?: Route) => {
return route === Route.NttManual || route === Route.NttRelay;
};

export const estimateAverageGasFee = async (
chain: ChainName | ChainId,
gasLimit: BigNumberish,
): Promise<BigNumber> => {
const provider = config.wh.mustGetProvider(chain);
const gasPrice = await provider.getGasPrice();
// This is a naive estimate 30% higher than what the oracle says
return gasPrice.mul(gasLimit).mul(130).div(100);
};
12 changes: 1 addition & 11 deletions wormhole-connect/src/utils/gas.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BigNumber, BigNumberish, utils } from 'ethers';
import { BigNumber, utils } from 'ethers';
import {
ChainName,
ChainId,
Expand Down Expand Up @@ -78,13 +78,3 @@ export const estimateClaimGas = async (
if (!gas) throw new Error('could not estimate send gas');
return formatGasFee(destChain, gas);
};

export const estimateAverageGasFee = async (
chain: ChainName | ChainId,
gasLimit: BigNumberish,
): Promise<BigNumber> => {
const provider = config.wh.mustGetProvider(chain);
const gasPrice = await provider.getGasPrice();
// This is a naive estimate 30% higher than what the oracle says
return gasPrice.mul(gasLimit).mul(130).div(100);
};
95 changes: 95 additions & 0 deletions wormhole-connect/tests/ci/routes.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { ChainId, ChainName } from '@wormhole-foundation/wormhole-connect-sdk';
import { describe, expect, test } from 'vitest';
import { setConfig } from 'config';
import { Route, WormholeConnectConfig } from 'config/types';
import { getRouteImpls } from 'routes/mappings';

describe('supported routes', () => {
type testCase = [
sourceToken: string,
destToken: string,
sourceChain: ChainName | ChainId,
destChain: ChainName | ChainId,
route: Route[],
];

setConfig({ env: 'mainnet' });

const testCases: testCase[] = [
// Token bridge
['ETH', 'WETH', 'ethereum', 'bsc', [Route.Bridge, Route.Relay]],
['DAI', 'DAI', 'ethereum', 'polygon', [Route.Bridge, Route.Relay]],
['WSOL', 'WSOL', 'solana', 'ethereum', [Route.Bridge]],
['WSOL', 'WSOL', 'ethereum', 'solana', [Route.Bridge]],
['ETH', 'WETH', 'ethereum', 'avalanche', [Route.Bridge, Route.Relay]],
['BNB', 'WBNB', 'bsc', 'polygon', [Route.Bridge, Route.Relay]],
['FTM', 'WFTM', 'fantom', 'polygon', [Route.Bridge, Route.Relay]],
['CELO', 'CELO', 'celo', 'polygon', [Route.Bridge, Route.Relay]],
// ETH bridge
['ETH', 'WETHbsc', 'ethereum', 'bsc', [Route.ETHBridge]],
['ETH', 'WETHpolygon', 'ethereum', 'polygon', [Route.ETHBridge]],
['WETHarbitrum', 'WETHpolygon', 'arbitrum', 'polygon', [Route.ETHBridge]],
['WETHpolygon', 'WETHarbitrum', 'polygon', 'arbitrum', [Route.ETHBridge]],
// wstETHBridge
['wstETH', 'wstETHpolygon', 'ethereum', 'polygon', [Route.wstETHBridge]],
['wstETH', 'wstETHarbitrum', 'ethereum', 'arbitrum', [Route.wstETHBridge]],
// NTT
[
'USDCeth',
'USDCfantom',
'ethereum',
'fantom',
[Route.NttManual, Route.NttRelay],
],
// CCTP
[
'USDCeth',
'USDCarbitrum',
'ethereum',
'arbitrum',
[Route.CCTPManual, Route.CCTPRelay],
],
[
'USDCarbitrum',
'USDCpolygon',
'arbitrum',
'polygon',
[Route.CCTPManual, Route.CCTPRelay],
],
['USDCeth', 'USDCsol', 'ethereum', 'solana', [Route.CCTPManual]],
['USDCavax', 'USDCsol', 'avalanche', 'solana', [Route.CCTPManual]],
// TBTC
['tBTC', 'tBTCpolygon', 'ethereum', 'polygon', [Route.TBTC]],
['tBTCoptimism', 'tBTC', 'optimism', 'ethereum', [Route.TBTC]],
['tBTCpolygon', 'tBTCoptimism', 'polygon', 'optimism', [Route.TBTC]],
['tBTCarbitrum', 'tBTCoptimism', 'arbitrum', 'optimism', [Route.TBTC]],
// Cosmos Gateway
['CELO', 'CELO', 'osmosis', 'celo', [Route.CosmosGateway]],
['CELO', 'CELO', 'osmosis', 'moonbeam', [Route.CosmosGateway]],
['GLMR', 'WGLMR', 'moonbeam', 'kujira', [Route.CosmosGateway]],
];

for (let [
sourceToken,
destToken,
sourceChain,
destChain,
routes,
] of testCases) {
for (let route of routes) {
test(`${route} ${sourceChain}:${sourceToken} -> ${destChain}:${destToken}`, async () => {
const r = getRouteImpls(route).v1;

const isSupported = await r.isRouteSupported(
sourceToken,
destToken,
'1.0',
sourceChain,
destChain,
);

expect(isSupported).toBeTruthy();
});
}
}
});

0 comments on commit 070ee06

Please sign in to comment.