diff --git a/.env.example b/.env.example index a341210..bb8cddb 100644 --- a/.env.example +++ b/.env.example @@ -31,6 +31,9 @@ ARBITRUM_ONE_RPC=https://arbitrum-one.public.blastapi.io OP_MAINNET_RPC=https://optimism-mainnet.public.blastapi.io POLYGON_MAINNET_RPC=https://polygon-bor-rpc.publicnode.com UNICHAIN_RPC=https://mainnet.unichain.org +AVALANCHE_RPC=https://avalanche-c-chain-rpc.publicnode.com +BSC_RPC=https://bsc-mainnet.public.blastapi.io +LINEA_RPC=https://linea-rpc.publicnode.com # Etherscan now uses a single API key for all chains. ETHERSCAN_API_KEY= diff --git a/contracts/interfaces/IRoute.sol b/contracts/interfaces/IRoute.sol index aa67fd7..e71f8e9 100644 --- a/contracts/interfaces/IRoute.sol +++ b/contracts/interfaces/IRoute.sol @@ -16,7 +16,9 @@ interface IRoute { ARBITRUM_SEPOLIA, BASE_SEPOLIA, POLYGON_AMOY, - UNICHAIN + UNICHAIN, + BSC, + LINEA } enum Provider { diff --git a/contracts/utils/AdapterHelper.sol b/contracts/utils/AdapterHelper.sol index 999add4..b29b14a 100644 --- a/contracts/utils/AdapterHelper.sol +++ b/contracts/utils/AdapterHelper.sol @@ -24,6 +24,12 @@ abstract contract AdapterHelper is IRoute { } else if (destinationDomain == Domain.POLYGON_MAINNET) { return 137; + } else + if (destinationDomain == Domain.BSC) { + return 56; + } else + if (destinationDomain == Domain.LINEA) { + return 59144; } else { revert UnsupportedDomain(); } diff --git a/contracts/utils/CCTPAdapter.sol b/contracts/utils/CCTPAdapter.sol index 45a4a93..fdf2336 100644 --- a/contracts/utils/CCTPAdapter.sol +++ b/contracts/utils/CCTPAdapter.sol @@ -18,8 +18,7 @@ abstract contract CCTPAdapter is AdapterHelper { address cctpTokenMessenger, address cctpMessageTransmitter ) { - require(cctpTokenMessenger != address(0), ZeroAddress()); - require(cctpMessageTransmitter != address(0), ZeroAddress()); + // No check for address(0) to allow deployment on chains where CCTP V1 is not available CCTP_TOKEN_MESSENGER = ICCTPTokenMessenger(cctpTokenMessenger); CCTP_MESSAGE_TRANSMITTER = ICCTPMessageTransmitter(cctpMessageTransmitter); } diff --git a/contracts/utils/StargateAdapter.sol b/contracts/utils/StargateAdapter.sol index f283999..43ef87b 100644 --- a/contracts/utils/StargateAdapter.sol +++ b/contracts/utils/StargateAdapter.sol @@ -55,6 +55,12 @@ abstract contract StargateAdapter is AdapterHelper { } else if (destinationDomain == Domain.UNICHAIN) { return 30320; + } else + if (destinationDomain == Domain.BSC) { + return 30102; + } else + if (destinationDomain == Domain.LINEA) { + return 30183; } else { revert UnsupportedDomain(); } diff --git a/deployments/deploy-avalanche.log b/deployments/deploy-avalanche.log new file mode 100644 index 0000000..6d08e52 --- /dev/null +++ b/deployments/deploy-avalanche.log @@ -0,0 +1,32 @@ +Deployment ID: MVP +Deploying Repayer +Using config for: AVALANCHE +Repayer: 0x36364Acc7B9c67692CA215af09A41CBd10439511 +RepayerProxyAdmin: 0x2B5D04eF6b3279bCdA4B219b02FAF627dA1664CB +RepayerRoutes: +┌─────────┬──────────────────────────────────────────────┬────────────────┬─────────────┬───────────────────┐ +│ (index) │ Pool │ Domain │ Provider │ SupportsAllTokens │ +├─────────┼──────────────────────────────────────────────┼────────────────┼─────────────┼───────────────────┤ +│ 0 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'ARBITRUM_ONE' │ 'CCTP' │ true │ +│ 1 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'ARBITRUM_ONE' │ 'EVERCLEAR' │ true │ +│ 2 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'ARBITRUM_ONE' │ 'STARGATE' │ true │ +│ 3 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'BASE' │ 'CCTP' │ true │ +│ 4 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'BASE' │ 'EVERCLEAR' │ true │ +│ 5 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'BASE' │ 'STARGATE' │ true │ +│ 6 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'OP_MAINNET' │ 'CCTP' │ true │ +│ 7 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'OP_MAINNET' │ 'EVERCLEAR' │ true │ +│ 8 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'OP_MAINNET' │ 'STARGATE' │ true │ +│ 9 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'ARBITRUM_ONE' │ 'CCTP' │ false │ +│ 10 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'BASE' │ 'CCTP' │ false │ +│ 11 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'ETHEREUM' │ 'CCTP' │ false │ +│ 12 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'OP_MAINNET' │ 'CCTP' │ false │ +│ 13 │ '0x2781650E1d76b56b3BCD9836e4d16E04c86d3D07' │ 'ETHEREUM' │ 'CCTP' │ true │ +│ 14 │ '0x2781650E1d76b56b3BCD9836e4d16E04c86d3D07' │ 'ETHEREUM' │ 'EVERCLEAR' │ true │ +│ 15 │ '0x2781650E1d76b56b3BCD9836e4d16E04c86d3D07' │ 'ETHEREUM' │ 'STARGATE' │ true │ +│ 16 │ '0x2781650E1d76b56b3BCD9836e4d16E04c86d3D07' │ 'UNICHAIN' │ 'CCTP' │ true │ +│ 17 │ '0x2781650E1d76b56b3BCD9836e4d16E04c86d3D07' │ 'UNICHAIN' │ 'EVERCLEAR' │ true │ +│ 18 │ '0x2781650E1d76b56b3BCD9836e4d16E04c86d3D07' │ 'UNICHAIN' │ 'STARGATE' │ true │ +│ 19 │ '0x5E8da448f3F7290cA355BbF7EF9F323ab8fDE422' │ 'ETHEREUM' │ 'CCTP' │ true │ +│ 20 │ '0x5E8da448f3F7290cA355BbF7EF9F323ab8fDE422' │ 'ETHEREUM' │ 'EVERCLEAR' │ true │ +│ 21 │ '0x5E8da448f3F7290cA355BbF7EF9F323ab8fDE422' │ 'ETHEREUM' │ 'STARGATE' │ true │ +└─────────┴──────────────────────────────────────────────┴────────────────┴─────────────┴───────────────────┘ diff --git a/deployments/deploy-bsc.log b/deployments/deploy-bsc.log new file mode 100644 index 0000000..8d63d9f --- /dev/null +++ b/deployments/deploy-bsc.log @@ -0,0 +1,36 @@ +Deployment ID: MVP +Deploying Repayer +Using config for: BSC +Repayer: 0x36364Acc7B9c67692CA215af09A41CBd10439511 +RepayerProxyAdmin: 0x2B5D04eF6b3279bCdA4B219b02FAF627dA1664CB +RepayerRoutes: +┌─────────┬──────────────────────────────────────────────┬────────────────┬─────────────┬───────────────────┐ +│ (index) │ Pool │ Domain │ Provider │ SupportsAllTokens │ +├─────────┼──────────────────────────────────────────────┼────────────────┼─────────────┼───────────────────┤ +│ 0 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'ARBITRUM_ONE' │ 'ACROSS' │ true │ +│ 1 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'ARBITRUM_ONE' │ 'EVERCLEAR' │ true │ +│ 2 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'ARBITRUM_ONE' │ 'STARGATE' │ true │ +│ 3 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'BASE' │ 'ACROSS' │ true │ +│ 4 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'BASE' │ 'EVERCLEAR' │ true │ +│ 5 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'BASE' │ 'STARGATE' │ true │ +│ 6 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'OP_MAINNET' │ 'ACROSS' │ true │ +│ 7 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'OP_MAINNET' │ 'EVERCLEAR' │ true │ +│ 8 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'OP_MAINNET' │ 'STARGATE' │ true │ +│ 9 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'ARBITRUM_ONE' │ 'ACROSS' │ false │ +│ 10 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'ARBITRUM_ONE' │ 'EVERCLEAR' │ false │ +│ 11 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'ARBITRUM_ONE' │ 'STARGATE' │ false │ +│ 12 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'BASE' │ 'ACROSS' │ false │ +│ 13 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'BASE' │ 'EVERCLEAR' │ false │ +│ 14 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'BASE' │ 'STARGATE' │ false │ +│ 15 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'ETHEREUM' │ 'ACROSS' │ false │ +│ 16 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'ETHEREUM' │ 'EVERCLEAR' │ false │ +│ 17 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'ETHEREUM' │ 'STARGATE' │ false │ +│ 18 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'OP_MAINNET' │ 'ACROSS' │ false │ +│ 19 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'OP_MAINNET' │ 'EVERCLEAR' │ false │ +│ 20 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'OP_MAINNET' │ 'STARGATE' │ false │ +│ 21 │ '0x2781650E1d76b56b3BCD9836e4d16E04c86d3D07' │ 'ETHEREUM' │ 'ACROSS' │ true │ +│ 22 │ '0x2781650E1d76b56b3BCD9836e4d16E04c86d3D07' │ 'ETHEREUM' │ 'EVERCLEAR' │ true │ +│ 23 │ '0x2781650E1d76b56b3BCD9836e4d16E04c86d3D07' │ 'ETHEREUM' │ 'STARGATE' │ true │ +│ 24 │ '0x5E8da448f3F7290cA355BbF7EF9F323ab8fDE422' │ 'ETHEREUM' │ 'EVERCLEAR' │ true │ +│ 25 │ '0x5E8da448f3F7290cA355BbF7EF9F323ab8fDE422' │ 'ETHEREUM' │ 'STARGATE' │ true │ +└─────────┴──────────────────────────────────────────────┴────────────────┴─────────────┴───────────────────┘ diff --git a/deployments/deploy-linea.log b/deployments/deploy-linea.log new file mode 100644 index 0000000..e5b39a7 --- /dev/null +++ b/deployments/deploy-linea.log @@ -0,0 +1,36 @@ +Deployment ID: MVP +Deploying Repayer +Using config for: LINEA +Repayer: 0x36364Acc7B9c67692CA215af09A41CBd10439511 +RepayerProxyAdmin: 0x2B5D04eF6b3279bCdA4B219b02FAF627dA1664CB +RepayerRoutes: +┌─────────┬──────────────────────────────────────────────┬────────────────┬─────────────┬───────────────────┐ +│ (index) │ Pool │ Domain │ Provider │ SupportsAllTokens │ +├─────────┼──────────────────────────────────────────────┼────────────────┼─────────────┼───────────────────┤ +│ 0 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'ARBITRUM_ONE' │ 'ACROSS' │ true │ +│ 1 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'ARBITRUM_ONE' │ 'EVERCLEAR' │ true │ +│ 2 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'ARBITRUM_ONE' │ 'STARGATE' │ true │ +│ 3 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'BASE' │ 'ACROSS' │ true │ +│ 4 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'BASE' │ 'EVERCLEAR' │ true │ +│ 5 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'BASE' │ 'STARGATE' │ true │ +│ 6 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'OP_MAINNET' │ 'ACROSS' │ true │ +│ 7 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'OP_MAINNET' │ 'EVERCLEAR' │ true │ +│ 8 │ '0x7C255279c098fdF6c3116D2BecD9978002c09f4b' │ 'OP_MAINNET' │ 'STARGATE' │ true │ +│ 9 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'ARBITRUM_ONE' │ 'ACROSS' │ false │ +│ 10 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'ARBITRUM_ONE' │ 'EVERCLEAR' │ false │ +│ 11 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'ARBITRUM_ONE' │ 'STARGATE' │ false │ +│ 12 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'BASE' │ 'ACROSS' │ false │ +│ 13 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'BASE' │ 'EVERCLEAR' │ false │ +│ 14 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'BASE' │ 'STARGATE' │ false │ +│ 15 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'ETHEREUM' │ 'ACROSS' │ false │ +│ 16 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'ETHEREUM' │ 'EVERCLEAR' │ false │ +│ 17 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'ETHEREUM' │ 'STARGATE' │ false │ +│ 18 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'OP_MAINNET' │ 'ACROSS' │ false │ +│ 19 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'OP_MAINNET' │ 'EVERCLEAR' │ false │ +│ 20 │ '0xB58Bb9643884abbbad64FA7eBc874c5481E5c032' │ 'OP_MAINNET' │ 'STARGATE' │ false │ +│ 21 │ '0x2781650E1d76b56b3BCD9836e4d16E04c86d3D07' │ 'ETHEREUM' │ 'ACROSS' │ true │ +│ 22 │ '0x2781650E1d76b56b3BCD9836e4d16E04c86d3D07' │ 'ETHEREUM' │ 'EVERCLEAR' │ true │ +│ 23 │ '0x2781650E1d76b56b3BCD9836e4d16E04c86d3D07' │ 'ETHEREUM' │ 'STARGATE' │ true │ +│ 24 │ '0x5E8da448f3F7290cA355BbF7EF9F323ab8fDE422' │ 'ETHEREUM' │ 'EVERCLEAR' │ true │ +│ 25 │ '0x5E8da448f3F7290cA355BbF7EF9F323ab8fDE422' │ 'ETHEREUM' │ 'STARGATE' │ true │ +└─────────┴──────────────────────────────────────────────┴────────────────┴─────────────┴───────────────────┘ diff --git a/deployments/deployments.yml b/deployments/deployments.yml index 40bcd8c..20a2e6a 100644 --- a/deployments/deployments.yml +++ b/deployments/deployments.yml @@ -62,3 +62,24 @@ eip155:130: USDC: "0x078D782b760474a361dDA0AF3839290b0EF57AD6" Rebalancer: "0xA85Cf46c150db2600b1D03E437bedD5513869888" Repayer: "0x36364Acc7B9c67692CA215af09A41CBd10439511" + +eip155:43114: + deployment id: MVP + name: AVALANCHE + env: prod + USDC: "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E" + Repayer: "0x36364Acc7B9c67692CA215af09A41CBd10439511" + +eip155:56: + deployment id: MVP + name: BSC + env: prod + USDC: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d" + Repayer: "0x36364Acc7B9c67692CA215af09A41CBd10439511" + +eip155:59144: + deployment id: MVP + name: LINEA + env: prod + USDC: "0x176211869cA2b568f2A7D4EE941E073a821EE1ff" + Repayer: "0x36364Acc7B9c67692CA215af09A41CBd10439511" diff --git a/hardhat.config.ts b/hardhat.config.ts index 86e02e8..85b1fae 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -560,6 +560,11 @@ const config: HardhatUserConfig = { localhost: { url: "http://127.0.0.1:8545/", }, + [Network.AVALANCHE]: { + chainId: networkConfig.AVALANCHE.ChainId, + url: process.env.AVALANCHE_RPC || "https://avalanche-c-chain-rpc.publicnode.com", + accounts, + }, [Network.BASE_SEPOLIA]: { chainId: networkConfig.BASE_SEPOLIA.ChainId, url: process.env.BASE_SEPOLIA_RPC || "https://sepolia.base.org", @@ -610,6 +615,16 @@ const config: HardhatUserConfig = { url: process.env.UNICHAIN_RPC || "https://mainnet.unichain.org", accounts, }, + [Network.BSC]: { + chainId: networkConfig.BSC.ChainId, + url: process.env.BSC_RPC || "https://bsc-mainnet.public.blastapi.io", + accounts, + }, + [Network.LINEA]: { + chainId: networkConfig.LINEA.ChainId, + url: process.env.LINEA_RPC || "https://linea-rpc.publicnode.com", + accounts, + }, hardhat: { forking: { url: isSet(process.env.DRY_RUN) || isSet(process.env.FORK_TEST) @@ -647,6 +662,14 @@ const config: HardhatUserConfig = { browserURL: "https://uniscan.xyz" }, }, + { + network: "linea", + chainId: networkConfig.LINEA.ChainId, + urls: { + apiURL: "https://api.etherscan.io/v2/api", + browserURL: "https://lineascan.build/" + }, + }, ], }, warnings: { diff --git a/network.config.ts b/network.config.ts index c3e851e..78883e9 100644 --- a/network.config.ts +++ b/network.config.ts @@ -49,6 +49,8 @@ export enum Network { BASE_SEPOLIA = "BASE_SEPOLIA", POLYGON_AMOY = "POLYGON_AMOY", UNICHAIN = "UNICHAIN", + BSC = "BSC", + LINEA = "LINEA", }; export enum Provider { @@ -114,7 +116,7 @@ interface HubConfig { export interface NetworkConfig { ChainId: number; - CCTP: CCTPConfig; + CCTP?: CCTPConfig; AcrossV3SpokePool?: string; StargateTreasurer?: string; EverclearFeeAdapter?: string; @@ -241,10 +243,37 @@ export const networkConfig: NetworksConfig = { RepayerCaller: "0x9A5B33bd11329116A55F764c604a5152eE8Ca292", MpcAddress: "0x3F68D470701522F1c9bb21CF44a33dBFa8E299C2", SignerAddress: "0x83B8D2eAda788943c3e80892f37f9c102271C1D6", - AavePool: { - AaveAddressesProvider: AAVEPools.AaveV3Avalanche.POOL_ADDRESSES_PROVIDER, - MinHealthFactor: 300, - DefaultLTV: 0, + RepayerRoutes: { + [LiquidityPoolAaveUSDC]: { + SupportsAllTokens: true, + Domains: { + [Network.ARBITRUM_ONE]: [Provider.CCTP, Provider.EVERCLEAR, Provider.STARGATE], + [Network.BASE]: [Provider.CCTP, Provider.EVERCLEAR, Provider.STARGATE], + [Network.OP_MAINNET]: [Provider.CCTP, Provider.EVERCLEAR, Provider.STARGATE], + }, + }, + [LiquidityPoolUSDC]: { + SupportsAllTokens: false, + Domains: { + [Network.ARBITRUM_ONE]: [Provider.CCTP], + [Network.BASE]: [Provider.CCTP], + [Network.ETHEREUM]: [Provider.CCTP], + [Network.OP_MAINNET]: [Provider.CCTP], + }, + }, + [LiquidityPoolUSDCStablecoin]: { + SupportsAllTokens: true, + Domains: { + [Network.ETHEREUM]: [Provider.CCTP, Provider.EVERCLEAR, Provider.STARGATE], + [Network.UNICHAIN]: [Provider.CCTP, Provider.EVERCLEAR, Provider.STARGATE], + }, + }, + [LiquidityPoolAaveUSDCLongTerm]: { + SupportsAllTokens: true, + Domains: { + [Network.ETHEREUM]: [Provider.CCTP, Provider.EVERCLEAR, Provider.STARGATE], + }, + }, }, }, OP_MAINNET: { @@ -886,6 +915,100 @@ export const networkConfig: NetworksConfig = { }, USDCStablecoinPool: true, }, + BSC: { + ChainId: 56, + AcrossV3SpokePool: "0x4e8E101924eDE233C13e2D8622DC8aED2872d505", + StargateTreasurer: "0x0a6A15964fEe494A881338D65940430797F0d97C", + EverclearFeeAdapter: "0x15a7cA97D1ed168fB34a4055CEFa2E2f9Bdb6C75", + USDC: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d", + WrappedNativeToken: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", + IsTest: false, + Admin: "0x4eA9E682BA79bC403523c9e8D98A05EaF3810636", + WithdrawProfit: "0x83B8D2eAda788943c3e80892f37f9c102271C1D6", + Pauser: "0x83B8D2eAda788943c3e80892f37f9c102271C1D6", + RebalanceCaller: "0x83B8D2eAda788943c3e80892f37f9c102271C1D6", + RepayerCaller: "0x9A5B33bd11329116A55F764c604a5152eE8Ca292", + MpcAddress: "0x3F68D470701522F1c9bb21CF44a33dBFa8E299C2", + SignerAddress: "0x83B8D2eAda788943c3e80892f37f9c102271C1D6", + RepayerRoutes: { + [LiquidityPoolAaveUSDC]: { + SupportsAllTokens: true, + Domains: { + [Network.ARBITRUM_ONE]: [Provider.ACROSS, Provider.EVERCLEAR, Provider.STARGATE], + [Network.BASE]: [Provider.ACROSS, Provider.EVERCLEAR, Provider.STARGATE], + [Network.OP_MAINNET]: [Provider.ACROSS, Provider.EVERCLEAR, Provider.STARGATE], + }, + }, + [LiquidityPoolUSDC]: { + SupportsAllTokens: false, + Domains: { + [Network.ARBITRUM_ONE]: [Provider.ACROSS, Provider.EVERCLEAR, Provider.STARGATE], + [Network.BASE]: [Provider.ACROSS, Provider.EVERCLEAR, Provider.STARGATE], + [Network.ETHEREUM]: [Provider.ACROSS, Provider.EVERCLEAR, Provider.STARGATE], + [Network.OP_MAINNET]: [Provider.ACROSS, Provider.EVERCLEAR, Provider.STARGATE], + }, + }, + [LiquidityPoolUSDCStablecoin]: { + SupportsAllTokens: true, + Domains: { + [Network.ETHEREUM]: [Provider.ACROSS, Provider.EVERCLEAR, Provider.STARGATE], + }, + }, + [LiquidityPoolAaveUSDCLongTerm]: { + SupportsAllTokens: true, + Domains: { + [Network.ETHEREUM]: [Provider.EVERCLEAR, Provider.STARGATE], + }, + }, + }, + }, + LINEA: { + ChainId: 59144, + AcrossV3SpokePool: "0x7E63A5f1a8F0B4d0934B2f2327DAED3F6bb2ee75", + StargateTreasurer: "0xf5F74d2508e97A3a7CCA2ccb75c8325D66b46152", + EverclearFeeAdapter: "0x1B0Dc9CB7EadDa36f4CcFB8130B0Ad967b0A3508", + USDC: "0x176211869cA2b568f2A7D4EE941E073a821EE1ff", + WrappedNativeToken: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", + IsTest: false, + Admin: "0x4eA9E682BA79bC403523c9e8D98A05EaF3810636", + WithdrawProfit: "0x83B8D2eAda788943c3e80892f37f9c102271C1D6", + Pauser: "0x83B8D2eAda788943c3e80892f37f9c102271C1D6", + RebalanceCaller: "0x83B8D2eAda788943c3e80892f37f9c102271C1D6", + RepayerCaller: "0x9A5B33bd11329116A55F764c604a5152eE8Ca292", + MpcAddress: "0x3F68D470701522F1c9bb21CF44a33dBFa8E299C2", + SignerAddress: "0x83B8D2eAda788943c3e80892f37f9c102271C1D6", + RepayerRoutes: { + [LiquidityPoolAaveUSDC]: { + SupportsAllTokens: true, + Domains: { + [Network.ARBITRUM_ONE]: [Provider.ACROSS, Provider.EVERCLEAR, Provider.STARGATE], + [Network.BASE]: [Provider.ACROSS, Provider.EVERCLEAR, Provider.STARGATE], + [Network.OP_MAINNET]: [Provider.ACROSS, Provider.EVERCLEAR, Provider.STARGATE], + }, + }, + [LiquidityPoolUSDC]: { + SupportsAllTokens: false, + Domains: { + [Network.ARBITRUM_ONE]: [Provider.ACROSS, Provider.EVERCLEAR, Provider.STARGATE], + [Network.BASE]: [Provider.ACROSS, Provider.EVERCLEAR, Provider.STARGATE], + [Network.ETHEREUM]: [Provider.ACROSS, Provider.EVERCLEAR, Provider.STARGATE], + [Network.OP_MAINNET]: [Provider.ACROSS, Provider.EVERCLEAR, Provider.STARGATE], + }, + }, + [LiquidityPoolUSDCStablecoin]: { + SupportsAllTokens: true, + Domains: { + [Network.ETHEREUM]: [Provider.ACROSS, Provider.EVERCLEAR, Provider.STARGATE], + }, + }, + [LiquidityPoolAaveUSDCLongTerm]: { + SupportsAllTokens: true, + Domains: { + [Network.ETHEREUM]: [Provider.EVERCLEAR, Provider.STARGATE], + }, + }, + }, + }, ETHEREUM_SEPOLIA: { ChainId: 11155111, CCTP: { diff --git a/package.json b/package.json index 9735a8c..438a615 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,9 @@ "deploy-repayer-polygon": "hardhat run ./scripts/deployRepayer.ts --network POLYGON_MAINNET", "deploy-repayer-unichain": "hardhat run ./scripts/deployRepayer.ts --network UNICHAIN", "deploy-repayer-ethereum": "hardhat run ./scripts/deployRepayer.ts --network ETHEREUM", + "deploy-repayer-avalanche": "hardhat run ./scripts/deployRepayer.ts --network AVALANCHE", + "deploy-repayer-bsc": "hardhat run ./scripts/deployRepayer.ts --network BSC", + "deploy-repayer-linea": "hardhat run ./scripts/deployRepayer.ts --network LINEA", "deploy-repayer-base-stage": "DEPLOY_TYPE=STAGE hardhat run ./scripts/deployRepayer.ts --network BASE", "deploy-repayer-arbitrumone-stage": "DEPLOY_TYPE=STAGE hardhat run ./scripts/deployRepayer.ts --network ARBITRUM_ONE", "deploy-repayer-opmainnet-stage": "DEPLOY_TYPE=STAGE hardhat run ./scripts/deployRepayer.ts --network OP_MAINNET", @@ -82,6 +85,9 @@ "dry:deploy-repayer-polygon": "DRY_RUN=POLYGON_MAINNET VERIFY=false ts-node --files ./scripts/deployRepayer.ts", "dry:deploy-repayer-unichain": "__EDR_UNSAFE_SKIP_UNSUPPORTED_TRANSACTION_TYPES=true DRY_RUN=UNICHAIN VERIFY=false ts-node --files ./scripts/deployRepayer.ts", "dry:deploy-repayer-ethereum": "DRY_RUN=ETHEREUM VERIFY=false ts-node --files ./scripts/deployRepayer.ts", + "dry:deploy-repayer-avalanche": "DRY_RUN=AVALANCHE VERIFY=false ts-node --files ./scripts/deployRepayer.ts", + "dry:deploy-repayer-bsc": "DRY_RUN=BSC VERIFY=false ts-node --files ./scripts/deployRepayer.ts", + "dry:deploy-repayer-linea": "DRY_RUN=LINEA VERIFY=false ts-node --files ./scripts/deployRepayer.ts", "dry:deploy-repayer-base-stage": "DRY_RUN=BASE DEPLOY_TYPE=STAGE VERIFY=false ts-node --files ./scripts/deployRepayer.ts", "dry:deploy-repayer-arbitrumone-stage": "DRY_RUN=ARBITRUM_ONE DEPLOY_TYPE=STAGE VERIFY=false ts-node --files ./scripts/deployRepayer.ts", "dry:deploy-repayer-opmainnet-stage": "DRY_RUN=OP_MAINNET DEPLOY_TYPE=STAGE VERIFY=false ts-node --files ./scripts/deployRepayer.ts", diff --git a/scripts/common.ts b/scripts/common.ts index 151591b..c005d26 100644 --- a/scripts/common.ts +++ b/scripts/common.ts @@ -51,6 +51,8 @@ export const DomainSolidity = { BASE_SEPOLIA: 10n, POLYGON_AMOY: 11n, UNICHAIN: 12n, + BSC: 13n, + LINEA: 14n, }; export const SolidityDomain: { [n: number]: Network } = { @@ -67,6 +69,8 @@ export const SolidityDomain: { [n: number]: Network } = { 10: Network.BASE_SEPOLIA, 11: Network.POLYGON_AMOY, 12: Network.UNICHAIN, + 13: Network.BSC, + 14: Network.LINEA, }; export const SolidityProvider: { [n: number]: Provider } = { diff --git a/scripts/deploy.ts b/scripts/deploy.ts index 0b178a1..aa37a33 100644 --- a/scripts/deploy.ts +++ b/scripts/deploy.ts @@ -57,6 +57,13 @@ export async function main() { assert(isAddress(config.SignerAddress), "SignerAddress must be an address"); assert(isAddress(config.WrappedNativeToken), "WrappedNativeToken must be an address"); + if (!config.CCTP) { + config.CCTP = { + TokenMessenger: ZERO_ADDRESS, + MessageTransmitter: ZERO_ADDRESS, + }; + } + if (config.Hub) { assert(config.Hub.Tiers.length > 0, "Empty liquidity mining tiers configuration."); assert(config.Hub.AssetsLimit <= MaxUint256 / 10n ** 12n, "Assets limit is too high"); diff --git a/scripts/deployRepayer.ts b/scripts/deployRepayer.ts index 2d22b8b..0be32ce 100644 --- a/scripts/deployRepayer.ts +++ b/scripts/deployRepayer.ts @@ -30,8 +30,6 @@ export async function main() { assert(isAddress(config.USDC), "USDC must be an address"); assert(isAddress(config.Admin), "Admin must be an address"); assert(isAddress(config.RepayerCaller), "RepayerCaller must be an address"); - assert(isAddress(config.CCTP.TokenMessenger), "CCTP TokenMessenger must be an address"); - assert(isAddress(config.CCTP.MessageTransmitter), "CCTP MessageTransmitter must be an address"); assert(isAddress(config.WrappedNativeToken), "WrappedNativeToken must be an address"); const repayerRoutes: {Pool: string, Domain: Network, Provider: Provider, SupportsAllTokens: boolean}[] = []; @@ -49,6 +47,12 @@ export async function main() { } await addLocalPools(config, network, repayerRoutes); + if (!config.CCTP) { + config.CCTP = { + TokenMessenger: ZERO_ADDRESS, + MessageTransmitter: ZERO_ADDRESS, + }; + } if (!config.AcrossV3SpokePool) { config.AcrossV3SpokePool = ZERO_ADDRESS; } diff --git a/scripts/deployStandaloneRepayer.ts b/scripts/deployStandaloneRepayer.ts index af88e76..1879677 100644 --- a/scripts/deployStandaloneRepayer.ts +++ b/scripts/deployStandaloneRepayer.ts @@ -37,8 +37,6 @@ export async function main() { assert(isAddress(config.Admin), "Admin must be an address"); assert(config.RepayerCallers.length > 0, "RepayerCallers must not be empty"); config.RepayerCallers.forEach(el => assert(isAddress(el), "Each RepayerCaller must be an address")); - assert(isAddress(config.CCTP.TokenMessenger), "CCTP TokenMessenger must be an address"); - assert(isAddress(config.CCTP.MessageTransmitter), "CCTP MessageTransmitter must be an address"); assert(isAddress(config.WrappedNativeToken), "WrappedNativeToken must be an address"); const repayerRoutes: {Pool: string, Domain: Network, Provider: Provider, SupportsAllTokens: boolean}[] = []; @@ -55,6 +53,12 @@ export async function main() { } } + if (!config.CCTP) { + config.CCTP = { + TokenMessenger: ZERO_ADDRESS, + MessageTransmitter: ZERO_ADDRESS, + }; + } if (!config.AcrossV3SpokePool) { config.AcrossV3SpokePool = ZERO_ADDRESS; } diff --git a/scripts/upgradeRebalancer.ts b/scripts/upgradeRebalancer.ts index bd71bbe..71ad043 100644 --- a/scripts/upgradeRebalancer.ts +++ b/scripts/upgradeRebalancer.ts @@ -4,7 +4,7 @@ import hre from "hardhat"; import {isAddress} from "ethers"; import {getVerifier, upgradeProxyX, getHardhatNetworkConfig, getNetworkConfig} from "./helpers"; import {getDeployProxyXAddress} from "../test/helpers"; -import {isSet, assert, DomainSolidity} from "./common"; +import {isSet, assert, DomainSolidity, ZERO_ADDRESS} from "./common"; import {Rebalancer} from "../typechain-types"; import {Network, NetworkConfig} from "../network.config"; @@ -26,8 +26,12 @@ export async function main() { } assert(isAddress(config.USDC), "USDC must be an address"); - assert(isAddress(config.CCTP.TokenMessenger), "CCTP TokenMessenger must be an address"); - assert(isAddress(config.CCTP.MessageTransmitter), "CCTP MessageTransmitter must be an address"); + if (!config.CCTP) { + config.CCTP = { + TokenMessenger: ZERO_ADDRESS, + MessageTransmitter: ZERO_ADDRESS, + }; + } const rebalancerAddress = await getDeployProxyXAddress("Rebalancer"); const rebalancerVersion = config.IsTest ? "TestRebalancer" : "Rebalancer"; diff --git a/scripts/upgradeRepayer.ts b/scripts/upgradeRepayer.ts index 0c1d291..bd793e8 100644 --- a/scripts/upgradeRepayer.ts +++ b/scripts/upgradeRepayer.ts @@ -26,9 +26,13 @@ export async function main() { } assert(isAddress(config.USDC), "USDC must be an address"); - assert(isAddress(config.CCTP.TokenMessenger), "CCTP TokenMessenger must be an address"); - assert(isAddress(config.CCTP.MessageTransmitter), "CCTP MessageTransmitter must be an address"); assert(isAddress(config.WrappedNativeToken), "WrappedNativeToken must be an address"); + if (!config.CCTP) { + config.CCTP = { + TokenMessenger: ZERO_ADDRESS, + MessageTransmitter: ZERO_ADDRESS, + }; + } if (!config.AcrossV3SpokePool) { config.AcrossV3SpokePool = ZERO_ADDRESS; }