Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bing/ft watcher mainnet #365

Merged
merged 1 commit into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion common/src/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,11 @@ export const INITIAL_NTT_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN: NetworkChainBloc
};

export const INITIAL_FT_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN: NetworkChainBlockMapping = {
['Mainnet']: {},
['Mainnet']: {
Solana: '285350104',
Arbitrum: '245882390',
Base: '18956026',
},
['Testnet']: {
Solana: '302162456',
ArbitrumSepolia: '49505590',
Expand Down
4 changes: 4 additions & 0 deletions common/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,7 @@ export async function retry<T>(
}
}
}

export function stringifyWithBigInt(obj: any) {
return JSON.stringify(obj, (_, value) => (typeof value === 'bigint' ? value.toString() : value));
}
432 changes: 304 additions & 128 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions watcher/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@
"@solana/spl-token": "^0.4.6",
"@solana/web3.js": "^1.73.0",
"@types/bn.js": "^5.1.0",
"@wormhole-foundation/example-liquidity-layer-definitions": "file:./sdk/wormhole-foundation-example-liquidity-layer-definitions-0.0.1.tgz",
"@wormhole-foundation/example-liquidity-layer-evm": "file:./sdk/wormhole-foundation-example-liquidity-layer-evm-0.0.1.tgz",
"@wormhole-foundation/example-liquidity-layer-solana": "file:./sdk/wormhole-foundation-example-liquidity-layer-solana-0.0.1.tgz",
"@wormhole-foundation/example-liquidity-layer-definitions": "file:sdk/wormhole-foundation-example-liquidity-layer-definitions-0.0.1.tgz",
"@wormhole-foundation/example-liquidity-layer-evm": "file:sdk/wormhole-foundation-example-liquidity-layer-evm-0.0.1.tgz",
"@wormhole-foundation/example-liquidity-layer-solana": "file:sdk/wormhole-foundation-example-liquidity-layer-solana-0.0.1.tgz",
"@wormhole-foundation/wormhole-monitor-common": "^0.0.1",
"algosdk": "^2.4.0",
"anchor-0.29.0": "npm:@coral-xyz/anchor@^0.29.0",
Expand Down
Binary file not shown.
60 changes: 48 additions & 12 deletions watcher/src/fastTransfer/consts.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import { Network } from '@wormhole-foundation/sdk-base';
import { Chain, Network } from '@wormhole-foundation/sdk-base';

export type FastTransferContracts = 'MatchingEngine' | 'TokenRouter' | 'USDCMint';

// Will define more as we know what the mainnet addresses are
export type MatchingEngineProgramId = 'mPydpGUWxzERTNpyvTKdvS7v8kvw5sgwfiP8WQFrXVS';
export type TokenRouterProgramId = 'tD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md';
export type USDCMintAddress = '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU';
export type SwapLayerProgramId = 'SwapLayer1111111111111111111111111111111111';
export type MatchingEngineProgramId =
| 'mPydpGUWxzERTNpyvTKdvS7v8kvw5sgwfiP8WQFrXVS'
| 'HtkeCDdYY4i9ncAxXKjYTx8Uu3WM8JbtiLRYjtHwaVXb';
export type TokenRouterProgramId =
| 'tD8RmtdcV7bzBeuFgyrFc8wvayj988ChccEzRQzo6md'
| '28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe';
export type USDCMintAddress =
| '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU'
| 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
export type SwapLayerProgramId =
| 'SwapLayer1111111111111111111111111111111111'
| '9Zv8ajzFjacRoYCgCPus4hq3pYjpNa9KkTFQ1sHa1h3d';

export interface SolanaContractAddresses {
MatchingEngine: MatchingEngineProgramId;
Expand All @@ -27,15 +34,30 @@ export type ContractAddresses = SolanaContractAddresses | EthereumContractAddres

export type FastTransferContractAddresses = {
[key in Network]?: {
Solana?: SolanaContractAddresses;
ArbitrumSepolia?: EthereumContractAddresses;
Ethereum?: EthereumContractAddresses;
// For each chain, use SolanaContractAddresses if it's Solana, otherwise use EthereumContractAddresses
[chain in Chain]?: chain extends 'Solana' ? SolanaContractAddresses : EthereumContractAddresses;
};
};

// Will add more chains as needed
export const FAST_TRANSFER_CONTRACTS: FastTransferContractAddresses = {
Mainnet: {},
Mainnet: {
Solana: {
MatchingEngine: 'HtkeCDdYY4i9ncAxXKjYTx8Uu3WM8JbtiLRYjtHwaVXb',
TokenRouter: '28topqjtJzMnPaGFmmZk68tzGmj9W9aMntaEK3QkgtRe',
USDCMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
// TODO: uncomment this when SwapLayer is deployed on Solana Mainnet
// SwapLayer: '9Zv8ajzFjacRoYCgCPus4hq3pYjpNa9KkTFQ1sHa1h3d',
},
Arbitrum: {
TokenRouter: '0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47',
CircleBridge: '0x19330d10D9Cc8751218eaf51E8885D058642E08A',
},
Base: {
TokenRouter: '0x70287c79ee41C5D1df8259Cd68Ba0890cd389c47',
CircleBridge: '0x1682Ae6375C4E4A97e4B583BC394c861A46D8962',
},
},
Testnet: {
Solana: {
MatchingEngine: 'mPydpGUWxzERTNpyvTKdvS7v8kvw5sgwfiP8WQFrXVS',
Expand All @@ -49,5 +71,19 @@ export const FAST_TRANSFER_CONTRACTS: FastTransferContractAddresses = {
},
};

// Will add more chains as needed
export type FTChains = 'ArbitrumSepolia';
// Separate testnet and mainnet chains
export type FTEVMMainnetChain = 'Arbitrum' | 'Base';
export type FTEVMTestnetChain = 'ArbitrumSepolia';
export type FTEVMChain = FTEVMMainnetChain | FTEVMTestnetChain;

export const FTEVMMainnetChains: FTEVMMainnetChain[] = ['Arbitrum', 'Base'];
export const FTEVMTestnetChains: FTEVMTestnetChain[] = ['ArbitrumSepolia'];

export const isFTEVMChain = (chain: Chain, network: Network): chain is FTEVMChain => {
if (network === 'Mainnet') {
return FTEVMMainnetChains.includes(chain as FTEVMMainnetChain);
} else if (network === 'Testnet') {
return FTEVMTestnetChains.includes(chain as FTEVMTestnetChain);
}
return false;
};
28 changes: 16 additions & 12 deletions watcher/src/fastTransfer/tokenRouter/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
contracts,
toChainId,
} from '@wormhole-foundation/sdk-base';
import { FAST_TRANSFER_CONTRACTS, FTChains } from '../consts';
import { FAST_TRANSFER_CONTRACTS, FTEVMChain } from '../consts';
import isNotNull from '../../../src/utils/isNotNull';
import { MarketOrder } from '../types';

Expand All @@ -19,17 +19,8 @@ class TokenRouterParser {
private evmTokenRouter: EvmTokenRouter;
private network: Network;
private chain: Chain;
// the only 2 functions we care about
private functionSelectors = [
ethers.utils
.id('placeFastMarketOrder(uint64,uint64,uint16,bytes32,bytes,address,uint64,uint32)')
.substring(0, 10),
ethers.utils
.id('placeFastMarketOrder(uint64,uint16,bytes32,bytes,uint64,uint32)')
.substring(0, 10),
];

constructor(network: Network, chain: FTChains, provider: ethers.providers.JsonRpcProvider) {
private functionSelectors: string[];
constructor(network: Network, chain: FTEVMChain, provider: ethers.providers.JsonRpcProvider) {
this.provider = provider;
this.evmTokenRouter = new EvmTokenRouter(
this.provider,
Expand All @@ -38,6 +29,19 @@ class TokenRouterParser {
);
this.network = network;
this.chain = chain;
// on Mainnet the TokenRouter is called via a SwapLayer proxy contract using the `initiate` method
// on Testnet there is no Swaplayer so we check using the primitive methods
this.functionSelectors =
this.network === 'Mainnet'
? [ethers.utils.id('initiate(uint16,bytes32,bytes)').substring(0, 10)]
: [
ethers.utils
.id('placeFastMarketOrder(uint64,uint64,uint16,bytes32,bytes,address,uint64,uint32)')
.substring(0, 10),
ethers.utils
.id('placeFastMarketOrder(uint64,uint16,bytes32,bytes,uint64,uint32)')
.substring(0, 10),
];
}

async parseFastMarketOrder(txHash: string): Promise<LiquidityLayerTransactionResult | null> {
Expand Down
4 changes: 3 additions & 1 deletion watcher/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { initDb } from './databases/utils';
import { Mode, getNetwork, getMode } from '@wormhole-foundation/wormhole-monitor-common';
import { startSupervisor } from './workers/supervisor';
import { Chain, Network } from '@wormhole-foundation/sdk-base';
import { FTEVMMainnetChains, FTEVMTestnetChains } from './fastTransfer/consts';

initDb();

Expand Down Expand Up @@ -93,7 +94,8 @@ const supportedNTTChains: Chain[] =
? ['Solana', 'Sepolia', 'ArbitrumSepolia', 'BaseSepolia', 'OptimismSepolia']
: ['Solana', 'Ethereum', 'Fantom', 'Arbitrum', 'Optimism', 'Base'];

const supportedFTChains: Chain[] = network === 'Testnet' ? ['Solana', 'ArbitrumSepolia'] : [];
const supportedFTChains: Chain[] =
network === 'Testnet' ? ['Solana', ...FTEVMTestnetChains] : ['Solana', ...FTEVMMainnetChains];

if (mode === 'vaa') {
startSupervisor(supportedChains);
Expand Down
8 changes: 4 additions & 4 deletions watcher/src/watchers/FTEVMWatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import knex, { Knex } from 'knex';
import { Watcher } from './Watcher';
import { Network } from '@wormhole-foundation/sdk-base';
import { assertEnvironmentVariable } from '@wormhole-foundation/wormhole-monitor-common';
import { FAST_TRANSFER_CONTRACTS, FTChains } from '../fastTransfer/consts';
import { FAST_TRANSFER_CONTRACTS, FTEVMChain } from '../fastTransfer/consts';
import { ethers } from 'ethers';
import { AXIOS_CONFIG_JSON, RPCS_BY_CHAIN } from '../consts';
import { makeBlockKey } from '../databases/utils';
Expand All @@ -29,7 +29,7 @@ export class FTEVMWatcher extends Watcher {

constructor(
network: Network,
chain: FTChains,
chain: FTEVMChain,
finalizedBlockTag: BlockTag = 'latest',
isTest = false
) {
Expand Down Expand Up @@ -154,8 +154,8 @@ export class FTEVMWatcher extends Watcher {
}

// we do not need to compare the lastBlockTime from tokenRouter and swapLayer as they both use toBlock
const lastBlockTime = tokenRouterResults.lastBlockTime;
return makeBlockKey(toBlock.toString(), lastBlockTime.toString());
const lastBlockTime = new Date(tokenRouterResults.lastBlockTime * 1000);
return makeBlockKey(toBlock.toString(), lastBlockTime.toISOString());
}

// saves items in smaller batches to reduce the impact in any case anything fails
Expand Down
Loading
Loading