From 635c9e285ff12312ba229537e284837a103f55a7 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 27 Jun 2024 11:54:42 +0300 Subject: [PATCH 01/22] add stargate v2 cross-chain provider --- .../constants/cross-chain-providers.ts | 6 +- .../models/cross-chain-trade-type.ts | 1 + .../stargate-v2-blockchain-supported-pools.ts | 72 +++++ .../constants/stargate-v2-bridge-token.ts | 13 + .../constants/stargate-v2-chain-id.ts | 23 ++ .../constants/stargate-v2-contract-address.ts | 85 ++++++ ...te-v2-cross-chain-supported-blockchains.ts | 23 ++ .../constants/stargate-v2-pool-abi.ts | 94 +++++++ .../constants/stargate-v2-pool-id.ts | 15 ++ .../modal/stargate-v2-quote-params-struct.ts | 19 ++ .../stargate-v2-cross-chain-provider.ts | 250 ++++++++++++++++++ .../stargate-v2-cross-chain-trade.ts | 158 +++++++++++ .../cross-chain-status-manager.ts | 3 +- 13 files changed, 759 insertions(+), 3 deletions(-) create mode 100644 src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-blockchain-supported-pools.ts create mode 100644 src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-bridge-token.ts create mode 100644 src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-chain-id.ts create mode 100644 src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-contract-address.ts create mode 100644 src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-cross-chain-supported-blockchains.ts create mode 100644 src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-abi.ts create mode 100644 src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-id.ts create mode 100644 src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/modal/stargate-v2-quote-params-struct.ts create mode 100644 src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts create mode 100644 src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts diff --git a/src/features/cross-chain/calculation-manager/constants/cross-chain-providers.ts b/src/features/cross-chain/calculation-manager/constants/cross-chain-providers.ts index 0d41927c1f..350c6ba696 100644 --- a/src/features/cross-chain/calculation-manager/constants/cross-chain-providers.ts +++ b/src/features/cross-chain/calculation-manager/constants/cross-chain-providers.ts @@ -16,12 +16,14 @@ import { MesonCrossChainProvider } from '../providers/meson-provider/meson-cross import { OrbiterBridgeProvider } from '../providers/orbiter-bridge/orbiter-bridge-provider'; import { OwlToBridgeProvider } from '../providers/owl-to-bridge/owl-to-bridge-provider'; import { RangoCrossChainProvider } from '../providers/rango-provider/rango-cross-chain-provider'; -// import { StargateCrossChainProvider } from '../providers/stargate-provider/stargate-cross-chain-provider'; +import { StargateV2CrossChainProvider } from '../providers/stargate-v2-provider/stargate-v2-cross-chain-provider'; +//import { StargateCrossChainProvider } from '../providers/stargate-provider/stargate-cross-chain-provider'; import { TaikoBridgeProvider } from '../providers/taiko-bridge/taiko-bridge-provider'; const proxyProviders = [ SymbiosisCrossChainProvider, - // StargateCrossChainProvider, + StargateV2CrossChainProvider, + //StargateCrossChainProvider, XyCrossChainProvider, CbridgeCrossChainProvider, LifiCrossChainProvider, diff --git a/src/features/cross-chain/calculation-manager/models/cross-chain-trade-type.ts b/src/features/cross-chain/calculation-manager/models/cross-chain-trade-type.ts index 51ef4b8d37..2c70600d04 100644 --- a/src/features/cross-chain/calculation-manager/models/cross-chain-trade-type.ts +++ b/src/features/cross-chain/calculation-manager/models/cross-chain-trade-type.ts @@ -8,6 +8,7 @@ export const CROSS_CHAIN_TRADE_TYPE = { CELER_BRIDGE: 'celer_bridge', CHANGENOW: 'changenow', STARGATE: 'stargate', + STARGATE_V2: 'stargate_v2', ARBITRUM: 'arbitrum', SQUIDROUTER: 'squidrouter', SCROLL_BRIDGE: 'scroll_bridge', diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-blockchain-supported-pools.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-blockchain-supported-pools.ts new file mode 100644 index 0000000000..3f214831d9 --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-blockchain-supported-pools.ts @@ -0,0 +1,72 @@ +import { BLOCKCHAIN_NAME } from 'src/core/blockchain/models/blockchain-name'; + +import { stargateV2BridgeToken } from './stargate-v2-bridge-token'; +import { StargateV2SupportedBlockchains } from './stargate-v2-cross-chain-supported-blockchains'; +import { stargateV2PoolId } from './stargate-v2-pool-id'; + +export const stargateV2BlockchainSupportedPools: Record = + { + [BLOCKCHAIN_NAME.ETHEREUM]: [ + stargateV2PoolId[stargateV2BridgeToken.USDC], + stargateV2PoolId[stargateV2BridgeToken.USDT], + stargateV2PoolId[stargateV2BridgeToken.ETH], + stargateV2PoolId[stargateV2BridgeToken.METIS], + stargateV2PoolId[stargateV2BridgeToken.METH] + ], + [BLOCKCHAIN_NAME.BINANCE_SMART_CHAIN]: [stargateV2PoolId[stargateV2BridgeToken.USDT]], + [BLOCKCHAIN_NAME.AVALANCHE]: [ + stargateV2PoolId[stargateV2BridgeToken.USDC], + stargateV2PoolId[stargateV2BridgeToken.USDT] + ], + [BLOCKCHAIN_NAME.POLYGON]: [ + stargateV2PoolId[stargateV2BridgeToken.USDC], + stargateV2PoolId[stargateV2BridgeToken.USDT] + ], + [BLOCKCHAIN_NAME.ARBITRUM]: [ + stargateV2PoolId[stargateV2BridgeToken.USDC], + stargateV2PoolId[stargateV2BridgeToken.USDT], + stargateV2PoolId[stargateV2BridgeToken.ETH] + ], + [BLOCKCHAIN_NAME.OPTIMISM]: [ + stargateV2PoolId[stargateV2BridgeToken.USDC], + stargateV2PoolId[stargateV2BridgeToken.USDT], + stargateV2PoolId[stargateV2BridgeToken.ETH] + ], + [BLOCKCHAIN_NAME.METIS]: [ + stargateV2PoolId[stargateV2BridgeToken.mUSD], + stargateV2PoolId[stargateV2BridgeToken.WETH], + stargateV2PoolId[stargateV2BridgeToken.METIS] + ], + [BLOCKCHAIN_NAME.LINEA]: [stargateV2PoolId[stargateV2BridgeToken.ETH]], + [BLOCKCHAIN_NAME.MANTLE]: [ + stargateV2PoolId[stargateV2BridgeToken.USDC], + stargateV2PoolId[stargateV2BridgeToken.USDT], + stargateV2PoolId[stargateV2BridgeToken.WETH], + stargateV2PoolId[stargateV2BridgeToken.METH] + ], + [BLOCKCHAIN_NAME.BASE]: [ + stargateV2PoolId[stargateV2BridgeToken.USDC], + stargateV2PoolId[stargateV2BridgeToken.ETH] + ], + [BLOCKCHAIN_NAME.KAVA]: [stargateV2PoolId[stargateV2BridgeToken.USDT]], + [BLOCKCHAIN_NAME.SCROLL]: [ + stargateV2PoolId[stargateV2BridgeToken.USDCe], + stargateV2PoolId[stargateV2BridgeToken.ETH] + ], + [BLOCKCHAIN_NAME.AURORA]: [stargateV2PoolId[stargateV2BridgeToken.USDC]], + [BLOCKCHAIN_NAME.KLAYTN]: [ + stargateV2PoolId[stargateV2BridgeToken.USDC], + stargateV2PoolId[stargateV2BridgeToken.USDT], + stargateV2PoolId[stargateV2BridgeToken.WETH] + ], + [BLOCKCHAIN_NAME.IOTA]: [ + stargateV2PoolId[stargateV2BridgeToken.USDC], + stargateV2PoolId[stargateV2BridgeToken.USDT], + stargateV2PoolId[stargateV2BridgeToken.WETH] + ], + [BLOCKCHAIN_NAME.TAIKO]: [ + stargateV2PoolId[stargateV2BridgeToken.USDC], + stargateV2PoolId[stargateV2BridgeToken.USDT] + ], + [BLOCKCHAIN_NAME.SEI]: [stargateV2PoolId[stargateV2BridgeToken.WETH]] + }; diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-bridge-token.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-bridge-token.ts new file mode 100644 index 0000000000..350f0d0eee --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-bridge-token.ts @@ -0,0 +1,13 @@ +export const stargateV2BridgeToken = { + USDC: 'USDC', + USDT: 'USDT', + METIS: 'METIS', + mUSD: 'm.USDT', + ETH: 'ETH', + METH: 'mETH', + WETH: 'WETH', + USDCe: 'USDC.e' +} as const; + +export type StargateV2BridgeToken = + (typeof stargateV2BridgeToken)[keyof typeof stargateV2BridgeToken]; diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-chain-id.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-chain-id.ts new file mode 100644 index 0000000000..16c5d3f9ca --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-chain-id.ts @@ -0,0 +1,23 @@ +import { BLOCKCHAIN_NAME } from 'src/core/blockchain/models/blockchain-name'; + +import { StargateV2SupportedBlockchains } from './stargate-v2-cross-chain-supported-blockchains'; + +export const stargateV2ChainIds: Record = { + [BLOCKCHAIN_NAME.ETHEREUM]: 30101, + [BLOCKCHAIN_NAME.BINANCE_SMART_CHAIN]: 30102, + [BLOCKCHAIN_NAME.AVALANCHE]: 30106, + [BLOCKCHAIN_NAME.POLYGON]: 30109, + [BLOCKCHAIN_NAME.ARBITRUM]: 30110, + [BLOCKCHAIN_NAME.OPTIMISM]: 30111, + [BLOCKCHAIN_NAME.METIS]: 30151, + [BLOCKCHAIN_NAME.LINEA]: 30183, + [BLOCKCHAIN_NAME.MANTLE]: 30181, + [BLOCKCHAIN_NAME.BASE]: 30184, + [BLOCKCHAIN_NAME.KAVA]: 30177, + [BLOCKCHAIN_NAME.SCROLL]: 30214, + [BLOCKCHAIN_NAME.AURORA]: 30211, + [BLOCKCHAIN_NAME.KLAYTN]: 30150, + [BLOCKCHAIN_NAME.IOTA]: 30284, + [BLOCKCHAIN_NAME.TAIKO]: 30290, + [BLOCKCHAIN_NAME.SEI]: 30280 +}; diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-contract-address.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-contract-address.ts new file mode 100644 index 0000000000..caa4cc00c4 --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-contract-address.ts @@ -0,0 +1,85 @@ +import { BLOCKCHAIN_NAME } from 'src/core/blockchain/models/blockchain-name'; + +import { StargateV2BridgeToken, stargateV2BridgeToken } from './stargate-v2-bridge-token'; +import { StargateV2SupportedBlockchains } from './stargate-v2-cross-chain-supported-blockchains'; + +type StargateV2ContractAddress = Record< + StargateV2SupportedBlockchains, + Partial> +>; + +export const stargateV2ContractAddress: StargateV2ContractAddress = { + [BLOCKCHAIN_NAME.ETHEREUM]: { + [stargateV2BridgeToken.ETH]: '0x77b2043768d28E9C9aB44E1aBfC95944bcE57931', + [stargateV2BridgeToken.USDC]: '0xc026395860Db2d07ee33e05fE50ed7bD583189C7', + [stargateV2BridgeToken.USDT]: '0x933597a323Eb81cAe705C5bC29985172fd5A3973', + [stargateV2BridgeToken.METIS]: '0xcDafB1b2dB43f366E48e6F614b8DCCBFeeFEEcD3', + [stargateV2BridgeToken.METH]: '0x268Ca24DAefF1FaC2ed883c598200CcbB79E931D' + }, + [BLOCKCHAIN_NAME.BINANCE_SMART_CHAIN]: { + [stargateV2BridgeToken.USDT]: '0x138EB30f73BC423c6455C53df6D89CB01d9eBc63' + }, + [BLOCKCHAIN_NAME.AVALANCHE]: { + [stargateV2BridgeToken.USDC]: '0x5634c4a5FEd09819E3c46D86A965Dd9447d86e47', + [stargateV2BridgeToken.USDT]: '0x22BdF9633F3e679785638Db690b85dC0Dc8B35B8' + }, + [BLOCKCHAIN_NAME.POLYGON]: { + [stargateV2BridgeToken.USDC]: '0x9Aa02D4Fae7F58b8E8f34c66E756cC734DAc7fe4', + [stargateV2BridgeToken.USDT]: '0xd47b03ee6d86Cf251ee7860FB2ACf9f91B9fD4d7' + }, + [BLOCKCHAIN_NAME.ARBITRUM]: { + [stargateV2BridgeToken.ETH]: '0xA45B5130f36CDcA45667738e2a258AB09f4A5f7F', + [stargateV2BridgeToken.USDC]: '0xe8CDF27AcD73a434D661C84887215F7598e7d0d3', + [stargateV2BridgeToken.USDT]: '0xcE8CcA271Ebc0533920C83d39F417ED6A0abB7D0' + }, + [BLOCKCHAIN_NAME.OPTIMISM]: { + [stargateV2BridgeToken.ETH]: '0xe8CDF27AcD73a434D661C84887215F7598e7d0d3', + [stargateV2BridgeToken.USDC]: '0xcE8CcA271Ebc0533920C83d39F417ED6A0abB7D0', + [stargateV2BridgeToken.USDT]: '0x19cFCE47eD54a88614648DC3f19A5980097007dD' + }, + [BLOCKCHAIN_NAME.METIS]: { + [stargateV2BridgeToken.METIS]: '0xD9050e7043102a0391F81462a3916326F86331F0', + [stargateV2BridgeToken.ETH]: '0x36ed193dc7160D3858EC250e69D12B03Ca087D08', + [stargateV2BridgeToken.USDT]: '0x4dCBFC0249e8d5032F89D6461218a9D2eFff5125' + }, + [BLOCKCHAIN_NAME.LINEA]: { + [stargateV2BridgeToken.ETH]: '0x81F6138153d473E8c5EcebD3DC8Cd4903506B075' + }, + [BLOCKCHAIN_NAME.MANTLE]: { + [stargateV2BridgeToken.WETH]: '0x4c1d3Fc3fC3c177c3b633427c2F769276c547463', + [stargateV2BridgeToken.USDC]: '0xAc290Ad4e0c891FDc295ca4F0a6214cf6dC6acDC', + [stargateV2BridgeToken.USDT]: '0xa81274AFac523D639DbcA2C32c1470f1600cCEBe', + [stargateV2BridgeToken.METH]: '0xF7628d84a2BbD9bb9c8E686AC95BB5d55169F3F1' + }, + [BLOCKCHAIN_NAME.BASE]: { + [stargateV2BridgeToken.ETH]: '0xdc181Bd607330aeeBEF6ea62e03e5e1Fb4B6F7C7', + [stargateV2BridgeToken.USDC]: '0x27a16dc786820B16E5c9028b75B99F6f604b5d26' + }, + [BLOCKCHAIN_NAME.KAVA]: { + [stargateV2BridgeToken.USDT]: '0x41A5b0470D96656Fb3e8f68A218b39AdBca3420b' + }, + [BLOCKCHAIN_NAME.SCROLL]: { + [stargateV2BridgeToken.ETH]: '0xC2b638Cb5042c1B3c5d5C969361fB50569840583', + [stargateV2BridgeToken.USDC]: '0x3Fc69CC4A842838bCDC9499178740226062b14E4' + }, + [BLOCKCHAIN_NAME.AURORA]: { + [stargateV2BridgeToken.USDC]: '0x81F6138153d473E8c5EcebD3DC8Cd4903506B075' + }, + [BLOCKCHAIN_NAME.KLAYTN]: { + [stargateV2BridgeToken.ETH]: '0xBB4957E44401a31ED81Cab33539d9e8993FA13Ce', + [stargateV2BridgeToken.USDC]: '0x01A7c805cc47AbDB254CD8AaD29dE5e447F59224', + [stargateV2BridgeToken.USDT]: '0x8619bA1B324e099CB2227060c4BC5bDEe14456c6' + }, + [BLOCKCHAIN_NAME.IOTA]: { + [stargateV2BridgeToken.ETH]: '0x9c2dc7377717603eB92b2655c5f2E7997a4945BD', + [stargateV2BridgeToken.USDC]: '0x8e8539e4CcD69123c623a106773F2b0cbbc58746', + [stargateV2BridgeToken.USDT]: '0x77C71633C34C3784ede189d74223122422492a0f' + }, + [BLOCKCHAIN_NAME.TAIKO]: { + [stargateV2BridgeToken.USDC]: '0x77C71633C34C3784ede189d74223122422492a0f', + [stargateV2BridgeToken.USDT]: '0x1C10CC06DC6D35970d1D53B2A23c76ef370d4135' + }, + [BLOCKCHAIN_NAME.SEI]: { + [stargateV2BridgeToken.WETH]: '0x5c386D85b1B82FD9Db681b9176C8a4248bb6345B' + } +}; diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-cross-chain-supported-blockchains.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-cross-chain-supported-blockchains.ts new file mode 100644 index 0000000000..28334be04b --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-cross-chain-supported-blockchains.ts @@ -0,0 +1,23 @@ +import { BLOCKCHAIN_NAME } from 'src/core/blockchain/models/blockchain-name'; + +export const stargateV2SupportedBlockchains = [ + BLOCKCHAIN_NAME.ETHEREUM, + BLOCKCHAIN_NAME.BINANCE_SMART_CHAIN, + BLOCKCHAIN_NAME.POLYGON, + BLOCKCHAIN_NAME.AVALANCHE, + BLOCKCHAIN_NAME.ARBITRUM, + BLOCKCHAIN_NAME.OPTIMISM, + BLOCKCHAIN_NAME.METIS, + BLOCKCHAIN_NAME.LINEA, + BLOCKCHAIN_NAME.MANTLE, + BLOCKCHAIN_NAME.BASE, + BLOCKCHAIN_NAME.KAVA, + BLOCKCHAIN_NAME.SCROLL, + BLOCKCHAIN_NAME.AURORA, + BLOCKCHAIN_NAME.KLAYTN, + BLOCKCHAIN_NAME.IOTA, + BLOCKCHAIN_NAME.TAIKO, + BLOCKCHAIN_NAME.SEI +]; + +export type StargateV2SupportedBlockchains = (typeof stargateV2SupportedBlockchains)[number]; diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-abi.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-abi.ts new file mode 100644 index 0000000000..f00afc05eb --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-abi.ts @@ -0,0 +1,94 @@ +import { AbiItem } from 'web3-utils'; + +export const stargateV2PoolAbi = [ + { + inputs: [ + { + components: [ + { internalType: 'uint32', name: 'dstEid', type: 'uint32' }, + { internalType: 'bytes32', name: 'to', type: 'bytes32' }, + { internalType: 'uint256', name: 'amountLD', type: 'uint256' }, + { internalType: 'uint256', name: 'minAmountLD', type: 'uint256' }, + { internalType: 'bytes', name: 'extraOptions', type: 'bytes' }, + { internalType: 'bytes', name: 'composeMsg', type: 'bytes' }, + { internalType: 'bytes', name: 'oftCmd', type: 'bytes' } + ], + internalType: 'struct SendParam', + name: '_sendParam', + type: 'tuple' + } + ], + name: 'quoteOFT', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'minAmountLD', type: 'uint256' }, + { internalType: 'uint256', name: 'maxAmountLD', type: 'uint256' } + ], + internalType: 'struct OFTLimit', + name: 'limit', + type: 'tuple' + }, + { + components: [ + { internalType: 'int256', name: 'feeAmountLD', type: 'int256' }, + { internalType: 'string', name: 'description', type: 'string' } + ], + internalType: 'struct OFTFeeDetail[]', + name: 'oftFeeDetails', + type: 'tuple[]' + }, + { + components: [ + { internalType: 'uint256', name: 'amountSentLD', type: 'uint256' }, + { internalType: 'uint256', name: 'amountReceivedLD', type: 'uint256' } + ], + internalType: 'struct OFTReceipt', + name: 'receipt', + type: 'tuple' + } + ], + stateMutability: 'view', + type: 'function' + } +] as AbiItem[]; + +export const stargateV2SendQuoteAbi = [ + { + inputs: [ + { + components: [ + { internalType: 'uint32', name: 'dstEid', type: 'uint32' }, + { internalType: 'bytes32', name: 'to', type: 'bytes32' }, + { internalType: 'uint256', name: 'amountLD', type: 'uint256' }, + { internalType: 'uint256', name: 'minAmountLD', type: 'uint256' }, + { internalType: 'bytes', name: 'extraOptions', type: 'bytes' }, + { internalType: 'bytes', name: 'composeMsg', type: 'bytes' }, + { internalType: 'bytes', name: 'oftCmd', type: 'bytes' } + ], + internalType: 'struct SendParam', + name: '_sendParam', + type: 'tuple' + }, + { + internalType: 'bool', + name: '_payInLzToken', + type: 'bool' + } + ], + name: 'quoteSend', + outputs: [ + { + components: [ + { internalType: 'uint256', name: 'nativeFee', type: 'uint256' }, + { internalType: 'uint256', name: 'lzTokenFee', type: 'uint256' } + ], + internalType: 'struct MessagingFee', + name: 'fee', + type: 'tuple' + } + ], + stateMutability: 'view', + type: 'function' + } +] as AbiItem[]; diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-id.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-id.ts new file mode 100644 index 0000000000..844b9e741c --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-id.ts @@ -0,0 +1,15 @@ +import { StargateV2BridgeToken, stargateV2BridgeToken } from './stargate-v2-bridge-token'; + +const pools = { + [stargateV2BridgeToken.USDC]: 1, + [stargateV2BridgeToken.USDCe]: 1, + [stargateV2BridgeToken.USDT]: 2, + [stargateV2BridgeToken.mUSD]: 2, + [stargateV2BridgeToken.ETH]: 13, + [stargateV2BridgeToken.WETH]: 13, + [stargateV2BridgeToken.METIS]: 17, + [stargateV2BridgeToken.METH]: 22 +} as const; + +export const stargateV2PoolId: Record = pools; +export type StargateV2PoolId = (typeof pools)[keyof typeof pools]; diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/modal/stargate-v2-quote-params-struct.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/modal/stargate-v2-quote-params-struct.ts new file mode 100644 index 0000000000..fbe368bdd6 --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/modal/stargate-v2-quote-params-struct.ts @@ -0,0 +1,19 @@ +export interface StargateV2QuoteParamsStruct { + dstEid: number; + to: string; + amountLD: string; + minAmountLD: string; + extraOptions: string; + composeMsg: string; + oftCmd: 1 | 0; +} + +export interface StargateV2QuoteOFTResponse { + amountSentLD?: string[]; + amountReceivedLD: string[]; +} + +export interface StargateV2MessagingFee { + nativeFee: string; + lzTokenFee: string; +} diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts new file mode 100644 index 0000000000..2d0d52aa8a --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts @@ -0,0 +1,250 @@ +import { ethers } from 'ethers'; +import { NotSupportedTokensError, RubicSdkError } from 'src/common/errors'; +import { PriceToken, PriceTokenAmount } from 'src/common/tokens'; +import { parseError } from 'src/common/utils/errors'; +import { + BLOCKCHAIN_NAME, + BlockchainName, + EvmBlockchainName +} from 'src/core/blockchain/models/blockchain-name'; +import { Web3Pure } from 'src/core/blockchain/web3-pure/web3-pure'; +import { Injector } from 'src/core/injector/injector'; +import { getFromWithoutFee } from 'src/features/common/utils/get-from-without-fee'; +import { EvmOnChainTrade } from 'src/features/on-chain/calculation-manager/providers/common/on-chain-trade/evm-on-chain-trade/evm-on-chain-trade'; + +import { RequiredCrossChainOptions } from '../../models/cross-chain-options'; +import { CROSS_CHAIN_TRADE_TYPE } from '../../models/cross-chain-trade-type'; +import { CrossChainProvider } from '../common/cross-chain-provider'; +import { CalculationResult } from '../common/models/calculation-result'; +import { FeeInfo } from '../common/models/fee-info'; +import { RubicStep } from '../common/models/rubicStep'; +import { ProxyCrossChainEvmTrade } from '../common/proxy-cross-chain-evm-facade/proxy-cross-chain-evm-trade'; +import { StargateV2BridgeToken } from './constants/stargate-v2-bridge-token'; +import { stargateV2ChainIds } from './constants/stargate-v2-chain-id'; +import { stargateV2ContractAddress } from './constants/stargate-v2-contract-address'; +import { + StargateV2SupportedBlockchains, + stargateV2SupportedBlockchains +} from './constants/stargate-v2-cross-chain-supported-blockchains'; +import { stargateV2PoolAbi } from './constants/stargate-v2-pool-abi'; +import { StargateV2QuoteOFTResponse } from './modal/stargate-v2-quote-params-struct'; +import { StargateV2CrossChainTrade } from './stargate-v2-cross-chain-trade'; + +export class StargateV2CrossChainProvider extends CrossChainProvider { + public readonly type = CROSS_CHAIN_TRADE_TYPE.STARGATE_V2; + + public isSupportedBlockchain(fromBlockchain: BlockchainName): boolean { + return stargateV2SupportedBlockchains.some( + supportedBlockchain => supportedBlockchain === fromBlockchain + ); + } + + // private static hasDirectRoute( + // from: PriceTokenAmount, + // to: PriceTokenAmount + // ): boolean { + // const fromBlockchain = from.blockchain as StargateV2SupportedBlockchains; + // const toBlockchain = to.blockchain as StargateV2SupportedBlockchains; + // const fromSymbol = StargateV2CrossChainProvider.getSymbol(from.symbol, from.blockchain); + // const toSymbol = StargateV2CrossChainProvider.getSymbol(to.symbol, to.blockchain); + // const srcPoolId = stargateV2PoolId[fromSymbol as StargateV2BridgeToken]; + // const srcSupportedPools = stargateV2BlockchainSupportedPools[fromBlockchain]; + // if (!srcPoolId || !srcSupportedPools?.includes(srcPoolId)) { + // return false; + // } + // const dstPoolId = stargateV2PoolId[toSymbol as StargateV2BridgeToken]; + // if (srcPoolId === dstPoolId) { + // return true; + // } + // const dstSupportedPools = stargateV2BlockchainSupportedPools[toBlockchain]; + // if (!dstSupportedPools?.includes(dstPoolId)) { + // throw new RubicSdkError('Tokens are not supported.'); + // } + // if (fromSymbol === toSymbol) { + // return true; + // } + // return false; + // } + + public async calculate( + from: PriceTokenAmount, + toToken: PriceToken, + options: RequiredCrossChainOptions + ): Promise { + try { + const fromBlockchain = from.blockchain as StargateV2SupportedBlockchains; + const toBlockchain = toToken.blockchain as StargateV2SupportedBlockchains; + const useProxy = options?.useProxy?.[this.type] ?? true; + if (!this.areSupportedBlockchains(fromBlockchain, toBlockchain)) { + return { + trade: null, + error: new NotSupportedTokensError(), + tradeType: this.type + }; + } + const dstChainId = stargateV2ChainIds[toBlockchain]; + + const feeInfo = await this.getFeeInfo( + from.blockchain, + options.providerAddress, + from, + useProxy + ); + const FAKE_ADDRESS = '0x17235BeeF7CC95a6cc65E98D7b3cA4F5B7f75283'; + const fromAddress = options?.fromAddress || FAKE_ADDRESS; + const fromSymbol = StargateV2CrossChainProvider.getSymbol( + from.symbol, + from.blockchain + ) as StargateV2BridgeToken; + const fromWithoutFee = getFromWithoutFee( + from, + feeInfo.rubicProxy?.platformFee?.percent + ); + const amountLD = fromWithoutFee.stringWeiAmount; + const sendParams = [ + dstChainId, + ethers.utils.hexZeroPad(fromAddress, 32), + amountLD, + amountLD, + '0x', + '0x', + 0 + ]; + + const { amountReceivedLD } = await this.getRecieveAmount( + sendParams, + from.blockchain, + fromSymbol + ); + const amountReceived = amountReceivedLD?.[1] || fromWithoutFee.stringWeiAmount; + sendParams[3] = amountReceived; + + const to = new PriceTokenAmount({ + ...toToken.asStruct, + tokenAmount: Web3Pure.fromWei(amountReceived, toToken.decimals) + }); + + const srcOnChainTrade: EvmOnChainTrade | null = null; + const routePath = await this.getRoutePath(from, to, srcOnChainTrade); + const gasData = + options.gasCalculation === 'enabled' + ? await StargateV2CrossChainTrade.getGasData( + from, + to, + feeInfo, + options.slippageTolerance, + options.providerAddress, + routePath, + options.receiverAddress + ) + : null; + return { + trade: new StargateV2CrossChainTrade( + { + from, + to, + feeInfo, + slippageTolerance: options.slippageTolerance, + gasData, + priceImpact: from.calculatePriceImpactPercent(to), + cryptoFeeToken: null + }, + options.providerAddress, + routePath + ), + tradeType: this.type + }; + } catch (err) { + return { + trade: null, + error: parseError(err), + tradeType: this.type + }; + } + } + + public static getSymbol(symbol: string, blockchain: BlockchainName): string { + if (blockchain === BLOCKCHAIN_NAME.METIS && symbol.toLowerCase() === 'usdt') { + return 'm.USDT'; + } + if (blockchain === BLOCKCHAIN_NAME.METIS && symbol.toLowerCase() === 'eth') { + return 'WETH'; + } + if (blockchain === BLOCKCHAIN_NAME.SCROLL && symbol.toLowerCase() === 'usdc') { + return 'USDC.e'; + } + return symbol; + } + + protected async getFeeInfo( + fromBlockchain: Partial, + providerAddress: string, + percentFeeToken: PriceTokenAmount, + useProxy: boolean + ): Promise { + return ProxyCrossChainEvmTrade.getFeeInfo( + fromBlockchain, + providerAddress, + percentFeeToken, + useProxy + ); + } + + private async getRecieveAmount( + sendParam: (string | number)[], + fromBlockchain: EvmBlockchainName, + tokenSymbol: StargateV2BridgeToken + ): Promise { + const contractAddress = + stargateV2ContractAddress?.[fromBlockchain as StargateV2SupportedBlockchains]?.[ + tokenSymbol + ]; + if (!contractAddress) { + throw new RubicSdkError(); + } + try { + const { 2: amountReceivedLD } = await Injector.web3PublicService + .getWeb3Public(fromBlockchain) + .callContractMethod<{ 2: string[] }>( + contractAddress, + stargateV2PoolAbi, + 'quoteOFT', + [sendParam] + ); + + return { + amountReceivedLD + }; + } catch (err) { + throw new RubicSdkError(err?.message); + } + } + + protected async getRoutePath( + from: PriceTokenAmount, + to: PriceTokenAmount, + srcOnChainTrade: EvmOnChainTrade | null + ): Promise { + if (srcOnChainTrade) { + return [ + { + type: 'on-chain', + provider: srcOnChainTrade.type, + path: [srcOnChainTrade.from, srcOnChainTrade.to] + }, + { + type: 'cross-chain', + provider: CROSS_CHAIN_TRADE_TYPE.STARGATE_V2, + path: [srcOnChainTrade.to, to] + } + ]; + } + return [ + { + type: 'cross-chain', + provider: CROSS_CHAIN_TRADE_TYPE.STARGATE_V2, + path: [from, to] + } + ]; + } +} diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts new file mode 100644 index 0000000000..de2db390bc --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts @@ -0,0 +1,158 @@ +import BigNumber from 'bignumber.js'; +import { RubicSdkError } from 'src/common/errors'; +import { PriceToken, PriceTokenAmount } from 'src/common/tokens'; +import { BlockchainName, EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; +import { EvmWeb3Pure } from 'src/core/blockchain/web3-pure/typed-web3-pure/evm-web3-pure/evm-web3-pure'; +import { EvmEncodeConfig } from 'src/core/blockchain/web3-pure/typed-web3-pure/evm-web3-pure/models/evm-encode-config'; +import { ContractParams } from 'src/features/common/models/contract-params'; +import { SwapTransactionOptions } from 'src/features/common/models/swap-transaction-options'; +import { EvmOnChainTrade } from 'src/features/on-chain/calculation-manager/providers/common/on-chain-trade/evm-on-chain-trade/evm-on-chain-trade'; + +import { CROSS_CHAIN_TRADE_TYPE } from '../../models/cross-chain-trade-type'; +import { getCrossChainGasData } from '../../utils/get-cross-chain-gas-data'; +import { rubicProxyContractAddress } from '../common/constants/rubic-proxy-contract-address'; +import { EvmCrossChainTrade } from '../common/emv-cross-chain-trade/evm-cross-chain-trade'; +import { GasData } from '../common/emv-cross-chain-trade/models/gas-data'; +import { BRIDGE_TYPE } from '../common/models/bridge-type'; +import { FeeInfo } from '../common/models/fee-info'; +import { GetContractParamsOptions } from '../common/models/get-contract-params-options'; +import { OnChainSubtype } from '../common/models/on-chain-subtype'; +import { RubicStep } from '../common/models/rubicStep'; +import { TradeInfo } from '../common/models/trade-info'; +import { StargateV2SupportedBlockchains } from './constants/stargate-v2-cross-chain-supported-blockchains'; + +export class StargateV2CrossChainTrade extends EvmCrossChainTrade { + protected get methodName(): string { + return 'swapAndStartBridgeTokensViaStargateV2'; + } + + public static async getGasData( + from: PriceTokenAmount, + toToken: PriceTokenAmount, + feeInfo: FeeInfo, + slippageTolerance: number, + providerAddress: string, + routePath: RubicStep[], + receiverAddress?: string + ): Promise { + try { + const trade = new StargateV2CrossChainTrade( + { + from, + to: toToken, + slippageTolerance, + priceImpact: null, + gasData: null, + feeInfo, + cryptoFeeToken: null + }, + providerAddress || EvmWeb3Pure.EMPTY_ADDRESS, + routePath + ); + + return getCrossChainGasData(trade, receiverAddress); + } catch (_err) { + return null; + } + } + + public readonly from: PriceTokenAmount; + + public readonly to: PriceTokenAmount; + + public readonly feeInfo: FeeInfo; + + public readonly type = CROSS_CHAIN_TRADE_TYPE.STARGATE_V2; + + public readonly gasData: GasData; + + public readonly isAggregator = false; + + public readonly slippageTolerance: number; + + public readonly priceImpact = null; + + public readonly onChainSubtype: OnChainSubtype = { from: undefined, to: undefined }; + + public readonly bridgeType = BRIDGE_TYPE.STARGATE_V2; + + public get fromBlockchain(): StargateV2SupportedBlockchains { + return this.from.blockchain as StargateV2SupportedBlockchains; + } + + protected get fromContractAddress(): string { + return this.isProxyTrade ? rubicProxyContractAddress[this.fromBlockchain].gateway : ' '; + } + + private readonly onChainTrade: EvmOnChainTrade | null; + + private readonly dstChainTrade: EvmOnChainTrade | null; + + private readonly cryptoFeeToken: PriceToken | null; + + public readonly toTokenAmountMin = new BigNumber(0); + + constructor( + crossChainTrade: { + from: PriceTokenAmount; + to: PriceTokenAmount; + slippageTolerance: number; + priceImpact: number | null; + gasData: GasData | null; + feeInfo: FeeInfo; + cryptoFeeToken: PriceToken | null; + }, + providerAddress: string, + routePath: RubicStep[] + ) { + super(providerAddress, routePath); + console.log(providerAddress); + this.from = crossChainTrade.from; + this.to = crossChainTrade.to; + this.feeInfo = crossChainTrade.feeInfo; + this.gasData = crossChainTrade.gasData; + this.slippageTolerance = crossChainTrade.slippageTolerance; + this.cryptoFeeToken = crossChainTrade.cryptoFeeToken; + this.onChainTrade = null; + this.dstChainTrade = null; + } + + protected async getContractParams(options: GetContractParamsOptions): Promise { + console.log(options.fromAddress); + return Promise.reject(new RubicSdkError('method not implemented')); + } + + protected async getTransactionConfigAndAmount( + receiverAddress?: string | undefined + ): Promise<{ config: EvmEncodeConfig; amount: string }> { + console.log(receiverAddress); + return Promise.reject(new RubicSdkError('method not implemented')); + } + + protected async swapDirect(options?: SwapTransactionOptions): Promise { + console.log(options); + return Promise.reject(new RubicSdkError('method not implemented')); + } + + protected async setTransactionConfig( + skipAmountChangeCheck: boolean, + useCacheData: boolean + ): Promise { + console.log(skipAmountChangeCheck, useCacheData); + return Promise.reject(new RubicSdkError('method not implemented')); + } + + public getTradeAmountRatio(fromUsd: BigNumber): BigNumber { + return fromUsd.dividedBy(this.to.tokenAmount); + } + + public getTradeInfo(): TradeInfo { + return { + estimatedGas: this.estimatedGas, + feeInfo: this.feeInfo, + priceImpact: this.priceImpact || null, + slippage: this.slippageTolerance * 100, + routePath: this.routePath + }; + } +} diff --git a/src/features/cross-chain/status-manager/cross-chain-status-manager.ts b/src/features/cross-chain/status-manager/cross-chain-status-manager.ts index 76aad738c5..23fa660223 100644 --- a/src/features/cross-chain/status-manager/cross-chain-status-manager.ts +++ b/src/features/cross-chain/status-manager/cross-chain-status-manager.ts @@ -95,7 +95,8 @@ export class CrossChainStatusManager { [CROSS_CHAIN_TRADE_TYPE.LAYERZERO]: this.getLayerZeroDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.ARCHON_BRIDGE]: this.getLayerZeroDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.MESON]: this.getMesonDstSwapStatus, - [CROSS_CHAIN_TRADE_TYPE.OWL_TO_BRIDGE]: this.getOwlToDstSwapStatus + [CROSS_CHAIN_TRADE_TYPE.OWL_TO_BRIDGE]: this.getOwlToDstSwapStatus, + [CROSS_CHAIN_TRADE_TYPE.STARGATE_V2]: this.getLayerZeroDstSwapStatus }; /** From b7220a2bff5a4987ffae685a8474d67835a34a39 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 1 Jul 2024 10:15:17 +0300 Subject: [PATCH 02/22] add stargate trade class --- package.json | 2 +- .../constants/stargate-v2-pool-abi.ts | 72 ++++++ .../stargate-v2-cross-chain-provider.ts | 92 ++++---- .../stargate-v2-cross-chain-trade.ts | 214 +++++++++++++++--- 4 files changed, 299 insertions(+), 81 deletions(-) diff --git a/package.json b/package.json index 16c8a9560a..ab43fde3d1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.29.0", + "version": "5.30.0-alpha-stargate-v2.0", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-abi.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-abi.ts index f00afc05eb..4e67875cb1 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-abi.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-abi.ts @@ -92,3 +92,75 @@ export const stargateV2SendQuoteAbi = [ type: 'function' } ] as AbiItem[]; + +export const stargateV2SendTokenAbi = [ + { + inputs: [ + { + components: [ + { internalType: 'uint32', name: 'dstEid', type: 'uint32' }, + { internalType: 'bytes32', name: 'to', type: 'bytes32' }, + { internalType: 'uint256', name: 'amountLD', type: 'uint256' }, + { internalType: 'uint256', name: 'minAmountLD', type: 'uint256' }, + { internalType: 'bytes', name: 'extraOptions', type: 'bytes' }, + { internalType: 'bytes', name: 'composeMsg', type: 'bytes' }, + { internalType: 'bytes', name: 'oftCmd', type: 'bytes' } + ], + internalType: 'struct SendParam', + name: '_sendParam', + type: 'tuple' + }, + { + components: [ + { internalType: 'uint256', name: 'nativeFee', type: 'uint256' }, + { internalType: 'uint256', name: 'lzTokenFee', type: 'uint256' } + ], + internalType: 'struct MessagingFee', + name: '_fee', + type: 'tuple' + }, + { internalType: 'address', name: '_refundAddress', type: 'address' } + ], + name: 'sendToken', + outputs: [ + { + components: [ + { internalType: 'bytes32', name: 'guid', type: 'bytes32' }, + { internalType: 'uint64', name: 'nonce', type: 'uint64' }, + { + components: [ + { internalType: 'uint256', name: 'nativeFee', type: 'uint256' }, + { internalType: 'uint256', name: 'lzTokenFee', type: 'uint256' } + ], + internalType: 'struct MessagingFee', + name: 'fee', + type: 'tuple' + } + ], + internalType: 'struct MessagingReceipt', + name: 'msgReceipt', + type: 'tuple' + }, + { + components: [ + { internalType: 'uint256', name: 'amountSentLD', type: 'uint256' }, + { internalType: 'uint256', name: 'amountReceivedLD', type: 'uint256' } + ], + internalType: 'struct OFTReceipt', + name: 'oftReceipt', + type: 'tuple' + }, + { + components: [ + { internalType: 'uint72', name: 'ticketId', type: 'uint72' }, + { internalType: 'bytes', name: 'passengerBytes', type: 'bytes' } + ], + internalType: 'struct Ticket', + name: 'ticket', + type: 'tuple' + } + ], + stateMutability: 'payable', + type: 'function' + } +] as AbiItem[]; diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts index 2d0d52aa8a..45ed7e5706 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts @@ -1,5 +1,5 @@ import { ethers } from 'ethers'; -import { NotSupportedTokensError, RubicSdkError } from 'src/common/errors'; +import { NotSupportedBlockchain, NotSupportedTokensError, RubicSdkError } from 'src/common/errors'; import { PriceToken, PriceTokenAmount } from 'src/common/tokens'; import { parseError } from 'src/common/utils/errors'; import { @@ -10,7 +10,6 @@ import { import { Web3Pure } from 'src/core/blockchain/web3-pure/web3-pure'; import { Injector } from 'src/core/injector/injector'; import { getFromWithoutFee } from 'src/features/common/utils/get-from-without-fee'; -import { EvmOnChainTrade } from 'src/features/on-chain/calculation-manager/providers/common/on-chain-trade/evm-on-chain-trade/evm-on-chain-trade'; import { RequiredCrossChainOptions } from '../../models/cross-chain-options'; import { CROSS_CHAIN_TRADE_TYPE } from '../../models/cross-chain-trade-type'; @@ -27,7 +26,10 @@ import { stargateV2SupportedBlockchains } from './constants/stargate-v2-cross-chain-supported-blockchains'; import { stargateV2PoolAbi } from './constants/stargate-v2-pool-abi'; -import { StargateV2QuoteOFTResponse } from './modal/stargate-v2-quote-params-struct'; +import { + StargateV2QuoteOFTResponse, + StargateV2QuoteParamsStruct +} from './modal/stargate-v2-quote-params-struct'; import { StargateV2CrossChainTrade } from './stargate-v2-cross-chain-trade'; export class StargateV2CrossChainProvider extends CrossChainProvider { @@ -71,11 +73,23 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { toToken: PriceToken, options: RequiredCrossChainOptions ): Promise { + if (!this.isSupportedBlockchain(from.blockchain)) { + throw new NotSupportedBlockchain(); + } try { const fromBlockchain = from.blockchain as StargateV2SupportedBlockchains; const toBlockchain = toToken.blockchain as StargateV2SupportedBlockchains; - const useProxy = options?.useProxy?.[this.type] ?? true; - if (!this.areSupportedBlockchains(fromBlockchain, toBlockchain)) { + const useProxy = false; + + const fromSymbol = StargateV2CrossChainProvider.getSymbol( + from.symbol, + from.blockchain + ) as StargateV2BridgeToken; + const isSupported = + stargateV2ContractAddress?.[fromBlockchain as StargateV2SupportedBlockchains]?.[ + fromSymbol + ]; + if (!isSupported) { return { trade: null, error: new NotSupportedTokensError(), @@ -92,40 +106,36 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { ); const FAKE_ADDRESS = '0x17235BeeF7CC95a6cc65E98D7b3cA4F5B7f75283'; const fromAddress = options?.fromAddress || FAKE_ADDRESS; - const fromSymbol = StargateV2CrossChainProvider.getSymbol( - from.symbol, - from.blockchain - ) as StargateV2BridgeToken; + const fromWithoutFee = getFromWithoutFee( from, feeInfo.rubicProxy?.platformFee?.percent ); const amountLD = fromWithoutFee.stringWeiAmount; - const sendParams = [ - dstChainId, - ethers.utils.hexZeroPad(fromAddress, 32), - amountLD, - amountLD, - '0x', - '0x', - 0 - ]; - - const { amountReceivedLD } = await this.getRecieveAmount( + const sendParams: StargateV2QuoteParamsStruct = { + dstEid: dstChainId, + to: ethers.utils.hexZeroPad(fromAddress, 32), + amountLD: amountLD, + minAmountLD: amountLD, + extraOptions: '0x', + composeMsg: '0x', + oftCmd: 0 + }; + + const { amountReceivedLD } = await this.getReceiveAmount( sendParams, from.blockchain, fromSymbol ); - const amountReceived = amountReceivedLD?.[1] || fromWithoutFee.stringWeiAmount; - sendParams[3] = amountReceived; + const amountReceived = amountReceivedLD[1] as string; + sendParams.minAmountLD = amountReceived; const to = new PriceTokenAmount({ ...toToken.asStruct, tokenAmount: Web3Pure.fromWei(amountReceived, toToken.decimals) }); - const srcOnChainTrade: EvmOnChainTrade | null = null; - const routePath = await this.getRoutePath(from, to, srcOnChainTrade); + const routePath = await this.getRoutePath(from, to); const gasData = options.gasCalculation === 'enabled' ? await StargateV2CrossChainTrade.getGasData( @@ -135,6 +145,7 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { options.slippageTolerance, options.providerAddress, routePath, + sendParams, options.receiverAddress ) : null; @@ -147,7 +158,7 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { slippageTolerance: options.slippageTolerance, gasData, priceImpact: from.calculatePriceImpactPercent(to), - cryptoFeeToken: null + sendParams }, options.providerAddress, routePath @@ -190,18 +201,14 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { ); } - private async getRecieveAmount( - sendParam: (string | number)[], + private async getReceiveAmount( + sendParam: StargateV2QuoteParamsStruct, fromBlockchain: EvmBlockchainName, tokenSymbol: StargateV2BridgeToken ): Promise { - const contractAddress = - stargateV2ContractAddress?.[fromBlockchain as StargateV2SupportedBlockchains]?.[ - tokenSymbol - ]; - if (!contractAddress) { - throw new RubicSdkError(); - } + const contractAddress = stargateV2ContractAddress[ + fromBlockchain as StargateV2SupportedBlockchains + ][tokenSymbol] as string; try { const { 2: amountReceivedLD } = await Injector.web3PublicService .getWeb3Public(fromBlockchain) @@ -222,23 +229,8 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { protected async getRoutePath( from: PriceTokenAmount, - to: PriceTokenAmount, - srcOnChainTrade: EvmOnChainTrade | null + to: PriceTokenAmount ): Promise { - if (srcOnChainTrade) { - return [ - { - type: 'on-chain', - provider: srcOnChainTrade.type, - path: [srcOnChainTrade.from, srcOnChainTrade.to] - }, - { - type: 'cross-chain', - provider: CROSS_CHAIN_TRADE_TYPE.STARGATE_V2, - path: [srcOnChainTrade.to, to] - } - ]; - } return [ { type: 'cross-chain', diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts index de2db390bc..d029519660 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts @@ -1,16 +1,20 @@ import BigNumber from 'bignumber.js'; -import { RubicSdkError } from 'src/common/errors'; -import { PriceToken, PriceTokenAmount } from 'src/common/tokens'; +import { FailedToCheckForTransactionReceiptError, RubicSdkError } from 'src/common/errors'; +import { PriceTokenAmount } from 'src/common/tokens'; import { BlockchainName, EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; +import { EvmWeb3Private } from 'src/core/blockchain/web3-private-service/web3-private/evm-web3-private/evm-web3-private'; import { EvmWeb3Pure } from 'src/core/blockchain/web3-pure/typed-web3-pure/evm-web3-pure/evm-web3-pure'; import { EvmEncodeConfig } from 'src/core/blockchain/web3-pure/typed-web3-pure/evm-web3-pure/models/evm-encode-config'; +import { Injector } from 'src/core/injector/injector'; import { ContractParams } from 'src/features/common/models/contract-params'; import { SwapTransactionOptions } from 'src/features/common/models/swap-transaction-options'; -import { EvmOnChainTrade } from 'src/features/on-chain/calculation-manager/providers/common/on-chain-trade/evm-on-chain-trade/evm-on-chain-trade'; +import { checkUnsupportedReceiverAddress } from 'src/features/common/utils/check-unsupported-receiver-address'; import { CROSS_CHAIN_TRADE_TYPE } from '../../models/cross-chain-trade-type'; import { getCrossChainGasData } from '../../utils/get-cross-chain-gas-data'; import { rubicProxyContractAddress } from '../common/constants/rubic-proxy-contract-address'; +import { evmCommonCrossChainAbi } from '../common/emv-cross-chain-trade/constants/evm-common-cross-chain-abi'; +import { gatewayRubicCrossChainAbi } from '../common/emv-cross-chain-trade/constants/gateway-rubic-cross-chain-abi'; import { EvmCrossChainTrade } from '../common/emv-cross-chain-trade/evm-cross-chain-trade'; import { GasData } from '../common/emv-cross-chain-trade/models/gas-data'; import { BRIDGE_TYPE } from '../common/models/bridge-type'; @@ -19,11 +23,20 @@ import { GetContractParamsOptions } from '../common/models/get-contract-params-o import { OnChainSubtype } from '../common/models/on-chain-subtype'; import { RubicStep } from '../common/models/rubicStep'; import { TradeInfo } from '../common/models/trade-info'; +import { ProxyCrossChainEvmTrade } from '../common/proxy-cross-chain-evm-facade/proxy-cross-chain-evm-trade'; +import { StargateCrossChainProvider } from '../stargate-provider/stargate-cross-chain-provider'; +import { StargateV2BridgeToken } from './constants/stargate-v2-bridge-token'; +import { stargateV2ContractAddress } from './constants/stargate-v2-contract-address'; import { StargateV2SupportedBlockchains } from './constants/stargate-v2-cross-chain-supported-blockchains'; +import { stargateV2SendQuoteAbi, stargateV2SendTokenAbi } from './constants/stargate-v2-pool-abi'; +import { + StargateV2MessagingFee, + StargateV2QuoteParamsStruct +} from './modal/stargate-v2-quote-params-struct'; export class StargateV2CrossChainTrade extends EvmCrossChainTrade { protected get methodName(): string { - return 'swapAndStartBridgeTokensViaStargateV2'; + return 'startBridgeTokensViaGenericCrossChain'; } public static async getGasData( @@ -33,6 +46,7 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { slippageTolerance: number, providerAddress: string, routePath: RubicStep[], + sendParams: StargateV2QuoteParamsStruct, receiverAddress?: string ): Promise { try { @@ -44,7 +58,7 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { priceImpact: null, gasData: null, feeInfo, - cryptoFeeToken: null + sendParams }, providerAddress || EvmWeb3Pure.EMPTY_ADDRESS, routePath @@ -56,6 +70,10 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { } } + protected get web3Private(): EvmWeb3Private { + return Injector.web3PrivateService.getWeb3PrivateByBlockchain(this.from.blockchain); + } + public readonly from: PriceTokenAmount; public readonly to: PriceTokenAmount; @@ -76,19 +94,23 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { public readonly bridgeType = BRIDGE_TYPE.STARGATE_V2; + private messagingFee: StargateV2MessagingFee = { nativeFee: '0', lzTokenFee: '0' }; + public get fromBlockchain(): StargateV2SupportedBlockchains { return this.from.blockchain as StargateV2SupportedBlockchains; } protected get fromContractAddress(): string { - return this.isProxyTrade ? rubicProxyContractAddress[this.fromBlockchain].gateway : ' '; + const fromTokenSymbol = StargateCrossChainProvider.getSymbol( + this.from.symbol, + this.from.blockchain + ) as StargateV2BridgeToken; + return this.isProxyTrade + ? rubicProxyContractAddress[this.fromBlockchain].gateway + : (stargateV2ContractAddress?.[this.fromBlockchain]?.[fromTokenSymbol] as string); } - private readonly onChainTrade: EvmOnChainTrade | null; - - private readonly dstChainTrade: EvmOnChainTrade | null; - - private readonly cryptoFeeToken: PriceToken | null; + private readonly stargateV2SendParams: StargateV2QuoteParamsStruct; public readonly toTokenAmountMin = new BigNumber(0); @@ -100,46 +122,148 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { priceImpact: number | null; gasData: GasData | null; feeInfo: FeeInfo; - cryptoFeeToken: PriceToken | null; + sendParams: StargateV2QuoteParamsStruct; }, providerAddress: string, routePath: RubicStep[] ) { super(providerAddress, routePath); - console.log(providerAddress); this.from = crossChainTrade.from; this.to = crossChainTrade.to; this.feeInfo = crossChainTrade.feeInfo; this.gasData = crossChainTrade.gasData; this.slippageTolerance = crossChainTrade.slippageTolerance; - this.cryptoFeeToken = crossChainTrade.cryptoFeeToken; - this.onChainTrade = null; - this.dstChainTrade = null; + this.stargateV2SendParams = crossChainTrade.sendParams; } protected async getContractParams(options: GetContractParamsOptions): Promise { - console.log(options.fromAddress); - return Promise.reject(new RubicSdkError('method not implemented')); + const { + data, + value: providerValue, + to + } = await this.setTransactionConfig( + false, + options?.useCacheData || false, + options?.receiverAddress + ); + try { + const bridgeData = ProxyCrossChainEvmTrade.getBridgeData( + { ...options }, + { + walletAddress: this.walletAddress, + fromTokenAmount: this.from, + toTokenAmount: this.to, + toAddress: undefined, + srcChainTrade: null, + providerAddress: this.providerAddress, + type: `native:${this.type}`, + fromAddress: this.walletAddress + } + ); + // const extraNativeFee = this.from.isNative + // ? new BigNumber(providerValue).minus(this.from.stringWeiAmount).toFixed() + // : new BigNumber(providerValue).toFixed(); + // const providerData = + // await ProxyCrossChainEvmTrade.getGenericProviderData( + // to, + // data, + // this.fromBlockchain as EvmBlockchainName, + // to, + // extraNativeFee + // ) + const methodArguments = [bridgeData, [to, to, this.messagingFee.nativeFee, data]]; + const value = this.getSwapValue(providerValue); + + const transactionConfiguration = EvmWeb3Pure.encodeMethodCall( + rubicProxyContractAddress[this.from.blockchain].router, + evmCommonCrossChainAbi, + this.methodName, + methodArguments, + value + ); + const sendingToken = this.from.isNative ? [] : [this.from.address]; + const sendingAmount = this.from.isNative ? [] : [this.from.stringWeiAmount]; + + return { + contractAddress: rubicProxyContractAddress[this.from.blockchain].gateway, + contractAbi: gatewayRubicCrossChainAbi, + methodName: 'startViaRubic', + methodArguments: [sendingToken, sendingAmount, transactionConfiguration.data], + value + }; + } catch (err) { + console.log(err?.message); + throw new RubicSdkError(err?.message); + } } protected async getTransactionConfigAndAmount( receiverAddress?: string | undefined ): Promise<{ config: EvmEncodeConfig; amount: string }> { - console.log(receiverAddress); - return Promise.reject(new RubicSdkError('method not implemented')); + const fromBlockchain = this.from.blockchain as StargateV2SupportedBlockchains; + const fromTokenSymbol = StargateCrossChainProvider.getSymbol( + this.from.symbol, + this.from.blockchain + ) as StargateV2BridgeToken; + const refundAddress = receiverAddress || this.walletAddress; + const messagingFee = await this.getNativeFee( + this.stargateV2SendParams, + this.from.blockchain, + fromTokenSymbol + ); + this.messagingFee = messagingFee; + const contractAddress = stargateV2ContractAddress?.[fromBlockchain]?.[fromTokenSymbol]; + if (!contractAddress) { + throw new RubicSdkError(); + } + const calldata = await EvmWeb3Pure.encodeMethodCall( + contractAddress, + stargateV2SendTokenAbi, + 'sendToken', + [this.stargateV2SendParams, messagingFee, refundAddress] + ); + return { + config: calldata, + amount: this.to.stringWeiAmount + }; } - protected async swapDirect(options?: SwapTransactionOptions): Promise { - console.log(options); - return Promise.reject(new RubicSdkError('method not implemented')); - } + protected async swapDirect(options: SwapTransactionOptions = {}): Promise { + this.checkWalletConnected(); + checkUnsupportedReceiverAddress(options?.receiverAddress, this.walletAddress); + await this.checkTradeErrors(); + await this.checkAllowanceAndApprove(options); + const { onConfirm, gasLimit, gasPriceOptions } = options; + let transactionHash: string; + const onTransactionHash = (hash: string) => { + if (onConfirm) { + onConfirm(hash); + } + transactionHash = hash; + }; + + try { + const { data, value, to } = await this.setTransactionConfig( + false, + options?.useCacheData || false, + options?.receiverAddress + ); + + await this.web3Private.trySendTransaction(to, { + data, + value, + onTransactionHash, + gas: gasLimit, + gasPriceOptions + }); - protected async setTransactionConfig( - skipAmountChangeCheck: boolean, - useCacheData: boolean - ): Promise { - console.log(skipAmountChangeCheck, useCacheData); - return Promise.reject(new RubicSdkError('method not implemented')); + return transactionHash!; + } catch (err) { + if (err instanceof FailedToCheckForTransactionReceiptError) { + return transactionHash!; + } + throw err; + } } public getTradeAmountRatio(fromUsd: BigNumber): BigNumber { @@ -155,4 +279,34 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { routePath: this.routePath }; } + + private async getNativeFee( + sendParam: StargateV2QuoteParamsStruct, + fromBlockchain: EvmBlockchainName, + tokenSymbol: StargateV2BridgeToken + ): Promise { + const contractAddress = + stargateV2ContractAddress?.[fromBlockchain as StargateV2SupportedBlockchains]?.[ + tokenSymbol + ]; + if (!contractAddress) { + throw new RubicSdkError(); + } + try { + const { 0: nativeFee, 1: lzTokenFee } = await Injector.web3PublicService + .getWeb3Public(fromBlockchain) + .callContractMethod<{ 0: string; 1: string }>( + contractAddress, + stargateV2SendQuoteAbi, + 'quoteSend', + [sendParam, false] + ); + return { + nativeFee, + lzTokenFee + }; + } catch (err) { + throw new RubicSdkError(err?.message); + } + } } From 4302add19d077cc09acf02951de1d9f4b9e38893 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 1 Jul 2024 19:30:10 +0300 Subject: [PATCH 03/22] add supported pools method --- .../constants/stargate-v2-pool-abi.ts | 16 +++++ .../stargate-v2-cross-chain-provider.ts | 71 ++++++++++--------- .../stargate-v2-cross-chain-trade.ts | 41 +++++++++-- 3 files changed, 86 insertions(+), 42 deletions(-) diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-abi.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-abi.ts index 4e67875cb1..6c6e5110cf 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-abi.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-abi.ts @@ -164,3 +164,19 @@ export const stargateV2SendTokenAbi = [ type: 'function' } ] as AbiItem[]; + +export const stargateV2PoolBalanceAbi = [ + { + inputs: [], + name: 'poolBalance', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + } +] as AbiItem[]; diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts index 45ed7e5706..a09f1ba635 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts @@ -9,6 +9,7 @@ import { } from 'src/core/blockchain/models/blockchain-name'; import { Web3Pure } from 'src/core/blockchain/web3-pure/web3-pure'; import { Injector } from 'src/core/injector/injector'; +import { FAKE_WALLET_ADDRESS } from 'src/features/common/constants/fake-wallet-address'; import { getFromWithoutFee } from 'src/features/common/utils/get-from-without-fee'; import { RequiredCrossChainOptions } from '../../models/cross-chain-options'; @@ -18,6 +19,7 @@ import { CalculationResult } from '../common/models/calculation-result'; import { FeeInfo } from '../common/models/fee-info'; import { RubicStep } from '../common/models/rubicStep'; import { ProxyCrossChainEvmTrade } from '../common/proxy-cross-chain-evm-facade/proxy-cross-chain-evm-trade'; +import { stargateV2BlockchainSupportedPools } from './constants/stargate-v2-blockchain-supported-pools'; import { StargateV2BridgeToken } from './constants/stargate-v2-bridge-token'; import { stargateV2ChainIds } from './constants/stargate-v2-chain-id'; import { stargateV2ContractAddress } from './constants/stargate-v2-contract-address'; @@ -26,6 +28,7 @@ import { stargateV2SupportedBlockchains } from './constants/stargate-v2-cross-chain-supported-blockchains'; import { stargateV2PoolAbi } from './constants/stargate-v2-pool-abi'; +import { stargateV2PoolId } from './constants/stargate-v2-pool-id'; import { StargateV2QuoteOFTResponse, StargateV2QuoteParamsStruct @@ -41,33 +44,6 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { ); } - // private static hasDirectRoute( - // from: PriceTokenAmount, - // to: PriceTokenAmount - // ): boolean { - // const fromBlockchain = from.blockchain as StargateV2SupportedBlockchains; - // const toBlockchain = to.blockchain as StargateV2SupportedBlockchains; - // const fromSymbol = StargateV2CrossChainProvider.getSymbol(from.symbol, from.blockchain); - // const toSymbol = StargateV2CrossChainProvider.getSymbol(to.symbol, to.blockchain); - // const srcPoolId = stargateV2PoolId[fromSymbol as StargateV2BridgeToken]; - // const srcSupportedPools = stargateV2BlockchainSupportedPools[fromBlockchain]; - // if (!srcPoolId || !srcSupportedPools?.includes(srcPoolId)) { - // return false; - // } - // const dstPoolId = stargateV2PoolId[toSymbol as StargateV2BridgeToken]; - // if (srcPoolId === dstPoolId) { - // return true; - // } - // const dstSupportedPools = stargateV2BlockchainSupportedPools[toBlockchain]; - // if (!dstSupportedPools?.includes(dstPoolId)) { - // throw new RubicSdkError('Tokens are not supported.'); - // } - // if (fromSymbol === toSymbol) { - // return true; - // } - // return false; - // } - public async calculate( from: PriceTokenAmount, toToken: PriceToken, @@ -77,7 +53,6 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { throw new NotSupportedBlockchain(); } try { - const fromBlockchain = from.blockchain as StargateV2SupportedBlockchains; const toBlockchain = toToken.blockchain as StargateV2SupportedBlockchains; const useProxy = false; @@ -85,11 +60,9 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { from.symbol, from.blockchain ) as StargateV2BridgeToken; - const isSupported = - stargateV2ContractAddress?.[fromBlockchain as StargateV2SupportedBlockchains]?.[ - fromSymbol - ]; - if (!isSupported) { + + const isSupportedPools = this.checkSupportedPools(from, toToken); + if (!isSupportedPools) { return { trade: null, error: new NotSupportedTokensError(), @@ -104,8 +77,7 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { from, useProxy ); - const FAKE_ADDRESS = '0x17235BeeF7CC95a6cc65E98D7b3cA4F5B7f75283'; - const fromAddress = options?.fromAddress || FAKE_ADDRESS; + const fromAddress = options?.fromAddress || FAKE_WALLET_ADDRESS; const fromWithoutFee = getFromWithoutFee( from, @@ -201,6 +173,35 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { ); } + private checkSupportedPools( + from: PriceTokenAmount, + to: PriceToken + ): boolean { + const fromTokenSymbol = StargateV2CrossChainProvider.getSymbol( + from.symbol, + from.blockchain + ) as StargateV2BridgeToken; + const toTokenSymbol = StargateV2CrossChainProvider.getSymbol( + to.symbol, + to.blockchain + ) as StargateV2BridgeToken; + const srcTokenPool = stargateV2PoolId[fromTokenSymbol]; + const dstTokenPool = stargateV2PoolId[toTokenSymbol]; + const srcSupportedPools = + stargateV2BlockchainSupportedPools[from.blockchain as StargateV2SupportedBlockchains]; + const dstSupportedPools = + stargateV2BlockchainSupportedPools[to.blockchain as StargateV2SupportedBlockchains]; + + if ( + srcSupportedPools.includes(srcTokenPool) && + dstSupportedPools.includes(dstTokenPool) && + srcTokenPool === dstTokenPool + ) { + return true; + } + return false; + } + private async getReceiveAmount( sendParam: StargateV2QuoteParamsStruct, fromBlockchain: EvmBlockchainName, diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts index d029519660..183b418fe3 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts @@ -1,5 +1,9 @@ import BigNumber from 'bignumber.js'; -import { FailedToCheckForTransactionReceiptError, RubicSdkError } from 'src/common/errors'; +import { + FailedToCheckForTransactionReceiptError, + MaxAmountError, + RubicSdkError +} from 'src/common/errors'; import { PriceTokenAmount } from 'src/common/tokens'; import { BlockchainName, EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; import { EvmWeb3Private } from 'src/core/blockchain/web3-private-service/web3-private/evm-web3-private/evm-web3-private'; @@ -28,7 +32,11 @@ import { StargateCrossChainProvider } from '../stargate-provider/stargate-cross- import { StargateV2BridgeToken } from './constants/stargate-v2-bridge-token'; import { stargateV2ContractAddress } from './constants/stargate-v2-contract-address'; import { StargateV2SupportedBlockchains } from './constants/stargate-v2-cross-chain-supported-blockchains'; -import { stargateV2SendQuoteAbi, stargateV2SendTokenAbi } from './constants/stargate-v2-pool-abi'; +import { + stargateV2PoolBalanceAbi, + stargateV2SendQuoteAbi, + stargateV2SendTokenAbi +} from './constants/stargate-v2-pool-abi'; import { StargateV2MessagingFee, StargateV2QuoteParamsStruct @@ -94,8 +102,6 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { public readonly bridgeType = BRIDGE_TYPE.STARGATE_V2; - private messagingFee: StargateV2MessagingFee = { nativeFee: '0', lzTokenFee: '0' }; - public get fromBlockchain(): StargateV2SupportedBlockchains { return this.from.blockchain as StargateV2SupportedBlockchains; } @@ -171,7 +177,7 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { // to, // extraNativeFee // ) - const methodArguments = [bridgeData, [to, to, this.messagingFee.nativeFee, data]]; + const methodArguments = [bridgeData, [to, to, providerValue, data]]; const value = this.getSwapValue(providerValue); const transactionConfiguration = EvmWeb3Pure.encodeMethodCall( @@ -206,12 +212,14 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { this.from.blockchain ) as StargateV2BridgeToken; const refundAddress = receiverAddress || this.walletAddress; + await this.checkMaxAmount(this.from.blockchain, fromTokenSymbol); + const messagingFee = await this.getNativeFee( this.stargateV2SendParams, this.from.blockchain, fromTokenSymbol ); - this.messagingFee = messagingFee; + const contractAddress = stargateV2ContractAddress?.[fromBlockchain]?.[fromTokenSymbol]; if (!contractAddress) { throw new RubicSdkError(); @@ -220,7 +228,8 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { contractAddress, stargateV2SendTokenAbi, 'sendToken', - [this.stargateV2SendParams, messagingFee, refundAddress] + [this.stargateV2SendParams, messagingFee, refundAddress], + messagingFee.nativeFee ); return { config: calldata, @@ -280,6 +289,24 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { }; } + private async checkMaxAmount( + fromBlockchain: EvmBlockchainName, + tokenSymbol: StargateV2BridgeToken + ): Promise { + const contractAddress = stargateV2ContractAddress[ + fromBlockchain as StargateV2SupportedBlockchains + ][tokenSymbol] as string; + const sendAmount = new BigNumber(this.stargateV2SendParams.amountLD); + const maxAmount = await Injector.web3PublicService + .getWeb3Public(fromBlockchain) + .callContractMethod(contractAddress, stargateV2PoolBalanceAbi, 'poolBalance'); + const maxAmounSend = new BigNumber(maxAmount); + + if (sendAmount.gt(maxAmounSend)) { + throw new MaxAmountError(maxAmounSend, tokenSymbol as string); + } + } + private async getNativeFee( sendParam: StargateV2QuoteParamsStruct, fromBlockchain: EvmBlockchainName, From 845aabdf57967e0e5a26c0df0adb9001d83685e1 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 3 Jul 2024 13:15:54 +0300 Subject: [PATCH 04/22] fix issues --- package.json | 4 +- .../constants/stargate-v2-contract-address.ts | 2 +- .../stargate-v2-cross-chain-provider.ts | 60 +++++++++++++++---- .../stargate-v2-cross-chain-trade.ts | 54 ++++------------- .../cross-chain-status-manager.ts | 2 +- yarn.lock | 10 ++-- 6 files changed, 71 insertions(+), 61 deletions(-) diff --git a/package.json b/package.json index ab43fde3d1..3eb775a0d4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.30.0-alpha-stargate-v2.0", + "version": "5.30.0-alpha-stargate-v2.2", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -73,7 +73,7 @@ "@1inch/limit-order-protocol-utils": "3.0.1", "@arbitrum/sdk": "^3.1.3", "@debridge-finance/debridge-external-call": "^1.0.7", - "@layerzerolabs/scan-client": "^0.0.0-beta.6", + "@layerzerolabs/scan-client": "0.0.8", "@noble/secp256k1": "^1.7.1", "@pancakeswap/sdk": "^5.1.0", "@pancakeswap/smart-router": "4.2.1", diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-contract-address.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-contract-address.ts index caa4cc00c4..0f6edf28b4 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-contract-address.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-contract-address.ts @@ -48,7 +48,7 @@ export const stargateV2ContractAddress: StargateV2ContractAddress = { [BLOCKCHAIN_NAME.MANTLE]: { [stargateV2BridgeToken.WETH]: '0x4c1d3Fc3fC3c177c3b633427c2F769276c547463', [stargateV2BridgeToken.USDC]: '0xAc290Ad4e0c891FDc295ca4F0a6214cf6dC6acDC', - [stargateV2BridgeToken.USDT]: '0xa81274AFac523D639DbcA2C32c1470f1600cCEBe', + [stargateV2BridgeToken.USDT]: '0xB715B85682B731dB9D5063187C450095c91C57FC', [stargateV2BridgeToken.METH]: '0xF7628d84a2BbD9bb9c8E686AC95BB5d55169F3F1' }, [BLOCKCHAIN_NAME.BASE]: { diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts index a09f1ba635..b36a0b8b8a 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts @@ -1,5 +1,11 @@ +import BigNumber from 'bignumber.js'; import { ethers } from 'ethers'; -import { NotSupportedBlockchain, NotSupportedTokensError, RubicSdkError } from 'src/common/errors'; +import { + MaxAmountError, + NotSupportedBlockchain, + NotSupportedTokensError, + RubicSdkError +} from 'src/common/errors'; import { PriceToken, PriceTokenAmount } from 'src/common/tokens'; import { parseError } from 'src/common/utils/errors'; import { @@ -27,7 +33,7 @@ import { StargateV2SupportedBlockchains, stargateV2SupportedBlockchains } from './constants/stargate-v2-cross-chain-supported-blockchains'; -import { stargateV2PoolAbi } from './constants/stargate-v2-pool-abi'; +import { stargateV2PoolAbi, stargateV2PoolBalanceAbi } from './constants/stargate-v2-pool-abi'; import { stargateV2PoolId } from './constants/stargate-v2-pool-id'; import { StargateV2QuoteOFTResponse, @@ -54,7 +60,7 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { } try { const toBlockchain = toToken.blockchain as StargateV2SupportedBlockchains; - const useProxy = false; + const useProxy = options?.useProxy?.[this.type] ?? true; const fromSymbol = StargateV2CrossChainProvider.getSymbol( from.symbol, @@ -77,12 +83,27 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { from, useProxy ); - const fromAddress = options?.fromAddress || FAKE_WALLET_ADDRESS; + const fromAddress = this.getWalletAddress(from.blockchain) || FAKE_WALLET_ADDRESS; const fromWithoutFee = getFromWithoutFee( from, feeInfo.rubicProxy?.platformFee?.percent ); + + const maxAmountError = await this.checkMaxAmount( + from.blockchain, + fromSymbol, + fromWithoutFee.weiAmount + ); + + if (maxAmountError) { + return { + trade: null, + error: maxAmountError, + tradeType: this.type + }; + } + const amountLD = fromWithoutFee.stringWeiAmount; const sendParams: StargateV2QuoteParamsStruct = { dstEid: dstChainId, @@ -104,7 +125,7 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { const to = new PriceTokenAmount({ ...toToken.asStruct, - tokenAmount: Web3Pure.fromWei(amountReceived, toToken.decimals) + tokenAmount: Web3Pure.fromWei(amountReceived, fromWithoutFee.decimals) }); const routePath = await this.getRoutePath(from, to); @@ -156,9 +177,31 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { if (blockchain === BLOCKCHAIN_NAME.SCROLL && symbol.toLowerCase() === 'usdc') { return 'USDC.e'; } + if (blockchain === BLOCKCHAIN_NAME.ETHEREUM && symbol.toLowerCase() === 'metis') { + return 'METIS'; + } return symbol; } + private async checkMaxAmount( + fromBlockchain: EvmBlockchainName, + tokenSymbol: StargateV2BridgeToken, + amountToSend: BigNumber + ): Promise { + const contractAddress = stargateV2ContractAddress[ + fromBlockchain as StargateV2SupportedBlockchains + ][tokenSymbol] as string; + const maxAmount = await Injector.web3PublicService + .getWeb3Public(fromBlockchain) + .callContractMethod(contractAddress, stargateV2PoolBalanceAbi, 'poolBalance'); + const maxAmounSend = new BigNumber(maxAmount); + + if (amountToSend.gt(maxAmounSend)) { + return new MaxAmountError(maxAmounSend, tokenSymbol as string); + } + return null; + } + protected async getFeeInfo( fromBlockchain: Partial, providerAddress: string, @@ -192,14 +235,11 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { const dstSupportedPools = stargateV2BlockchainSupportedPools[to.blockchain as StargateV2SupportedBlockchains]; - if ( + return ( srcSupportedPools.includes(srcTokenPool) && dstSupportedPools.includes(dstTokenPool) && srcTokenPool === dstTokenPool - ) { - return true; - } - return false; + ); } private async getReceiveAmount( diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts index 183b418fe3..e8bf8006da 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts @@ -1,9 +1,5 @@ import BigNumber from 'bignumber.js'; -import { - FailedToCheckForTransactionReceiptError, - MaxAmountError, - RubicSdkError -} from 'src/common/errors'; +import { FailedToCheckForTransactionReceiptError, RubicSdkError } from 'src/common/errors'; import { PriceTokenAmount } from 'src/common/tokens'; import { BlockchainName, EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; import { EvmWeb3Private } from 'src/core/blockchain/web3-private-service/web3-private/evm-web3-private/evm-web3-private'; @@ -32,11 +28,7 @@ import { StargateCrossChainProvider } from '../stargate-provider/stargate-cross- import { StargateV2BridgeToken } from './constants/stargate-v2-bridge-token'; import { stargateV2ContractAddress } from './constants/stargate-v2-contract-address'; import { StargateV2SupportedBlockchains } from './constants/stargate-v2-cross-chain-supported-blockchains'; -import { - stargateV2PoolBalanceAbi, - stargateV2SendQuoteAbi, - stargateV2SendTokenAbi -} from './constants/stargate-v2-pool-abi'; +import { stargateV2SendQuoteAbi, stargateV2SendTokenAbi } from './constants/stargate-v2-pool-abi'; import { StargateV2MessagingFee, StargateV2QuoteParamsStruct @@ -166,18 +158,17 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { fromAddress: this.walletAddress } ); - // const extraNativeFee = this.from.isNative - // ? new BigNumber(providerValue).minus(this.from.stringWeiAmount).toFixed() - // : new BigNumber(providerValue).toFixed(); - // const providerData = - // await ProxyCrossChainEvmTrade.getGenericProviderData( - // to, - // data, - // this.fromBlockchain as EvmBlockchainName, - // to, - // extraNativeFee - // ) - const methodArguments = [bridgeData, [to, to, providerValue, data]]; + const extraNativeFee = this.from.isNative + ? new BigNumber(providerValue).minus(this.from.stringWeiAmount).toFixed() + : new BigNumber(providerValue).toFixed(); + const providerData = await ProxyCrossChainEvmTrade.getGenericProviderData( + to, + data, + this.fromBlockchain as EvmBlockchainName, + to, + extraNativeFee + ); + const methodArguments = [bridgeData, providerData]; const value = this.getSwapValue(providerValue); const transactionConfiguration = EvmWeb3Pure.encodeMethodCall( @@ -212,7 +203,6 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { this.from.blockchain ) as StargateV2BridgeToken; const refundAddress = receiverAddress || this.walletAddress; - await this.checkMaxAmount(this.from.blockchain, fromTokenSymbol); const messagingFee = await this.getNativeFee( this.stargateV2SendParams, @@ -289,24 +279,6 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { }; } - private async checkMaxAmount( - fromBlockchain: EvmBlockchainName, - tokenSymbol: StargateV2BridgeToken - ): Promise { - const contractAddress = stargateV2ContractAddress[ - fromBlockchain as StargateV2SupportedBlockchains - ][tokenSymbol] as string; - const sendAmount = new BigNumber(this.stargateV2SendParams.amountLD); - const maxAmount = await Injector.web3PublicService - .getWeb3Public(fromBlockchain) - .callContractMethod(contractAddress, stargateV2PoolBalanceAbi, 'poolBalance'); - const maxAmounSend = new BigNumber(maxAmount); - - if (sendAmount.gt(maxAmounSend)) { - throw new MaxAmountError(maxAmounSend, tokenSymbol as string); - } - } - private async getNativeFee( sendParam: StargateV2QuoteParamsStruct, fromBlockchain: EvmBlockchainName, diff --git a/src/features/cross-chain/status-manager/cross-chain-status-manager.ts b/src/features/cross-chain/status-manager/cross-chain-status-manager.ts index 23fa660223..baea555e52 100644 --- a/src/features/cross-chain/status-manager/cross-chain-status-manager.ts +++ b/src/features/cross-chain/status-manager/cross-chain-status-manager.ts @@ -179,7 +179,7 @@ export class CrossChainStatusManager { const client = lzPackage.createClient('mainnet'); const scanResponse = await client.getMessagesBySrcTxHash(data.srcTxHash); const targetTrade = scanResponse.messages.find( - item => item.srcTxHash.toLocaleLowerCase() === data.srcTxHash.toLocaleLowerCase() + item => item.srcTxHash?.toLocaleLowerCase() === data.srcTxHash.toLocaleLowerCase() ); const txStatusData: TxStatusData = { status: TX_STATUS.PENDING, diff --git a/yarn.lock b/yarn.lock index 2f1bbfa117..1cd06d8de8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1671,12 +1671,10 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" -"@layerzerolabs/scan-client@^0.0.0-beta.6": - version "0.0.0-beta.6" - resolved "https://registry.yarnpkg.com/@layerzerolabs/scan-client/-/scan-client-0.0.0-beta.6.tgz#079275514e2a386677fc8129ced52a3c3f0a1b9a" - integrity sha512-TjhEfMcmN5Q8Gtog45lj6in+y8OzGPoLzUzSF45cJO703Lrlwf5tAA85TQnnRWPGBiChw70KG2S6nzgmMRQWJg== - dependencies: - axios "^0.27.2" +"@layerzerolabs/scan-client@0.0.8": + version "0.0.8" + resolved "https://registry.yarnpkg.com/@layerzerolabs/scan-client/-/scan-client-0.0.8.tgz#38316cde50c06556bb81b74f18d10a36b637eefb" + integrity sha512-V9vvt9GW0+AHoWXfOSNmZ9WUa28fVBmC93J/f9RLeDMEy5VR8srW2Du5pf1mMAg6ncEL0kQ1xkVCu+X6ARFBtQ== "@metamask/eth-sig-util@^4.0.1": version "4.0.1" From 389e578286271af7a34d432ac3676aeb83ea47ab Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 5 Jul 2024 09:34:08 +0300 Subject: [PATCH 05/22] fix price impact --- .../stargate-v2-cross-chain-provider.ts | 1 - .../stargate-v2-cross-chain-trade.ts | 12 +++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts index b36a0b8b8a..1450df94db 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts @@ -150,7 +150,6 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { feeInfo, slippageTolerance: options.slippageTolerance, gasData, - priceImpact: from.calculatePriceImpactPercent(to), sendParams }, options.providerAddress, diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts index e8bf8006da..ca8be35920 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts @@ -55,7 +55,6 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { from, to: toToken, slippageTolerance, - priceImpact: null, gasData: null, feeInfo, sendParams @@ -84,11 +83,13 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { public readonly gasData: GasData; + public readonly toTokenAmountMin: BigNumber; + public readonly isAggregator = false; public readonly slippageTolerance: number; - public readonly priceImpact = null; + public readonly priceImpact: number | null; public readonly onChainSubtype: OnChainSubtype = { from: undefined, to: undefined }; @@ -110,14 +111,11 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { private readonly stargateV2SendParams: StargateV2QuoteParamsStruct; - public readonly toTokenAmountMin = new BigNumber(0); - constructor( crossChainTrade: { from: PriceTokenAmount; to: PriceTokenAmount; slippageTolerance: number; - priceImpact: number | null; gasData: GasData | null; feeInfo: FeeInfo; sendParams: StargateV2QuoteParamsStruct; @@ -132,6 +130,10 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { this.gasData = crossChainTrade.gasData; this.slippageTolerance = crossChainTrade.slippageTolerance; this.stargateV2SendParams = crossChainTrade.sendParams; + this.priceImpact = this.from.calculatePriceImpactPercent(this.to); + this.toTokenAmountMin = this.to.tokenAmount.multipliedBy( + 1 - crossChainTrade.slippageTolerance + ); } protected async getContractParams(options: GetContractParamsOptions): Promise { From d96b62ef785a7ec297ceb31bbb888c3f0b0e1415 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 9 Jul 2024 11:07:27 +0300 Subject: [PATCH 06/22] change name --- .../calculation-manager/models/cross-chain-trade-type.ts | 1 - .../stargate-v2-provider/stargate-v2-cross-chain-provider.ts | 4 ++-- .../stargate-v2-provider/stargate-v2-cross-chain-trade.ts | 4 ++-- .../cross-chain/status-manager/cross-chain-status-manager.ts | 3 +-- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/features/cross-chain/calculation-manager/models/cross-chain-trade-type.ts b/src/features/cross-chain/calculation-manager/models/cross-chain-trade-type.ts index 2c70600d04..51ef4b8d37 100644 --- a/src/features/cross-chain/calculation-manager/models/cross-chain-trade-type.ts +++ b/src/features/cross-chain/calculation-manager/models/cross-chain-trade-type.ts @@ -8,7 +8,6 @@ export const CROSS_CHAIN_TRADE_TYPE = { CELER_BRIDGE: 'celer_bridge', CHANGENOW: 'changenow', STARGATE: 'stargate', - STARGATE_V2: 'stargate_v2', ARBITRUM: 'arbitrum', SQUIDROUTER: 'squidrouter', SCROLL_BRIDGE: 'scroll_bridge', diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts index 1450df94db..2b717a19f8 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts @@ -42,7 +42,7 @@ import { import { StargateV2CrossChainTrade } from './stargate-v2-cross-chain-trade'; export class StargateV2CrossChainProvider extends CrossChainProvider { - public readonly type = CROSS_CHAIN_TRADE_TYPE.STARGATE_V2; + public readonly type = CROSS_CHAIN_TRADE_TYPE.STARGATE; public isSupportedBlockchain(fromBlockchain: BlockchainName): boolean { return stargateV2SupportedBlockchains.some( @@ -274,7 +274,7 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { return [ { type: 'cross-chain', - provider: CROSS_CHAIN_TRADE_TYPE.STARGATE_V2, + provider: CROSS_CHAIN_TRADE_TYPE.STARGATE, path: [from, to] } ]; diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts index ca8be35920..beef811815 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts @@ -79,7 +79,7 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { public readonly feeInfo: FeeInfo; - public readonly type = CROSS_CHAIN_TRADE_TYPE.STARGATE_V2; + public readonly type = CROSS_CHAIN_TRADE_TYPE.STARGATE; public readonly gasData: GasData; @@ -93,7 +93,7 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { public readonly onChainSubtype: OnChainSubtype = { from: undefined, to: undefined }; - public readonly bridgeType = BRIDGE_TYPE.STARGATE_V2; + public readonly bridgeType = BRIDGE_TYPE.STARGATE; public get fromBlockchain(): StargateV2SupportedBlockchains { return this.from.blockchain as StargateV2SupportedBlockchains; diff --git a/src/features/cross-chain/status-manager/cross-chain-status-manager.ts b/src/features/cross-chain/status-manager/cross-chain-status-manager.ts index baea555e52..fcfa171cec 100644 --- a/src/features/cross-chain/status-manager/cross-chain-status-manager.ts +++ b/src/features/cross-chain/status-manager/cross-chain-status-manager.ts @@ -84,7 +84,6 @@ export class CrossChainStatusManager { [CROSS_CHAIN_TRADE_TYPE.XY]: this.getXyDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.CELER_BRIDGE]: this.getCelerBridgeDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.CHANGENOW]: this.getChangenowDstSwapStatus, - [CROSS_CHAIN_TRADE_TYPE.STARGATE]: this.getLayerZeroDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.ARBITRUM]: this.getArbitrumBridgeDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.SQUIDROUTER]: this.getSquidrouterDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.SCROLL_BRIDGE]: this.getScrollBridgeDstSwapStatus, @@ -96,7 +95,7 @@ export class CrossChainStatusManager { [CROSS_CHAIN_TRADE_TYPE.ARCHON_BRIDGE]: this.getLayerZeroDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.MESON]: this.getMesonDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.OWL_TO_BRIDGE]: this.getOwlToDstSwapStatus, - [CROSS_CHAIN_TRADE_TYPE.STARGATE_V2]: this.getLayerZeroDstSwapStatus + [CROSS_CHAIN_TRADE_TYPE.STARGATE]: this.getLayerZeroDstSwapStatus }; /** From e1180872ae8c2349e1d6f084526a8b21b81f834d Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 9 Jul 2024 12:54:33 +0300 Subject: [PATCH 07/22] add provider fee --- package.json | 2 +- .../stargate-v2-cross-chain-provider.ts | 62 ++++++++++++++- .../stargate-v2-cross-chain-trade.ts | 78 +++++++++---------- 3 files changed, 99 insertions(+), 43 deletions(-) diff --git a/package.json b/package.json index 3eb775a0d4..7137e93867 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.30.0-alpha-stargate-v2.2", + "version": "5.30.0-alpha-stargate-v2.5", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts index 2b717a19f8..bb3f5a78f1 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts @@ -7,6 +7,7 @@ import { RubicSdkError } from 'src/common/errors'; import { PriceToken, PriceTokenAmount } from 'src/common/tokens'; +import { nativeTokensList } from 'src/common/tokens/constants/native-tokens'; import { parseError } from 'src/common/utils/errors'; import { BLOCKCHAIN_NAME, @@ -33,9 +34,14 @@ import { StargateV2SupportedBlockchains, stargateV2SupportedBlockchains } from './constants/stargate-v2-cross-chain-supported-blockchains'; -import { stargateV2PoolAbi, stargateV2PoolBalanceAbi } from './constants/stargate-v2-pool-abi'; +import { + stargateV2PoolAbi, + stargateV2PoolBalanceAbi, + stargateV2SendQuoteAbi +} from './constants/stargate-v2-pool-abi'; import { stargateV2PoolId } from './constants/stargate-v2-pool-id'; import { + StargateV2MessagingFee, StargateV2QuoteOFTResponse, StargateV2QuoteParamsStruct } from './modal/stargate-v2-quote-params-struct'; @@ -122,6 +128,13 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { ); const amountReceived = amountReceivedLD[1] as string; sendParams.minAmountLD = amountReceived; + const messagingFee = await this.getNativeFee(sendParams, from.blockchain, fromSymbol); + const nativeToken = nativeTokensList[from.blockchain]; + + const cryptoFeeToken = await PriceTokenAmount.createFromToken({ + ...nativeToken, + weiAmount: new BigNumber(messagingFee.nativeFee) + }); const to = new PriceTokenAmount({ ...toToken.asStruct, @@ -139,6 +152,7 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { options.providerAddress, routePath, sendParams, + messagingFee, options.receiverAddress ) : null; @@ -147,10 +161,22 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { { from, to, - feeInfo, + feeInfo: { + ...feeInfo, + provider: { + cryptoFee: { + amount: Web3Pure.fromWei( + messagingFee.nativeFee, + nativeToken.decimals + ), + token: cryptoFeeToken + } + } + }, slippageTolerance: options.slippageTolerance, gasData, - sendParams + sendParams, + messagingFee }, options.providerAddress, routePath @@ -279,4 +305,34 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { } ]; } + + private async getNativeFee( + sendParam: StargateV2QuoteParamsStruct, + fromBlockchain: EvmBlockchainName, + tokenSymbol: StargateV2BridgeToken + ): Promise { + const contractAddress = + stargateV2ContractAddress?.[fromBlockchain as StargateV2SupportedBlockchains]?.[ + tokenSymbol + ]; + if (!contractAddress) { + throw new RubicSdkError(); + } + try { + const { 0: nativeFee, 1: lzTokenFee } = await Injector.web3PublicService + .getWeb3Public(fromBlockchain) + .callContractMethod<{ 0: string; 1: string }>( + contractAddress, + stargateV2SendQuoteAbi, + 'quoteSend', + [sendParam, false] + ); + return { + nativeFee, + lzTokenFee + }; + } catch (err) { + throw new RubicSdkError(err?.message); + } + } } diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts index beef811815..de36cbc052 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts @@ -28,7 +28,7 @@ import { StargateCrossChainProvider } from '../stargate-provider/stargate-cross- import { StargateV2BridgeToken } from './constants/stargate-v2-bridge-token'; import { stargateV2ContractAddress } from './constants/stargate-v2-contract-address'; import { StargateV2SupportedBlockchains } from './constants/stargate-v2-cross-chain-supported-blockchains'; -import { stargateV2SendQuoteAbi, stargateV2SendTokenAbi } from './constants/stargate-v2-pool-abi'; +import { stargateV2SendTokenAbi } from './constants/stargate-v2-pool-abi'; import { StargateV2MessagingFee, StargateV2QuoteParamsStruct @@ -47,6 +47,7 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { providerAddress: string, routePath: RubicStep[], sendParams: StargateV2QuoteParamsStruct, + messagingFee: StargateV2MessagingFee, receiverAddress?: string ): Promise { try { @@ -57,7 +58,8 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { slippageTolerance, gasData: null, feeInfo, - sendParams + sendParams, + messagingFee }, providerAddress || EvmWeb3Pure.EMPTY_ADDRESS, routePath @@ -95,6 +97,8 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { public readonly bridgeType = BRIDGE_TYPE.STARGATE; + public readonly messagingFee: StargateV2MessagingFee; + public get fromBlockchain(): StargateV2SupportedBlockchains { return this.from.blockchain as StargateV2SupportedBlockchains; } @@ -119,6 +123,7 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { gasData: GasData | null; feeInfo: FeeInfo; sendParams: StargateV2QuoteParamsStruct; + messagingFee: StargateV2MessagingFee; }, providerAddress: string, routePath: RubicStep[] @@ -130,6 +135,7 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { this.gasData = crossChainTrade.gasData; this.slippageTolerance = crossChainTrade.slippageTolerance; this.stargateV2SendParams = crossChainTrade.sendParams; + this.messagingFee = crossChainTrade.messagingFee; this.priceImpact = this.from.calculatePriceImpactPercent(this.to); this.toTokenAmountMin = this.to.tokenAmount.multipliedBy( 1 - crossChainTrade.slippageTolerance @@ -206,12 +212,6 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { ) as StargateV2BridgeToken; const refundAddress = receiverAddress || this.walletAddress; - const messagingFee = await this.getNativeFee( - this.stargateV2SendParams, - this.from.blockchain, - fromTokenSymbol - ); - const contractAddress = stargateV2ContractAddress?.[fromBlockchain]?.[fromTokenSymbol]; if (!contractAddress) { throw new RubicSdkError(); @@ -220,8 +220,8 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { contractAddress, stargateV2SendTokenAbi, 'sendToken', - [this.stargateV2SendParams, messagingFee, refundAddress], - messagingFee.nativeFee + [this.stargateV2SendParams, this.messagingFee, refundAddress], + this.messagingFee.nativeFee ); return { config: calldata, @@ -281,33 +281,33 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { }; } - private async getNativeFee( - sendParam: StargateV2QuoteParamsStruct, - fromBlockchain: EvmBlockchainName, - tokenSymbol: StargateV2BridgeToken - ): Promise { - const contractAddress = - stargateV2ContractAddress?.[fromBlockchain as StargateV2SupportedBlockchains]?.[ - tokenSymbol - ]; - if (!contractAddress) { - throw new RubicSdkError(); - } - try { - const { 0: nativeFee, 1: lzTokenFee } = await Injector.web3PublicService - .getWeb3Public(fromBlockchain) - .callContractMethod<{ 0: string; 1: string }>( - contractAddress, - stargateV2SendQuoteAbi, - 'quoteSend', - [sendParam, false] - ); - return { - nativeFee, - lzTokenFee - }; - } catch (err) { - throw new RubicSdkError(err?.message); - } - } + // private async getNativeFee( + // sendParam: StargateV2QuoteParamsStruct, + // fromBlockchain: EvmBlockchainName, + // tokenSymbol: StargateV2BridgeToken + // ): Promise { + // const contractAddress = + // stargateV2ContractAddress?.[fromBlockchain as StargateV2SupportedBlockchains]?.[ + // tokenSymbol + // ]; + // if (!contractAddress) { + // throw new RubicSdkError(); + // } + // try { + // const { 0: nativeFee, 1: lzTokenFee } = await Injector.web3PublicService + // .getWeb3Public(fromBlockchain) + // .callContractMethod<{ 0: string; 1: string }>( + // contractAddress, + // stargateV2SendQuoteAbi, + // 'quoteSend', + // [sendParam, false] + // ); + // return { + // nativeFee, + // lzTokenFee + // }; + // } catch (err) { + // throw new RubicSdkError(err?.message); + // } + // } } From 298afd00fe15a1a711e0f76b6b59c841398f28f8 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 9 Jul 2024 17:13:49 +0300 Subject: [PATCH 08/22] fix native fee amount --- .../stargate-v2-provider/stargate-v2-cross-chain-trade.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts index de36cbc052..37f3c63c3a 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts @@ -216,12 +216,17 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { if (!contractAddress) { throw new RubicSdkError(); } + const nativeFee = new BigNumber(this.messagingFee.nativeFee); + + const value = this.from.isNative ? + new BigNumber(this.from.stringWeiAmount).plus(nativeFee).toFixed() + : this.messagingFee.nativeFee const calldata = await EvmWeb3Pure.encodeMethodCall( contractAddress, stargateV2SendTokenAbi, 'sendToken', [this.stargateV2SendParams, this.messagingFee, refundAddress], - this.messagingFee.nativeFee + value ); return { config: calldata, From a804d1e94b298c3c3abe51b1c4a4ff993259b54d Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 10 Jul 2024 12:16:45 +0300 Subject: [PATCH 09/22] fix issues --- package.json | 2 +- .../modal/stargate-v2-quote-params-struct.ts | 2 +- .../stargate-v2-provider/stargate-v2-cross-chain-provider.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 7137e93867..8d63ed5043 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.30.0-alpha-stargate-v2.5", + "version": "5.30.0-alpha-stargate-v2.7", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/modal/stargate-v2-quote-params-struct.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/modal/stargate-v2-quote-params-struct.ts index fbe368bdd6..6c00ee0117 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/modal/stargate-v2-quote-params-struct.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/modal/stargate-v2-quote-params-struct.ts @@ -5,7 +5,7 @@ export interface StargateV2QuoteParamsStruct { minAmountLD: string; extraOptions: string; composeMsg: string; - oftCmd: 1 | 0; + oftCmd: string; } export interface StargateV2QuoteOFTResponse { diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts index bb3f5a78f1..430b8cf7f6 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts @@ -118,7 +118,7 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { minAmountLD: amountLD, extraOptions: '0x', composeMsg: '0x', - oftCmd: 0 + oftCmd: '0x' }; const { amountReceivedLD } = await this.getReceiveAmount( From be65f2c796ffb0d43c354f66607deb0ef7035dc8 Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 12 Jul 2024 10:17:51 +0300 Subject: [PATCH 10/22] resolve conflicts --- package.json | 2 +- .../cross-chain/status-manager/cross-chain-status-manager.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 8d63ed5043..5f56d08c72 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.30.0-alpha-stargate-v2.7", + "version": "5.30.0-alpha-stargate-v2.9", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/features/cross-chain/status-manager/cross-chain-status-manager.ts b/src/features/cross-chain/status-manager/cross-chain-status-manager.ts index 90045be681..60280b3d24 100644 --- a/src/features/cross-chain/status-manager/cross-chain-status-manager.ts +++ b/src/features/cross-chain/status-manager/cross-chain-status-manager.ts @@ -96,7 +96,7 @@ export class CrossChainStatusManager { [CROSS_CHAIN_TRADE_TYPE.ARCHON_BRIDGE]: this.getLayerZeroDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.MESON]: this.getMesonDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.OWL_TO_BRIDGE]: this.getOwlToDstSwapStatus, - [CROSS_CHAIN_TRADE_TYPE.STARGATE]: this.getLayerZeroDstSwapStatus + [CROSS_CHAIN_TRADE_TYPE.STARGATE]: this.getLayerZeroDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.EDDY_BRIDGE]: this.getEddyBridgeDstSwapStatus }; @@ -181,7 +181,6 @@ export class CrossChainStatusManager { const scanResponse = await client.getMessagesBySrcTxHash(data.srcTxHash); const targetTrade = scanResponse.messages.find( item => item.srcTxHash?.toLocaleLowerCase() === data.srcTxHash.toLocaleLowerCase() - item => item.srcTxHash?.toLocaleLowerCase() === data.srcTxHash.toLocaleLowerCase() ); const txStatusData: TxStatusData = { status: TX_STATUS.PENDING, From 6579c8a09572ca817bc69ef7e0ac5afef38ea8d4 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 15 Jul 2024 15:23:07 +0300 Subject: [PATCH 11/22] create getTokenPoolByAddress method --- package.json | 2 +- .../models/cross-chain-trade-type.ts | 1 + .../stargate-v2-blockchain-supported-pools.ts | 38 ++++----- .../constants/stargate-v2-chain-id.ts | 10 +-- .../constants/stargate-v2-contract-address.ts | 42 +++++----- ...te-v2-cross-chain-supported-blockchains.ts | 10 +-- .../constants/stargate-v2-pool-id.ts | 13 ++++ .../constants/stargate-v2-token-address.ts | 61 +++++++++++++++ .../stargate-v2-cross-chain-provider.ts | 78 ++++++++++++------- .../stargate-v2-cross-chain-trade.ts | 20 +++-- .../cross-chain-status-manager.ts | 5 +- 11 files changed, 189 insertions(+), 91 deletions(-) create mode 100644 src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-token-address.ts diff --git a/package.json b/package.json index 5f56d08c72..3c46c44478 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.30.0-alpha-stargate-v2.9", + "version": "5.30.0-alpha-stargate-v2.10", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/features/cross-chain/calculation-manager/models/cross-chain-trade-type.ts b/src/features/cross-chain/calculation-manager/models/cross-chain-trade-type.ts index 6a3ad75f3a..278d5fb742 100644 --- a/src/features/cross-chain/calculation-manager/models/cross-chain-trade-type.ts +++ b/src/features/cross-chain/calculation-manager/models/cross-chain-trade-type.ts @@ -8,6 +8,7 @@ export const CROSS_CHAIN_TRADE_TYPE = { CELER_BRIDGE: 'celer_bridge', CHANGENOW: 'changenow', STARGATE: 'stargate', + STARGATE_V2: 'stargate_v2', ARBITRUM: 'arbitrum', SQUIDROUTER: 'squidrouter', SCROLL_BRIDGE: 'scroll_bridge', diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-blockchain-supported-pools.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-blockchain-supported-pools.ts index 3f214831d9..c810e93b6e 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-blockchain-supported-pools.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-blockchain-supported-pools.ts @@ -10,7 +10,7 @@ export const stargateV2BlockchainSupportedPools: Record [BLOCKCHAIN_NAME.BASE]: 30184, [BLOCKCHAIN_NAME.KAVA]: 30177, [BLOCKCHAIN_NAME.SCROLL]: 30214, - [BLOCKCHAIN_NAME.AURORA]: 30211, - [BLOCKCHAIN_NAME.KLAYTN]: 30150, - [BLOCKCHAIN_NAME.IOTA]: 30284, - [BLOCKCHAIN_NAME.TAIKO]: 30290, - [BLOCKCHAIN_NAME.SEI]: 30280 + [BLOCKCHAIN_NAME.AURORA]: 30211 + // [BLOCKCHAIN_NAME.KLAYTN]: 30150, + // [BLOCKCHAIN_NAME.IOTA]: 30284, + // [BLOCKCHAIN_NAME.TAIKO]: 30290, + // [BLOCKCHAIN_NAME.SEI]: 30280 }; diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-contract-address.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-contract-address.ts index 0f6edf28b4..f3801a3768 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-contract-address.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-contract-address.ts @@ -21,7 +21,7 @@ export const stargateV2ContractAddress: StargateV2ContractAddress = { }, [BLOCKCHAIN_NAME.AVALANCHE]: { [stargateV2BridgeToken.USDC]: '0x5634c4a5FEd09819E3c46D86A965Dd9447d86e47', - [stargateV2BridgeToken.USDT]: '0x22BdF9633F3e679785638Db690b85dC0Dc8B35B8' + [stargateV2BridgeToken.USDT]: '0x12dC9256Acc9895B076f6638D628382881e62CeE' }, [BLOCKCHAIN_NAME.POLYGON]: { [stargateV2BridgeToken.USDC]: '0x9Aa02D4Fae7F58b8E8f34c66E756cC734DAc7fe4', @@ -39,8 +39,8 @@ export const stargateV2ContractAddress: StargateV2ContractAddress = { }, [BLOCKCHAIN_NAME.METIS]: { [stargateV2BridgeToken.METIS]: '0xD9050e7043102a0391F81462a3916326F86331F0', - [stargateV2BridgeToken.ETH]: '0x36ed193dc7160D3858EC250e69D12B03Ca087D08', - [stargateV2BridgeToken.USDT]: '0x4dCBFC0249e8d5032F89D6461218a9D2eFff5125' + [stargateV2BridgeToken.WETH]: '0x36ed193dc7160D3858EC250e69D12B03Ca087D08', + [stargateV2BridgeToken.mUSD]: '0x4dCBFC0249e8d5032F89D6461218a9D2eFff5125' }, [BLOCKCHAIN_NAME.LINEA]: { [stargateV2BridgeToken.ETH]: '0x81F6138153d473E8c5EcebD3DC8Cd4903506B075' @@ -60,26 +60,26 @@ export const stargateV2ContractAddress: StargateV2ContractAddress = { }, [BLOCKCHAIN_NAME.SCROLL]: { [stargateV2BridgeToken.ETH]: '0xC2b638Cb5042c1B3c5d5C969361fB50569840583', - [stargateV2BridgeToken.USDC]: '0x3Fc69CC4A842838bCDC9499178740226062b14E4' + [stargateV2BridgeToken.USDCe]: '0x3Fc69CC4A842838bCDC9499178740226062b14E4' }, [BLOCKCHAIN_NAME.AURORA]: { [stargateV2BridgeToken.USDC]: '0x81F6138153d473E8c5EcebD3DC8Cd4903506B075' - }, - [BLOCKCHAIN_NAME.KLAYTN]: { - [stargateV2BridgeToken.ETH]: '0xBB4957E44401a31ED81Cab33539d9e8993FA13Ce', - [stargateV2BridgeToken.USDC]: '0x01A7c805cc47AbDB254CD8AaD29dE5e447F59224', - [stargateV2BridgeToken.USDT]: '0x8619bA1B324e099CB2227060c4BC5bDEe14456c6' - }, - [BLOCKCHAIN_NAME.IOTA]: { - [stargateV2BridgeToken.ETH]: '0x9c2dc7377717603eB92b2655c5f2E7997a4945BD', - [stargateV2BridgeToken.USDC]: '0x8e8539e4CcD69123c623a106773F2b0cbbc58746', - [stargateV2BridgeToken.USDT]: '0x77C71633C34C3784ede189d74223122422492a0f' - }, - [BLOCKCHAIN_NAME.TAIKO]: { - [stargateV2BridgeToken.USDC]: '0x77C71633C34C3784ede189d74223122422492a0f', - [stargateV2BridgeToken.USDT]: '0x1C10CC06DC6D35970d1D53B2A23c76ef370d4135' - }, - [BLOCKCHAIN_NAME.SEI]: { - [stargateV2BridgeToken.WETH]: '0x5c386D85b1B82FD9Db681b9176C8a4248bb6345B' } + // [BLOCKCHAIN_NAME.KLAYTN]: { + // [stargateV2BridgeToken.ETH]: '0xBB4957E44401a31ED81Cab33539d9e8993FA13Ce', + // [stargateV2BridgeToken.USDC]: '0x01A7c805cc47AbDB254CD8AaD29dE5e447F59224', + // [stargateV2BridgeToken.USDT]: '0x8619bA1B324e099CB2227060c4BC5bDEe14456c6' + // }, + // [BLOCKCHAIN_NAME.IOTA]: { + // [stargateV2BridgeToken.ETH]: '0x9c2dc7377717603eB92b2655c5f2E7997a4945BD', + // [stargateV2BridgeToken.USDC]: '0x8e8539e4CcD69123c623a106773F2b0cbbc58746', + // [stargateV2BridgeToken.USDT]: '0x77C71633C34C3784ede189d74223122422492a0f' + // }, + // [BLOCKCHAIN_NAME.TAIKO]: { + // [stargateV2BridgeToken.USDC]: '0x77C71633C34C3784ede189d74223122422492a0f', + // [stargateV2BridgeToken.USDT]: '0x1C10CC06DC6D35970d1D53B2A23c76ef370d4135' + // }, + // [BLOCKCHAIN_NAME.SEI]: { + // [stargateV2BridgeToken.WETH]: '0x5c386D85b1B82FD9Db681b9176C8a4248bb6345B' + // } }; diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-cross-chain-supported-blockchains.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-cross-chain-supported-blockchains.ts index 28334be04b..05ee121687 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-cross-chain-supported-blockchains.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-cross-chain-supported-blockchains.ts @@ -13,11 +13,11 @@ export const stargateV2SupportedBlockchains = [ BLOCKCHAIN_NAME.BASE, BLOCKCHAIN_NAME.KAVA, BLOCKCHAIN_NAME.SCROLL, - BLOCKCHAIN_NAME.AURORA, - BLOCKCHAIN_NAME.KLAYTN, - BLOCKCHAIN_NAME.IOTA, - BLOCKCHAIN_NAME.TAIKO, - BLOCKCHAIN_NAME.SEI + BLOCKCHAIN_NAME.AURORA + // BLOCKCHAIN_NAME.KLAYTN, + // BLOCKCHAIN_NAME.IOTA, + // BLOCKCHAIN_NAME.TAIKO, + // BLOCKCHAIN_NAME.SEI ]; export type StargateV2SupportedBlockchains = (typeof stargateV2SupportedBlockchains)[number]; diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-id.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-id.ts index 844b9e741c..f8953db439 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-id.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-id.ts @@ -1,4 +1,6 @@ import { StargateV2BridgeToken, stargateV2BridgeToken } from './stargate-v2-bridge-token'; +import { StargateV2SupportedBlockchains } from './stargate-v2-cross-chain-supported-blockchains'; +import { stargateV2TokenAddress } from './stargate-v2-token-address'; const pools = { [stargateV2BridgeToken.USDC]: 1, @@ -13,3 +15,14 @@ const pools = { export const stargateV2PoolId: Record = pools; export type StargateV2PoolId = (typeof pools)[keyof typeof pools]; + +export function getTokenPoolByAddress( + blockchain: StargateV2SupportedBlockchains, + contractAddress: string +): number | null { + const tokenSymbol = stargateV2TokenAddress?.[blockchain]?.[contractAddress]; + if (tokenSymbol) { + return stargateV2PoolId[tokenSymbol]; + } + return null; +} diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-token-address.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-token-address.ts new file mode 100644 index 0000000000..a52b36794e --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-token-address.ts @@ -0,0 +1,61 @@ +import { BLOCKCHAIN_NAME } from 'src/core/blockchain/models/blockchain-name'; + +import { StargateV2BridgeToken, stargateV2BridgeToken } from './stargate-v2-bridge-token'; +import { StargateV2SupportedBlockchains } from './stargate-v2-cross-chain-supported-blockchains'; + +type StargateV2TokenAddress = Record< + StargateV2SupportedBlockchains, + Partial> +>; + +export const stargateV2TokenAddress: StargateV2TokenAddress = { + [BLOCKCHAIN_NAME.ETHEREUM]: { + '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': stargateV2BridgeToken.USDC, + '0xdac17f958d2ee523a2206206994597c13d831ec7': stargateV2BridgeToken.USDT, + '0x9e32b13ce7f2e80a01932b42553652e053d6ed8e': stargateV2BridgeToken.METIS, + '0xd5f7838f5c461feff7fe49ea5ebaf7728bb0adfa': stargateV2BridgeToken.METH + }, + [BLOCKCHAIN_NAME.BINANCE_SMART_CHAIN]: { + '0x55d398326f99059fF775485246999027B3197955': stargateV2BridgeToken.USDT + }, + [BLOCKCHAIN_NAME.AVALANCHE]: { + '0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e': stargateV2BridgeToken.USDC, + '0x9702230a8ea53601f5cd2dc00fdbc13d4df4a8c7': stargateV2BridgeToken.USDT + }, + [BLOCKCHAIN_NAME.POLYGON]: { + '0x3c499c542cef5e3811e1192ce70d8cc03d5c3359': stargateV2BridgeToken.USDC, + '0xc2132d05d31c914a87c6611c10748aeb04b58e8f': stargateV2BridgeToken.USDT + }, + [BLOCKCHAIN_NAME.ARBITRUM]: { + '0xaf88d065e77c8cc2239327c5edb3a432268e5831': stargateV2BridgeToken.USDC, + '0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9': stargateV2BridgeToken.USDT + }, + [BLOCKCHAIN_NAME.OPTIMISM]: { + '0x0b2c639c533813f4aa9d7837caf62653d097ff85': stargateV2BridgeToken.USDC, + '0x94b008aa00579c1307b0ef2c499ad98a8ce58e58': stargateV2BridgeToken.USDT + }, + [BLOCKCHAIN_NAME.METIS]: { + '0xbb06dca3ae6887fabf931640f67cab3e3a16f4dc': stargateV2BridgeToken.mUSD, + '0x420000000000000000000000000000000000000a': stargateV2BridgeToken.WETH, + '0xdeaddeaddeaddeaddeaddeaddeaddeaddead0000': stargateV2BridgeToken.METIS + }, + [BLOCKCHAIN_NAME.LINEA]: {}, + [BLOCKCHAIN_NAME.MANTLE]: { + '0x09bc4e0d864854c6afb6eb9a9cdf58ac190d0df9': stargateV2BridgeToken.USDC, + '0x201eba5cc46d216ce6dc03f6a759e8e766e956ae': stargateV2BridgeToken.USDT, + '0xdeaddeaddeaddeaddeaddeaddeaddeaddead1111': stargateV2BridgeToken.WETH, + '0xcda86a272531e8640cd7f1a92c01839911b90bb0': stargateV2BridgeToken.METH + }, + [BLOCKCHAIN_NAME.BASE]: { + '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913': stargateV2BridgeToken.USDC + }, + [BLOCKCHAIN_NAME.KAVA]: { + '0x919c1c267bc06a7039e03fcc2ef738525769109c': stargateV2BridgeToken.USDC + }, + [BLOCKCHAIN_NAME.SCROLL]: { + '0x06efdbff2a14a7c8e15944d1f4a48f9f95f663a4': stargateV2BridgeToken.USDCe + }, + [BLOCKCHAIN_NAME.AURORA]: { + '0x368ebb46aca6b8d0787c96b2b20bd3cc3f2c45f7': stargateV2BridgeToken.USDC + } +}; diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts index 430b8cf7f6..cc0dcc9f5c 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts @@ -39,7 +39,8 @@ import { stargateV2PoolBalanceAbi, stargateV2SendQuoteAbi } from './constants/stargate-v2-pool-abi'; -import { stargateV2PoolId } from './constants/stargate-v2-pool-id'; +import { getTokenPoolByAddress } from './constants/stargate-v2-pool-id'; +import { stargateV2TokenAddress } from './constants/stargate-v2-token-address'; import { StargateV2MessagingFee, StargateV2QuoteOFTResponse, @@ -48,7 +49,7 @@ import { import { StargateV2CrossChainTrade } from './stargate-v2-cross-chain-trade'; export class StargateV2CrossChainProvider extends CrossChainProvider { - public readonly type = CROSS_CHAIN_TRADE_TYPE.STARGATE; + public readonly type = CROSS_CHAIN_TRADE_TYPE.STARGATE_V2; public isSupportedBlockchain(fromBlockchain: BlockchainName): boolean { return stargateV2SupportedBlockchains.some( @@ -67,13 +68,8 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { try { const toBlockchain = toToken.blockchain as StargateV2SupportedBlockchains; const useProxy = options?.useProxy?.[this.type] ?? true; - - const fromSymbol = StargateV2CrossChainProvider.getSymbol( - from.symbol, - from.blockchain - ) as StargateV2BridgeToken; - const isSupportedPools = this.checkSupportedPools(from, toToken); + if (!isSupportedPools) { return { trade: null, @@ -89,7 +85,10 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { from, useProxy ); - const fromAddress = this.getWalletAddress(from.blockchain) || FAKE_WALLET_ADDRESS; + const receiverAddress = + options?.receiverAddress || + this.getWalletAddress(from.blockchain) || + FAKE_WALLET_ADDRESS; const fromWithoutFee = getFromWithoutFee( from, @@ -98,7 +97,7 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { const maxAmountError = await this.checkMaxAmount( from.blockchain, - fromSymbol, + from.address, fromWithoutFee.weiAmount ); @@ -111,9 +110,10 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { } const amountLD = fromWithoutFee.stringWeiAmount; + const sendParams: StargateV2QuoteParamsStruct = { dstEid: dstChainId, - to: ethers.utils.hexZeroPad(fromAddress, 32), + to: ethers.utils.hexZeroPad(receiverAddress, 32), amountLD: amountLD, minAmountLD: amountLD, extraOptions: '0x', @@ -124,11 +124,11 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { const { amountReceivedLD } = await this.getReceiveAmount( sendParams, from.blockchain, - fromSymbol + from.address ); const amountReceived = amountReceivedLD[1] as string; sendParams.minAmountLD = amountReceived; - const messagingFee = await this.getNativeFee(sendParams, from.blockchain, fromSymbol); + const messagingFee = await this.getNativeFee(sendParams, from.blockchain, from.address); const nativeToken = nativeTokensList[from.blockchain]; const cryptoFeeToken = await PriceTokenAmount.createFromToken({ @@ -205,17 +205,24 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { if (blockchain === BLOCKCHAIN_NAME.ETHEREUM && symbol.toLowerCase() === 'metis') { return 'METIS'; } + if (blockchain === BLOCKCHAIN_NAME.AVALANCHE && symbol.toLowerCase() === 'usdt') { + return 'USDT'; + } return symbol; } private async checkMaxAmount( fromBlockchain: EvmBlockchainName, - tokenSymbol: StargateV2BridgeToken, + tokenAddress: string, amountToSend: BigNumber ): Promise { + const tokenSymbol = stargateV2TokenAddress[ + fromBlockchain as StargateV2SupportedBlockchains + ][tokenAddress] as StargateV2BridgeToken; const contractAddress = stargateV2ContractAddress[ fromBlockchain as StargateV2SupportedBlockchains ][tokenSymbol] as string; + const maxAmount = await Injector.web3PublicService .getWeb3Public(fromBlockchain) .callContractMethod(contractAddress, stargateV2PoolBalanceAbi, 'poolBalance'); @@ -245,16 +252,21 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { from: PriceTokenAmount, to: PriceToken ): boolean { - const fromTokenSymbol = StargateV2CrossChainProvider.getSymbol( - from.symbol, - from.blockchain - ) as StargateV2BridgeToken; - const toTokenSymbol = StargateV2CrossChainProvider.getSymbol( - to.symbol, - to.blockchain - ) as StargateV2BridgeToken; - const srcTokenPool = stargateV2PoolId[fromTokenSymbol]; - const dstTokenPool = stargateV2PoolId[toTokenSymbol]; + // const fromTokenSymbol = StargateV2CrossChainProvider.getSymbol( + // from.symbol, + // from.blockchain + // ) as StargateV2BridgeToken; + // const toTokenSymbol = StargateV2CrossChainProvider.getSymbol( + // to.symbol, + // to.blockchain + // ) as StargateV2BridgeToken; + const fromBlockchain = from.blockchain as StargateV2SupportedBlockchains; + const toBlockchain = to.blockchain as StargateV2SupportedBlockchains; + const srcTokenPool = getTokenPoolByAddress(fromBlockchain, from.address); + const dstTokenPool = getTokenPoolByAddress(toBlockchain, to.address); + if (!srcTokenPool || !dstTokenPool) { + return false; + } const srcSupportedPools = stargateV2BlockchainSupportedPools[from.blockchain as StargateV2SupportedBlockchains]; const dstSupportedPools = @@ -270,11 +282,20 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { private async getReceiveAmount( sendParam: StargateV2QuoteParamsStruct, fromBlockchain: EvmBlockchainName, - tokenSymbol: StargateV2BridgeToken + tokenAddress: string ): Promise { + const tokenSymbol = stargateV2TokenAddress[ + fromBlockchain as StargateV2SupportedBlockchains + ][tokenAddress] as StargateV2BridgeToken; + const contractAddress = stargateV2ContractAddress[ fromBlockchain as StargateV2SupportedBlockchains ][tokenSymbol] as string; + + if (!contractAddress) { + throw new RubicSdkError(); + } + try { const { 2: amountReceivedLD } = await Injector.web3PublicService .getWeb3Public(fromBlockchain) @@ -300,7 +321,7 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { return [ { type: 'cross-chain', - provider: CROSS_CHAIN_TRADE_TYPE.STARGATE, + provider: CROSS_CHAIN_TRADE_TYPE.STARGATE_V2, path: [from, to] } ]; @@ -309,8 +330,11 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { private async getNativeFee( sendParam: StargateV2QuoteParamsStruct, fromBlockchain: EvmBlockchainName, - tokenSymbol: StargateV2BridgeToken + tokenAddress: string ): Promise { + const tokenSymbol = stargateV2TokenAddress[ + fromBlockchain as StargateV2SupportedBlockchains + ][tokenAddress] as StargateV2BridgeToken; const contractAddress = stargateV2ContractAddress?.[fromBlockchain as StargateV2SupportedBlockchains]?.[ tokenSymbol diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts index 37f3c63c3a..45987f6f0e 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts @@ -8,7 +8,6 @@ import { EvmEncodeConfig } from 'src/core/blockchain/web3-pure/typed-web3-pure/e import { Injector } from 'src/core/injector/injector'; import { ContractParams } from 'src/features/common/models/contract-params'; import { SwapTransactionOptions } from 'src/features/common/models/swap-transaction-options'; -import { checkUnsupportedReceiverAddress } from 'src/features/common/utils/check-unsupported-receiver-address'; import { CROSS_CHAIN_TRADE_TYPE } from '../../models/cross-chain-trade-type'; import { getCrossChainGasData } from '../../utils/get-cross-chain-gas-data'; @@ -29,6 +28,7 @@ import { StargateV2BridgeToken } from './constants/stargate-v2-bridge-token'; import { stargateV2ContractAddress } from './constants/stargate-v2-contract-address'; import { StargateV2SupportedBlockchains } from './constants/stargate-v2-cross-chain-supported-blockchains'; import { stargateV2SendTokenAbi } from './constants/stargate-v2-pool-abi'; +import { stargateV2TokenAddress } from './constants/stargate-v2-token-address'; import { StargateV2MessagingFee, StargateV2QuoteParamsStruct @@ -81,7 +81,7 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { public readonly feeInfo: FeeInfo; - public readonly type = CROSS_CHAIN_TRADE_TYPE.STARGATE; + public readonly type = CROSS_CHAIN_TRADE_TYPE.STARGATE_V2; public readonly gasData: GasData; @@ -95,7 +95,7 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { public readonly onChainSubtype: OnChainSubtype = { from: undefined, to: undefined }; - public readonly bridgeType = BRIDGE_TYPE.STARGATE; + public readonly bridgeType = BRIDGE_TYPE.STARGATE_V2; public readonly messagingFee: StargateV2MessagingFee; @@ -104,10 +104,9 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { } protected get fromContractAddress(): string { - const fromTokenSymbol = StargateCrossChainProvider.getSymbol( - this.from.symbol, - this.from.blockchain - ) as StargateV2BridgeToken; + const fromTokenSymbol = stargateV2TokenAddress[ + this.from.blockchain as StargateV2SupportedBlockchains + ][this.from.address] as StargateV2BridgeToken; return this.isProxyTrade ? rubicProxyContractAddress[this.fromBlockchain].gateway : (stargateV2ContractAddress?.[this.fromBlockchain]?.[fromTokenSymbol] as string); @@ -218,9 +217,9 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { } const nativeFee = new BigNumber(this.messagingFee.nativeFee); - const value = this.from.isNative ? - new BigNumber(this.from.stringWeiAmount).plus(nativeFee).toFixed() - : this.messagingFee.nativeFee + const value = this.from.isNative + ? new BigNumber(this.from.stringWeiAmount).plus(nativeFee).toFixed() + : this.messagingFee.nativeFee; const calldata = await EvmWeb3Pure.encodeMethodCall( contractAddress, stargateV2SendTokenAbi, @@ -236,7 +235,6 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { protected async swapDirect(options: SwapTransactionOptions = {}): Promise { this.checkWalletConnected(); - checkUnsupportedReceiverAddress(options?.receiverAddress, this.walletAddress); await this.checkTradeErrors(); await this.checkAllowanceAndApprove(options); const { onConfirm, gasLimit, gasPriceOptions } = options; diff --git a/src/features/cross-chain/status-manager/cross-chain-status-manager.ts b/src/features/cross-chain/status-manager/cross-chain-status-manager.ts index 60280b3d24..26624e8919 100644 --- a/src/features/cross-chain/status-manager/cross-chain-status-manager.ts +++ b/src/features/cross-chain/status-manager/cross-chain-status-manager.ts @@ -96,8 +96,9 @@ export class CrossChainStatusManager { [CROSS_CHAIN_TRADE_TYPE.ARCHON_BRIDGE]: this.getLayerZeroDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.MESON]: this.getMesonDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.OWL_TO_BRIDGE]: this.getOwlToDstSwapStatus, - [CROSS_CHAIN_TRADE_TYPE.STARGATE]: this.getLayerZeroDstSwapStatus, - [CROSS_CHAIN_TRADE_TYPE.EDDY_BRIDGE]: this.getEddyBridgeDstSwapStatus + [CROSS_CHAIN_TRADE_TYPE.STARGATE_V2]: this.getLayerZeroDstSwapStatus, + [CROSS_CHAIN_TRADE_TYPE.EDDY_BRIDGE]: this.getEddyBridgeDstSwapStatus, + [CROSS_CHAIN_TRADE_TYPE.STARGATE]: this.getLayerZeroDstSwapStatus }; /** From 39910203c76157d0322d882ccb3b4a9bca30e3fa Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 15 Jul 2024 16:11:35 +0300 Subject: [PATCH 12/22] add native address for stargateV2TokenAddress config --- package.json | 2 +- .../constants/stargate-v2-token-address.ts | 11 ++++- .../stargate-v2-cross-chain-provider.ts | 49 +++++-------------- .../stargate-v2-cross-chain-trade.ts | 7 ++- 4 files changed, 24 insertions(+), 45 deletions(-) diff --git a/package.json b/package.json index 3c46c44478..754c685d41 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.30.0-alpha-stargate-v2.10", + "version": "5.30.0-alpha-stargate-v2.11", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-token-address.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-token-address.ts index a52b36794e..6224b449f5 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-token-address.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-token-address.ts @@ -10,6 +10,7 @@ type StargateV2TokenAddress = Record< export const stargateV2TokenAddress: StargateV2TokenAddress = { [BLOCKCHAIN_NAME.ETHEREUM]: { + '0x0000000000000000000000000000000000000000': stargateV2BridgeToken.ETH, '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': stargateV2BridgeToken.USDC, '0xdac17f958d2ee523a2206206994597c13d831ec7': stargateV2BridgeToken.USDT, '0x9e32b13ce7f2e80a01932b42553652e053d6ed8e': stargateV2BridgeToken.METIS, @@ -27,10 +28,12 @@ export const stargateV2TokenAddress: StargateV2TokenAddress = { '0xc2132d05d31c914a87c6611c10748aeb04b58e8f': stargateV2BridgeToken.USDT }, [BLOCKCHAIN_NAME.ARBITRUM]: { + '0x0000000000000000000000000000000000000000': stargateV2BridgeToken.ETH, '0xaf88d065e77c8cc2239327c5edb3a432268e5831': stargateV2BridgeToken.USDC, '0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9': stargateV2BridgeToken.USDT }, [BLOCKCHAIN_NAME.OPTIMISM]: { + '0x0000000000000000000000000000000000000000': stargateV2BridgeToken.ETH, '0x0b2c639c533813f4aa9d7837caf62653d097ff85': stargateV2BridgeToken.USDC, '0x94b008aa00579c1307b0ef2c499ad98a8ce58e58': stargateV2BridgeToken.USDT }, @@ -39,7 +42,9 @@ export const stargateV2TokenAddress: StargateV2TokenAddress = { '0x420000000000000000000000000000000000000a': stargateV2BridgeToken.WETH, '0xdeaddeaddeaddeaddeaddeaddeaddeaddead0000': stargateV2BridgeToken.METIS }, - [BLOCKCHAIN_NAME.LINEA]: {}, + [BLOCKCHAIN_NAME.LINEA]: { + '0x0000000000000000000000000000000000000000': stargateV2BridgeToken.ETH + }, [BLOCKCHAIN_NAME.MANTLE]: { '0x09bc4e0d864854c6afb6eb9a9cdf58ac190d0df9': stargateV2BridgeToken.USDC, '0x201eba5cc46d216ce6dc03f6a759e8e766e956ae': stargateV2BridgeToken.USDT, @@ -47,12 +52,14 @@ export const stargateV2TokenAddress: StargateV2TokenAddress = { '0xcda86a272531e8640cd7f1a92c01839911b90bb0': stargateV2BridgeToken.METH }, [BLOCKCHAIN_NAME.BASE]: { + '0x0000000000000000000000000000000000000000': stargateV2BridgeToken.ETH, '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913': stargateV2BridgeToken.USDC }, [BLOCKCHAIN_NAME.KAVA]: { - '0x919c1c267bc06a7039e03fcc2ef738525769109c': stargateV2BridgeToken.USDC + '0x919c1c267bc06a7039e03fcc2ef738525769109c': stargateV2BridgeToken.USDT }, [BLOCKCHAIN_NAME.SCROLL]: { + '0x0000000000000000000000000000000000000000': stargateV2BridgeToken.ETH, '0x06efdbff2a14a7c8e15944d1f4a48f9f95f663a4': stargateV2BridgeToken.USDCe }, [BLOCKCHAIN_NAME.AURORA]: { diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts index cc0dcc9f5c..90f16608b9 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts @@ -145,16 +145,16 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { const gasData = options.gasCalculation === 'enabled' ? await StargateV2CrossChainTrade.getGasData( - from, - to, - feeInfo, - options.slippageTolerance, - options.providerAddress, - routePath, - sendParams, - messagingFee, - options.receiverAddress - ) + from, + to, + feeInfo, + options.slippageTolerance, + options.providerAddress, + routePath, + sendParams, + messagingFee, + options.receiverAddress + ) : null; return { trade: new StargateV2CrossChainTrade( @@ -192,25 +192,6 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { } } - public static getSymbol(symbol: string, blockchain: BlockchainName): string { - if (blockchain === BLOCKCHAIN_NAME.METIS && symbol.toLowerCase() === 'usdt') { - return 'm.USDT'; - } - if (blockchain === BLOCKCHAIN_NAME.METIS && symbol.toLowerCase() === 'eth') { - return 'WETH'; - } - if (blockchain === BLOCKCHAIN_NAME.SCROLL && symbol.toLowerCase() === 'usdc') { - return 'USDC.e'; - } - if (blockchain === BLOCKCHAIN_NAME.ETHEREUM && symbol.toLowerCase() === 'metis') { - return 'METIS'; - } - if (blockchain === BLOCKCHAIN_NAME.AVALANCHE && symbol.toLowerCase() === 'usdt') { - return 'USDT'; - } - return symbol; - } - private async checkMaxAmount( fromBlockchain: EvmBlockchainName, tokenAddress: string, @@ -252,14 +233,6 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { from: PriceTokenAmount, to: PriceToken ): boolean { - // const fromTokenSymbol = StargateV2CrossChainProvider.getSymbol( - // from.symbol, - // from.blockchain - // ) as StargateV2BridgeToken; - // const toTokenSymbol = StargateV2CrossChainProvider.getSymbol( - // to.symbol, - // to.blockchain - // ) as StargateV2BridgeToken; const fromBlockchain = from.blockchain as StargateV2SupportedBlockchains; const toBlockchain = to.blockchain as StargateV2SupportedBlockchains; const srcTokenPool = getTokenPoolByAddress(fromBlockchain, from.address); @@ -337,7 +310,7 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { ][tokenAddress] as StargateV2BridgeToken; const contractAddress = stargateV2ContractAddress?.[fromBlockchain as StargateV2SupportedBlockchains]?.[ - tokenSymbol + tokenSymbol ]; if (!contractAddress) { throw new RubicSdkError(); diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts index 45987f6f0e..3f0843e838 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts @@ -205,10 +205,9 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { receiverAddress?: string | undefined ): Promise<{ config: EvmEncodeConfig; amount: string }> { const fromBlockchain = this.from.blockchain as StargateV2SupportedBlockchains; - const fromTokenSymbol = StargateCrossChainProvider.getSymbol( - this.from.symbol, - this.from.blockchain - ) as StargateV2BridgeToken; + const fromTokenSymbol = stargateV2TokenAddress[ + fromBlockchain + ][this.from.address] as StargateV2BridgeToken; const refundAddress = receiverAddress || this.walletAddress; const contractAddress = stargateV2ContractAddress?.[fromBlockchain]?.[fromTokenSymbol]; From c51a882b023cc3d68f87f236d5bb10d1e59d6a35 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 16 Jul 2024 09:45:47 +0300 Subject: [PATCH 13/22] fix token address for polygon and arb --- package.json | 2 +- .../constants/stargate-v2-blockchain-supported-pools.ts | 6 +++--- .../constants/stargate-v2-token-address.ts | 6 +++--- .../stargate-v2-provider/stargate-v2-cross-chain-trade.ts | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 754c685d41..05cba00bcc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.30.0-alpha-stargate-v2.11", + "version": "5.30.0-alpha-stargate-v2.12", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-blockchain-supported-pools.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-blockchain-supported-pools.ts index c810e93b6e..ad9d1629dd 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-blockchain-supported-pools.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-blockchain-supported-pools.ts @@ -10,7 +10,7 @@ export const stargateV2BlockchainSupportedPools: Record Date: Tue, 16 Jul 2024 15:28:21 +0300 Subject: [PATCH 14/22] fix token address config --- package.json | 2 +- .../constants/stargate-v2-token-address.ts | 7 ++++--- .../stargate-v2-cross-chain-provider.ts | 6 ++++-- .../stargate-v2-provider/stargate-v2-cross-chain-trade.ts | 8 +++++--- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 05cba00bcc..21f0c3c895 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.30.0-alpha-stargate-v2.12", + "version": "5.30.0-alpha-stargate-v2.13", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-token-address.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-token-address.ts index 38aeb78ed8..0346f2b540 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-token-address.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-token-address.ts @@ -24,12 +24,12 @@ export const stargateV2TokenAddress: StargateV2TokenAddress = { '0x9702230a8ea53601f5cd2dc00fdbc13d4df4a8c7': stargateV2BridgeToken.USDT }, [BLOCKCHAIN_NAME.POLYGON]: { - '0x2791bca1f2de4661ed88a30c99a7a9449aa84174': stargateV2BridgeToken.USDC, + '0x3c499c542cef5e3811e1192ce70d8cc03d5c3359': stargateV2BridgeToken.USDC, '0xc2132d05d31c914a87c6611c10748aeb04b58e8f': stargateV2BridgeToken.USDT }, [BLOCKCHAIN_NAME.ARBITRUM]: { '0x0000000000000000000000000000000000000000': stargateV2BridgeToken.ETH, - '0xff970a61a04b1ca14834a43f5de4533ebddb5cc8': stargateV2BridgeToken.USDC, + '0xaf88d065e77c8cc2239327c5edb3a432268e5831': stargateV2BridgeToken.USDC, '0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9': stargateV2BridgeToken.USDT }, [BLOCKCHAIN_NAME.OPTIMISM]: { @@ -63,6 +63,7 @@ export const stargateV2TokenAddress: StargateV2TokenAddress = { '0x06efdbff2a14a7c8e15944d1f4a48f9f95f663a4': stargateV2BridgeToken.USDCe }, [BLOCKCHAIN_NAME.AURORA]: { - '0x368ebb46aca6b8d0787c96b2b20bd3cc3f2c45f7': stargateV2BridgeToken.USDC + '0xb12bfca5a55806aaf64e99521918a4bf0fc40802': stargateV2BridgeToken.USDC } }; + diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts index 90f16608b9..5a1f89d471 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts @@ -176,7 +176,8 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { slippageTolerance: options.slippageTolerance, gasData, sendParams, - messagingFee + messagingFee, + priceImpact: from.calculatePriceImpactPercent(to) }, options.providerAddress, routePath @@ -237,6 +238,7 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { const toBlockchain = to.blockchain as StargateV2SupportedBlockchains; const srcTokenPool = getTokenPoolByAddress(fromBlockchain, from.address); const dstTokenPool = getTokenPoolByAddress(toBlockchain, to.address); + if (!srcTokenPool || !dstTokenPool) { return false; } @@ -263,7 +265,7 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { const contractAddress = stargateV2ContractAddress[ fromBlockchain as StargateV2SupportedBlockchains - ][tokenSymbol] as string; + ][tokenSymbol]; if (!contractAddress) { throw new RubicSdkError(); diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts index 8a11ee1d92..ba814c4a24 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts @@ -59,7 +59,8 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { gasData: null, feeInfo, sendParams, - messagingFee + messagingFee, + priceImpact: 0 }, providerAddress || EvmWeb3Pure.EMPTY_ADDRESS, routePath @@ -123,6 +124,7 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { feeInfo: FeeInfo; sendParams: StargateV2QuoteParamsStruct; messagingFee: StargateV2MessagingFee; + priceImpact: number | null; }, providerAddress: string, routePath: RubicStep[] @@ -135,7 +137,7 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { this.slippageTolerance = crossChainTrade.slippageTolerance; this.stargateV2SendParams = crossChainTrade.sendParams; this.messagingFee = crossChainTrade.messagingFee; - this.priceImpact = this.from.calculatePriceImpactPercent(this.to); + this.priceImpact = crossChainTrade.priceImpact; this.toTokenAmountMin = this.to.tokenAmount.multipliedBy( 1 - crossChainTrade.slippageTolerance ); @@ -277,7 +279,7 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { return { estimatedGas: this.estimatedGas, feeInfo: this.feeInfo, - priceImpact: this.priceImpact || null, + priceImpact: this.priceImpact, slippage: this.slippageTolerance * 100, routePath: this.routePath }; From c66e48d83398ca8ba59fa90071ef304c8951e0cb Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 17 Jul 2024 16:39:10 +0300 Subject: [PATCH 15/22] fix getTokenPoolByAddress method --- package.json | 2 +- .../stargate-v2-provider/constants/stargate-v2-pool-id.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 21f0c3c895..a0515fe0d1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.30.0-alpha-stargate-v2.13", + "version": "5.30.0-alpha-stargate-v2.15", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-id.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-id.ts index f8953db439..dabf7c90cc 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-id.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-id.ts @@ -20,7 +20,8 @@ export function getTokenPoolByAddress( blockchain: StargateV2SupportedBlockchains, contractAddress: string ): number | null { - const tokenSymbol = stargateV2TokenAddress?.[blockchain]?.[contractAddress]; + const tokenAddress = contractAddress.toLowerCase(); + const tokenSymbol = stargateV2TokenAddress?.[blockchain]?.[tokenAddress]; if (tokenSymbol) { return stargateV2PoolId[tokenSymbol]; } From 2936be711c1cbb7ffa845f34deebd49fed34f197 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 17 Jul 2024 18:33:16 +0300 Subject: [PATCH 16/22] fix issues --- package.json | 2 +- .../stargate-v2-cross-chain-provider.ts | 8 ++-- .../stargate-v2-cross-chain-trade.ts | 37 +++---------------- 3 files changed, 10 insertions(+), 37 deletions(-) diff --git a/package.json b/package.json index a0515fe0d1..1ad8f03d70 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.30.0-alpha-stargate-v2.15", + "version": "5.30.0-alpha-stargate-v2.16", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts index 5a1f89d471..f45feab5b6 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts @@ -69,7 +69,7 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { const toBlockchain = toToken.blockchain as StargateV2SupportedBlockchains; const useProxy = options?.useProxy?.[this.type] ?? true; const isSupportedPools = this.checkSupportedPools(from, toToken); - + const fromTokenAddress = from.address.toLowerCase() if (!isSupportedPools) { return { trade: null, @@ -97,7 +97,7 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { const maxAmountError = await this.checkMaxAmount( from.blockchain, - from.address, + fromTokenAddress, fromWithoutFee.weiAmount ); @@ -124,11 +124,11 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { const { amountReceivedLD } = await this.getReceiveAmount( sendParams, from.blockchain, - from.address + fromTokenAddress ); const amountReceived = amountReceivedLD[1] as string; sendParams.minAmountLD = amountReceived; - const messagingFee = await this.getNativeFee(sendParams, from.blockchain, from.address); + const messagingFee = await this.getNativeFee(sendParams, from.blockchain, fromTokenAddress); const nativeToken = nativeTokensList[from.blockchain]; const cryptoFeeToken = await PriceTokenAmount.createFromToken({ diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts index ba814c4a24..ab641d5ffd 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts @@ -100,6 +100,8 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { public readonly messagingFee: StargateV2MessagingFee; + private readonly fromTokenAddress: string; + public get fromBlockchain(): StargateV2SupportedBlockchains { return this.from.blockchain as StargateV2SupportedBlockchains; } @@ -107,7 +109,7 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { protected get fromContractAddress(): string { const fromTokenSymbol = stargateV2TokenAddress[ this.from.blockchain as StargateV2SupportedBlockchains - ][this.from.address] as StargateV2BridgeToken; + ][this.fromTokenAddress] as StargateV2BridgeToken; return this.isProxyTrade ? rubicProxyContractAddress[this.fromBlockchain].gateway : (stargateV2ContractAddress?.[this.fromBlockchain]?.[fromTokenSymbol] as string); @@ -138,6 +140,7 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { this.stargateV2SendParams = crossChainTrade.sendParams; this.messagingFee = crossChainTrade.messagingFee; this.priceImpact = crossChainTrade.priceImpact; + this.fromTokenAddress = this.from.address.toLowerCase(); this.toTokenAmountMin = this.to.tokenAmount.multipliedBy( 1 - crossChainTrade.slippageTolerance ); @@ -209,7 +212,7 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { const fromBlockchain = this.from.blockchain as StargateV2SupportedBlockchains; const fromTokenSymbol = stargateV2TokenAddress[ fromBlockchain - ][this.from.address] as StargateV2BridgeToken; + ][this.fromTokenAddress] as StargateV2BridgeToken; console.log(receiverAddress); const contractAddress = stargateV2ContractAddress?.[fromBlockchain]?.[fromTokenSymbol]; @@ -284,34 +287,4 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { routePath: this.routePath }; } - - // private async getNativeFee( - // sendParam: StargateV2QuoteParamsStruct, - // fromBlockchain: EvmBlockchainName, - // tokenSymbol: StargateV2BridgeToken - // ): Promise { - // const contractAddress = - // stargateV2ContractAddress?.[fromBlockchain as StargateV2SupportedBlockchains]?.[ - // tokenSymbol - // ]; - // if (!contractAddress) { - // throw new RubicSdkError(); - // } - // try { - // const { 0: nativeFee, 1: lzTokenFee } = await Injector.web3PublicService - // .getWeb3Public(fromBlockchain) - // .callContractMethod<{ 0: string; 1: string }>( - // contractAddress, - // stargateV2SendQuoteAbi, - // 'quoteSend', - // [sendParam, false] - // ); - // return { - // nativeFee, - // lzTokenFee - // }; - // } catch (err) { - // throw new RubicSdkError(err?.message); - // } - // } } From d88e789e56535dc8f60285c0efd74d2e40a47dc9 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 18 Jul 2024 17:50:33 +0300 Subject: [PATCH 17/22] fix min amount received --- package.json | 2 +- .../stargate-v2-cross-chain-provider.ts | 9 +++++++-- .../stargate-v2-cross-chain-trade.ts | 8 ++++---- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 1ad8f03d70..2e4a41c670 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.30.0-alpha-stargate-v2.16", + "version": "5.30.0-alpha-stargate-v2.17", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts index f45feab5b6..6ee399f58f 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts @@ -127,7 +127,11 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { fromTokenAddress ); const amountReceived = amountReceivedLD[1] as string; - sendParams.minAmountLD = amountReceived; + const slippageAmount = new BigNumber(amountReceived) + .multipliedBy(options.slippageTolerance); + const minReceivedAmount = new BigNumber(amountReceived).minus(slippageAmount); + sendParams.amountLD = amountReceived; + sendParams.minAmountLD = minReceivedAmount.toFixed(0); const messagingFee = await this.getNativeFee(sendParams, from.blockchain, fromTokenAddress); const nativeToken = nativeTokensList[from.blockchain]; @@ -177,7 +181,8 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { gasData, sendParams, messagingFee, - priceImpact: from.calculatePriceImpactPercent(to) + priceImpact: from.calculatePriceImpactPercent(to), + toTokenAmountMin: Web3Pure.fromWei(minReceivedAmount, fromWithoutFee.decimals) }, options.providerAddress, routePath diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts index ab641d5ffd..04e0aac129 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts @@ -60,7 +60,8 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { feeInfo, sendParams, messagingFee, - priceImpact: 0 + priceImpact: 0, + toTokenAmountMin: new BigNumber(0) }, providerAddress || EvmWeb3Pure.EMPTY_ADDRESS, routePath @@ -127,6 +128,7 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { sendParams: StargateV2QuoteParamsStruct; messagingFee: StargateV2MessagingFee; priceImpact: number | null; + toTokenAmountMin: BigNumber; }, providerAddress: string, routePath: RubicStep[] @@ -140,10 +142,8 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { this.stargateV2SendParams = crossChainTrade.sendParams; this.messagingFee = crossChainTrade.messagingFee; this.priceImpact = crossChainTrade.priceImpact; + this.toTokenAmountMin = crossChainTrade.toTokenAmountMin; this.fromTokenAddress = this.from.address.toLowerCase(); - this.toTokenAmountMin = this.to.tokenAmount.multipliedBy( - 1 - crossChainTrade.slippageTolerance - ); } protected async getContractParams(options: GetContractParamsOptions): Promise { From d4c335cf9f097f66c8a6dcc3017b695a028742ac Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 19 Jul 2024 12:13:14 +0300 Subject: [PATCH 18/22] fix usdc token address for aurora, fix lint issue --- package.json | 2 +- .../stargate-v2-blockchain-supported-pools.ts | 2 +- .../constants/stargate-v2-token-address.ts | 3 +- .../stargate-v2-cross-chain-provider.ts | 53 ++++++++++--------- .../stargate-v2-cross-chain-trade.ts | 7 ++- 5 files changed, 35 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index 2e4a41c670..713e784f3f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.30.0-alpha-stargate-v2.17", + "version": "5.30.0-alpha-stargate-v2.18", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-blockchain-supported-pools.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-blockchain-supported-pools.ts index 529b09ffa5..c810e93b6e 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-blockchain-supported-pools.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-blockchain-supported-pools.ts @@ -34,7 +34,7 @@ export const stargateV2BlockchainSupportedPools: Record { const fromBlockchain = this.from.blockchain as StargateV2SupportedBlockchains; - const fromTokenSymbol = stargateV2TokenAddress[ - fromBlockchain - ][this.fromTokenAddress] as StargateV2BridgeToken; + const fromTokenSymbol = stargateV2TokenAddress[fromBlockchain][ + this.fromTokenAddress + ] as StargateV2BridgeToken; console.log(receiverAddress); const contractAddress = stargateV2ContractAddress?.[fromBlockchain]?.[fromTokenSymbol]; From ca9e3ee0fd3f0b199c9f9b8a882f92c419d47561 Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 19 Jul 2024 12:42:03 +0300 Subject: [PATCH 19/22] set sdk release version --- package.json | 2 +- .../stargate-v2-cross-chain-provider.ts | 37 ++++++++----------- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index 713e784f3f..ab747ee41f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.30.0-alpha-stargate-v2.18", + "version": "5.32.0", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts index d6693181f5..1c02bd55ef 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts @@ -150,16 +150,16 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { const gasData = options.gasCalculation === 'enabled' ? await StargateV2CrossChainTrade.getGasData( - from, - to, - feeInfo, - options.slippageTolerance, - options.providerAddress, - routePath, - sendParams, - messagingFee, - options.receiverAddress - ) + from, + to, + feeInfo, + options.slippageTolerance, + options.providerAddress, + routePath, + sendParams, + messagingFee, + options.receiverAddress + ) : null; return { trade: new StargateV2CrossChainTrade( @@ -274,12 +274,8 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { const contractAddress = stargateV2ContractAddress[fromBlockchain as StargateV2SupportedBlockchains][ - tokenSymbol - ]; - - if (!contractAddress) { - throw new RubicSdkError(); - } + tokenSymbol + ] as string; try { const { 2: amountReceivedLD } = await Injector.web3PublicService @@ -321,12 +317,9 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { fromBlockchain as StargateV2SupportedBlockchains ][tokenAddress] as StargateV2BridgeToken; const contractAddress = - stargateV2ContractAddress?.[fromBlockchain as StargateV2SupportedBlockchains]?.[ - tokenSymbol - ]; - if (!contractAddress) { - throw new RubicSdkError(); - } + stargateV2ContractAddress[fromBlockchain as StargateV2SupportedBlockchains][ + tokenSymbol + ] as string; try { const { 0: nativeFee, 1: lzTokenFee } = await Injector.web3PublicService .getWeb3Public(fromBlockchain) From 0a42972ad87cc0a31d35d8682b5205c39fb469ab Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 19 Jul 2024 12:45:38 +0300 Subject: [PATCH 20/22] fix lint issues --- .../stargate-v2-cross-chain-provider.ts | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts index 1c02bd55ef..281050be13 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts @@ -150,16 +150,16 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { const gasData = options.gasCalculation === 'enabled' ? await StargateV2CrossChainTrade.getGasData( - from, - to, - feeInfo, - options.slippageTolerance, - options.providerAddress, - routePath, - sendParams, - messagingFee, - options.receiverAddress - ) + from, + to, + feeInfo, + options.slippageTolerance, + options.providerAddress, + routePath, + sendParams, + messagingFee, + options.receiverAddress + ) : null; return { trade: new StargateV2CrossChainTrade( @@ -272,10 +272,9 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { fromBlockchain as StargateV2SupportedBlockchains ][tokenAddress] as StargateV2BridgeToken; - const contractAddress = - stargateV2ContractAddress[fromBlockchain as StargateV2SupportedBlockchains][ - tokenSymbol - ] as string; + const contractAddress = stargateV2ContractAddress[ + fromBlockchain as StargateV2SupportedBlockchains + ][tokenSymbol] as string; try { const { 2: amountReceivedLD } = await Injector.web3PublicService @@ -316,10 +315,9 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { const tokenSymbol = stargateV2TokenAddress[ fromBlockchain as StargateV2SupportedBlockchains ][tokenAddress] as StargateV2BridgeToken; - const contractAddress = - stargateV2ContractAddress[fromBlockchain as StargateV2SupportedBlockchains][ - tokenSymbol - ] as string; + const contractAddress = stargateV2ContractAddress[ + fromBlockchain as StargateV2SupportedBlockchains + ][tokenSymbol] as string; try { const { 0: nativeFee, 1: lzTokenFee } = await Injector.web3PublicService .getWeb3Public(fromBlockchain) From 6d519218c02a89b350ae36ca87cb1771a3cf33d8 Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 19 Jul 2024 13:25:12 +0300 Subject: [PATCH 21/22] minor fix --- .../constants/stargate-v2-pool-abi.ts | 16 ++++++++-------- .../stargate-v2-cross-chain-provider.ts | 8 +++++--- .../stargate-v2-cross-chain-trade.ts | 8 ++++---- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-abi.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-abi.ts index 6c6e5110cf..ca8b03a643 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-abi.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/constants/stargate-v2-pool-abi.ts @@ -1,6 +1,6 @@ import { AbiItem } from 'web3-utils'; -export const stargateV2PoolAbi = [ +export const stargateV2PoolAbi: AbiItem[] = [ { inputs: [ { @@ -51,9 +51,9 @@ export const stargateV2PoolAbi = [ stateMutability: 'view', type: 'function' } -] as AbiItem[]; +]; -export const stargateV2SendQuoteAbi = [ +export const stargateV2SendQuoteAbi: AbiItem[] = [ { inputs: [ { @@ -91,9 +91,9 @@ export const stargateV2SendQuoteAbi = [ stateMutability: 'view', type: 'function' } -] as AbiItem[]; +]; -export const stargateV2SendTokenAbi = [ +export const stargateV2SendTokenAbi: AbiItem[] = [ { inputs: [ { @@ -163,9 +163,9 @@ export const stargateV2SendTokenAbi = [ stateMutability: 'payable', type: 'function' } -] as AbiItem[]; +]; -export const stargateV2PoolBalanceAbi = [ +export const stargateV2PoolBalanceAbi: AbiItem[] = [ { inputs: [], name: 'poolBalance', @@ -179,4 +179,4 @@ export const stargateV2PoolBalanceAbi = [ stateMutability: 'view', type: 'function' } -] as AbiItem[]; +]; diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts index 281050be13..5284a9688d 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-provider.ts @@ -62,10 +62,7 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { throw new NotSupportedBlockchain(); } try { - const toBlockchain = toToken.blockchain as StargateV2SupportedBlockchains; - const useProxy = options?.useProxy?.[this.type] ?? true; const isSupportedPools = this.checkSupportedPools(from, toToken); - const fromTokenAddress = from.address.toLowerCase(); if (!isSupportedPools) { return { trade: null, @@ -73,6 +70,11 @@ export class StargateV2CrossChainProvider extends CrossChainProvider { tradeType: this.type }; } + + const toBlockchain = toToken.blockchain as StargateV2SupportedBlockchains; + const useProxy = options?.useProxy?.[this.type] ?? true; + const fromTokenAddress = from.address.toLowerCase(); + const dstChainId = stargateV2ChainIds[toBlockchain]; const feeInfo = await this.getFeeInfo( diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts index 7c5f5615e4..6a78fb2bdb 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts @@ -205,14 +205,14 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { } } - protected async getTransactionConfigAndAmount( - receiverAddress?: string | undefined - ): Promise<{ config: EvmEncodeConfig; amount: string }> { + protected async getTransactionConfigAndAmount(): Promise<{ + config: EvmEncodeConfig; + amount: string; + }> { const fromBlockchain = this.from.blockchain as StargateV2SupportedBlockchains; const fromTokenSymbol = stargateV2TokenAddress[fromBlockchain][ this.fromTokenAddress ] as StargateV2BridgeToken; - console.log(receiverAddress); const contractAddress = stargateV2ContractAddress?.[fromBlockchain]?.[fromTokenSymbol]; if (!contractAddress) { From 307ded42b0a638fe3e5ecfdff027de06c57642fa Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 19 Jul 2024 13:38:09 +0300 Subject: [PATCH 22/22] fix getTransactionConfigAndAmount method --- .../stargate-v2-cross-chain-trade.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts index 6a78fb2bdb..d0b850fb3e 100644 --- a/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/stargate-v2-provider/stargate-v2-cross-chain-trade.ts @@ -205,15 +205,17 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { } } - protected async getTransactionConfigAndAmount(): Promise<{ - config: EvmEncodeConfig; - amount: string; - }> { + protected async getTransactionConfigAndAmount( + receiverAddress?: string | undefined + ): Promise<{ config: EvmEncodeConfig; amount: string }> { const fromBlockchain = this.from.blockchain as StargateV2SupportedBlockchains; const fromTokenSymbol = stargateV2TokenAddress[fromBlockchain][ this.fromTokenAddress ] as StargateV2BridgeToken; - + const sendParams = { + ...this.stargateV2SendParams, + to: receiverAddress || this.walletAddress + }; const contractAddress = stargateV2ContractAddress?.[fromBlockchain]?.[fromTokenSymbol]; if (!contractAddress) { throw new RubicSdkError(); @@ -227,7 +229,7 @@ export class StargateV2CrossChainTrade extends EvmCrossChainTrade { contractAddress, stargateV2SendTokenAbi, 'sendToken', - [this.stargateV2SendParams, this.messagingFee, this.walletAddress], + [sendParams, this.messagingFee, this.walletAddress], value ); return {