diff --git a/packages/boba/contracts/contracts/lzTokenBridge/AltL1Bridge.sol b/packages/boba/contracts/contracts/lzTokenBridge/AltL1Bridge.sol index 66da3f8d57..dc553f0618 100644 --- a/packages/boba/contracts/contracts/lzTokenBridge/AltL1Bridge.sol +++ b/packages/boba/contracts/contracts/lzTokenBridge/AltL1Bridge.sol @@ -34,6 +34,9 @@ import "./lzApp/NonblockingLzApp.sol"; uint256 public transferredAmount; uint256 public transferTimestampCheckPoint; + // Map the L2 token to the L1 token to limit token pairs. + mapping(address => address) public tokenPairs; + // Note: Specify the _lzEndpoint on this layer, _dstChainId is not the actual evm chainIds, but the layerZero // proprietary ones, pass the chainId of the destination for _dstChainId function initialize(address _lzEndpoint, uint16 _dstChainId, address _ethBridgeAddress) public initializer { @@ -85,6 +88,8 @@ import "./lzApp/NonblockingLzApp.sol"; bytes calldata _data ) internal { require(_to != address(0), "_to cannot be zero address"); + require(tokenPairs[_l2Token] != address(0), "token pair not registered"); + require(_data.length < 100, "data too long"); // check if the total amount transferred is smaller than the maximum amount of tokens can be transferred in 24 hours // if it's out of 24 hours, reset the transferred amount to 0 and set the transferTimestampCheckPoint to the current time @@ -185,6 +190,14 @@ import "./lzApp/NonblockingLzApp.sol"; * Admin * **************/ + function registerTokenPair(address _l1Token, address _l2Token) external onlyOwner { + require(_l1Token != address(0) && _l2Token != address(0), "token addresses cannot be zero address"); + require(tokenPairs[_l2Token] == address(0), "token pair already registered"); + tokenPairs[_l2Token] = _l1Token; + + emit TokenPairRegistered(_l1Token, _l2Token); + } + function setDstChainId(uint16 _dstChainId) external onlyOwner { dstChainId = _dstChainId; } diff --git a/packages/boba/contracts/contracts/lzTokenBridge/EthBridge.sol b/packages/boba/contracts/contracts/lzTokenBridge/EthBridge.sol index abd8b1938f..bf61b96099 100644 --- a/packages/boba/contracts/contracts/lzTokenBridge/EthBridge.sol +++ b/packages/boba/contracts/contracts/lzTokenBridge/EthBridge.sol @@ -35,6 +35,9 @@ import "./lzApp/NonblockingLzApp.sol"; // Maps L1 token to wrapped token on alt l1 to balance of the L1 token deposited mapping(address => mapping(address => uint256)) public deposits; + // Map the L1 token to the L2 token to limit token pairs. + mapping(address => address) public tokenPairs; + // Note: Specify the _lzEndpoint on this layer, _dstChainId is not the actual evm chainIds, but the layerZero // proprietary ones, pass the chainId of the destination for _dstChainId function initialize(address _lzEndpoint, uint16 _dstChainId, address _altL1BridgeAddress) public initializer { @@ -99,6 +102,8 @@ import "./lzApp/NonblockingLzApp.sol"; bytes calldata _data ) internal { require(_to != address(0), "_to cannot be zero address"); + require(tokenPairs[_l1Token] == _l2Token, "Token pair not registered"); + require(_data.length < 100, "data too long"); // check if the total amount transferred is smaller than the maximum amount of tokens can be transferred in 24 hours // if it's out of 24 hours, reset the transferred amount to 0 and set the transferTimestampCheckPoint to the current time @@ -172,6 +177,14 @@ import "./lzApp/NonblockingLzApp.sol"; * Admin * **************/ + function registerTokenPair(address _l1Token, address _l2Token) external onlyOwner() { + require(_l1Token != address(0) && _l2Token != address(0), "Token addresses cannot be zero address"); + require(tokenPairs[_l1Token] == address(0), "Token pair already registered"); + tokenPairs[_l1Token] = _l2Token; + + emit TokenPairRegistered(_l1Token, _l2Token); + } + function setDstChainId(uint16 _dstChainId) external onlyOwner { dstChainId = _dstChainId; } diff --git a/packages/boba/contracts/contracts/lzTokenBridge/interfaces/IAltL1Bridge.sol b/packages/boba/contracts/contracts/lzTokenBridge/interfaces/IAltL1Bridge.sol index b41ccb5fda..3da1d908d3 100644 --- a/packages/boba/contracts/contracts/lzTokenBridge/interfaces/IAltL1Bridge.sol +++ b/packages/boba/contracts/contracts/lzTokenBridge/interfaces/IAltL1Bridge.sol @@ -20,6 +20,11 @@ interface IAltL1Bridge { bytes _data ); + event TokenPairRegistered( + address indexed _l1Token, + address indexed _l2Token + ); + function withdraw( address _l2Token, uint256 _amount, @@ -36,4 +41,4 @@ interface IAltL1Bridge { bytes memory _adapterParams, bytes calldata _data ) external payable; -} \ No newline at end of file +} diff --git a/packages/boba/contracts/contracts/lzTokenBridge/interfaces/IEthBridge.sol b/packages/boba/contracts/contracts/lzTokenBridge/interfaces/IEthBridge.sol index 951a55c1dd..7f94347378 100644 --- a/packages/boba/contracts/contracts/lzTokenBridge/interfaces/IEthBridge.sol +++ b/packages/boba/contracts/contracts/lzTokenBridge/interfaces/IEthBridge.sol @@ -20,6 +20,11 @@ interface IEthBridge { bytes _data ); + event TokenPairRegistered( + address indexed _l1Token, + address indexed _l2Token + ); + function depositERC20( address _l1Token, address _l2Token, @@ -38,4 +43,4 @@ interface IEthBridge { bytes memory _adapterParams, bytes calldata _data ) external payable; -} \ No newline at end of file +} diff --git a/packages/boba/contracts/hardhat.config.ts b/packages/boba/contracts/hardhat.config.ts index 78627cadf9..9d38f13b9e 100644 --- a/packages/boba/contracts/hardhat.config.ts +++ b/packages/boba/contracts/hardhat.config.ts @@ -243,7 +243,8 @@ const config: HardhatUserConfig = { network: 'snowtrace', chainId: 43114, urls: { - apiURL: 'https://api.snowtrace.io/api', + apiURL: + 'https://api.routescan.io/v2/network/mainnet/evm/43114/etherscan/api', browserURL: 'https://snowtrace.io', }, }, diff --git a/packages/boba/register/addresses/layerZeroMainnet.json b/packages/boba/register/addresses/layerZeroMainnet.json index 4d37610845..3ee0a39972 100644 --- a/packages/boba/register/addresses/layerZeroMainnet.json +++ b/packages/boba/register/addresses/layerZeroMainnet.json @@ -27,18 +27,18 @@ "Proxy__EthBridgeToFantom": "0x9DD4202AA5ee9625d1eaa671E2294014dd434E7E", "Proxy__EthBridgeToAvalanche": "0xB0003eB166654f7e57c0463F8D1a438eB238c490", "Proxy__EthBridgeToMoonbeam": "0x6F537839714761388B6d7ED61Bc09579d5dA2F41", - "EthBridgeToBNB": "0x5d7824051Ea90F05eC1c6EcfEF05d5234B59040F", - "EthBridgeToFantom": "0xd5c567aC6571aB35568A8E8C73470dFf8Eed939e", - "EthBridgeToAvalanche": "0x51C3db474B023e4924133F36152f40a7b6E27f3F", - "EthBridgeToMoonbeam": "0x6482767251d24f309C0C9985E2EA1262465400dE", + "EthBridgeToBNB": "0x2230C37Cf0B8b88b3e14CcD849b178Bb68e92cD5", + "EthBridgeToFantom": "0xEe67e593539723CaC84C6662d99C9B772b3357Cb", + "EthBridgeToAvalanche": "0x8c24Ee8de079D4844b731432B2BA33191BF13A78", + "EthBridgeToMoonbeam": "0xC61CE1Ca4ca7BE5fC0f766970eE23B4E82537020", "Proxy__BNBBridgeToEth": "0x819FF4d9215C9dAC76f5eC676b1355973157eBBa", "Proxy__FantomBridgeToEth": "0x409e3693A23D4331F613c36f6D5f439a5b9834e8", "Proxy__AvalancheBridgeToEth": "0x351F4853A0E94DB055ed6ad5DF1b3590791c1F71", "Proxy__MoonbeamBridgeToEth": "0x9F868333DB1720Fb1412AFfb1AeF47e8C6cFc8c3", - "BNBBridgeToEth": "0x62C1275bf5484d940BF46d1fCC1e1Ad5DbdD5AE5", - "FantomBridgeToEth": "0x2164dFc94E0f2EE6C2982045950ed052298D12a0", - "AvalancheBridgeToEth": "0xBFcB8A6eD80Ef99a5265B72fdC87f4B4dAA598D3", - "MoonbeamBridgeToEth": "0x05469d879dF44cD83f6923Be12f46E2871dA2DAf", + "BNBBridgeToEth": "0xdCb7039A3BAd9C202487790b243410D590eF101A", + "FantomBridgeToEth": "0xAC441a71134197d8746dA64B5866b41c33AB3557", + "AvalancheBridgeToEth": "0x9d761B117bB0bA653a5E230b7f2EaBE9Ec9Ff6Bf", + "MoonbeamBridgeToEth": "0x98e63Ee8afbBe1CDE82Ba163Ae37Ed0b6Ef04f2c", "Eth_TK_BOBA": "0x42bbfa2e77757c645eeaad1655e0911a7553efbc", "BNB_TK_BOBA": "0xE0DB679377A0F5Ae2BaE485DE475c9e1d8A4607D", "Avalanche_TK_BOBA": "0x3cD790449CF7D187a143d4Bd7F4654d4f2403e02", @@ -47,30 +47,30 @@ }, "BNB": { "Proxy__EthBridgeToBNB": "0x1A36E24D61BC1aDa68C21C2Da1aD53EaB8E03e55", - "EthBridgeToBNB": "0x5d7824051Ea90F05eC1c6EcfEF05d5234B59040F", + "EthBridgeToBNB": "0x2230C37Cf0B8b88b3e14CcD849b178Bb68e92cD5", "Proxy__BNBBridgeToEth": "0x819FF4d9215C9dAC76f5eC676b1355973157eBBa", - "BNBBridgeToEth": "0x62C1275bf5484d940BF46d1fCC1e1Ad5DbdD5AE5", + "BNBBridgeToEth": "0xdCb7039A3BAd9C202487790b243410D590eF101A", "BNB_TK_BOBA": "0xE0DB679377A0F5Ae2BaE485DE475c9e1d8A4607D" }, "Fantom": { "Proxy__EthBridgeToFantom": "0x9DD4202AA5ee9625d1eaa671E2294014dd434E7E", - "EthBridgeToFantom": "0xd5c567aC6571aB35568A8E8C73470dFf8Eed939e", + "EthBridgeToFantom": "0xEe67e593539723CaC84C6662d99C9B772b3357Cb", "Proxy__FantomBridgeToEth": "0x409e3693A23D4331F613c36f6D5f439a5b9834e8", - "FantomBridgeToEth": "0x2164dFc94E0f2EE6C2982045950ed052298D12a0", + "FantomBridgeToEth": "0xAC441a71134197d8746dA64B5866b41c33AB3557", "Fantom_TK_BOBA": "0x4389b230D15119c347B9E8BEA6d930A21aaDF6BA" }, "Avalanche": { "Proxy__EthBridgeToAvalanche": "0xB0003eB166654f7e57c0463F8D1a438eB238c490", - "EthBridgeToAvalanche": "0x51C3db474B023e4924133F36152f40a7b6E27f3F", + "EthBridgeToAvalanche": "0x8c24Ee8de079D4844b731432B2BA33191BF13A78", "Proxy__AvalancheBridgeToEth": "0x351F4853A0E94DB055ed6ad5DF1b3590791c1F71", - "AvalancheBridgeToEth": "0xBFcB8A6eD80Ef99a5265B72fdC87f4B4dAA598D3", + "AvalancheBridgeToEth": "0x9d761B117bB0bA653a5E230b7f2EaBE9Ec9Ff6Bf", "Avalanche_TK_BOBA": "0x3cD790449CF7D187a143d4Bd7F4654d4f2403e02" }, "Moonbeam": { "Proxy__EthBridgeToMoonbeam": "0x6F537839714761388B6d7ED61Bc09579d5dA2F41", - "EthBridgeToMoonbeam": "0x6482767251d24f309C0C9985E2EA1262465400dE", + "EthBridgeToMoonbeam": "0xC61CE1Ca4ca7BE5fC0f766970eE23B4E82537020", "Proxy__MoonbeamBridgeToEth": "0x9F868333DB1720Fb1412AFfb1AeF47e8C6cFc8c3", - "MoonbeamBridgeToEth": "0x05469d879dF44cD83f6923Be12f46E2871dA2DAf", + "MoonbeamBridgeToEth": "0x98e63Ee8afbBe1CDE82Ba163Ae37Ed0b6Ef04f2c", "Moonbeam_TK_BOBA": "0x18D17A9fD652D7d6a59903E23792ab97F832Ed6C" } }