From d92b5a7139bf3f04679262c13907a40b60b2ff0e Mon Sep 17 00:00:00 2001 From: ss-sonic Date: Fri, 20 Sep 2024 10:23:49 +0530 Subject: [PATCH] add router bridge support --- src/apps/nitro/RouterNitroApp.sol | 52 ++++++ src/apps/nitro/RouterNitroAppBeacon.sol | 23 ++- src/interfaces/nitro/IRouterNitroApp.sol | 26 ++- .../nitro/IRouterNitroAppBeacon.sol | 16 +- src/interfaces/nitro/IRouterNitroGateway.sol | 166 ++++++++++++++++++ 5 files changed, 278 insertions(+), 5 deletions(-) diff --git a/src/apps/nitro/RouterNitroApp.sol b/src/apps/nitro/RouterNitroApp.sol index 15b08e7..8d8b0ed 100644 --- a/src/apps/nitro/RouterNitroApp.sol +++ b/src/apps/nitro/RouterNitroApp.sol @@ -69,6 +69,29 @@ contract RouterNitroApp is AppAccountBase, IRouterNitroApp { gateway.iDeposit{ value: msg.value }(depositData, destToken, recipient); } + /** + * @dev This function is used to bridge mintable assets from one network to another. + * @param transferPayload The data related to the transfer. + */ + function bridgeMintableAssets(IRouterNitroGateway.TransferPayload memory transferPayload) + external + payable + nonReentrant + requiresAuthorizedOperationsParty + { + // Get the app beacon instance + IRouterNitroAppBeacon appBeacon = _getAppBeacon(); + + // Get the gateway instance from the app beacon + IRouterNitroGateway gateway = IRouterNitroGateway(appBeacon.routerAssetBridgeGateway()); + + // Approve the gateway to spend the source token on behalf of the contract + IERC20(transferPayload.srcTokenAddress).approve(address(gateway), transferPayload.srcTokenAmount); + + // Call the transferToken function on the gateway + gateway.transferToken{ value: msg.value }(transferPayload); + } + /** * @dev This function is used to update the bridge transaction data. * @param srcToken The source token address. @@ -131,6 +154,35 @@ contract RouterNitroApp is AppAccountBase, IRouterNitroApp { gateway.iDepositMessage{ value: msg.value }(depositData, destToken, recipient, message); } + /** + * @dev This function is used to bridge mintable assets with an instruction from one network to another. + * @param transferPayload The data related to the transfer. + * @param destGasLimit The destination gas limit. + * @param instruction The instruction to be sent along with the transaction. + */ + function bridgeMintableAssetsWithInstruction( + IRouterNitroGateway.TransferPayload memory transferPayload, + uint64 destGasLimit, + bytes calldata instruction + ) + external + payable + nonReentrant + requiresAuthorizedOperationsParty + { + // Get the app beacon instance + IRouterNitroAppBeacon appBeacon = _getAppBeacon(); + + // Get the gateway instance from the app beacon + IRouterNitroGateway gateway = IRouterNitroGateway(appBeacon.routerAssetBridgeGateway()); + + // Approve the gateway to spend the source token on behalf of the contract + IERC20(transferPayload.srcTokenAddress).approve(address(gateway), transferPayload.srcTokenAmount); + + // Call the transferTokenWithInstruction function on the gateway + gateway.transferTokenWithInstruction{ value: msg.value }(transferPayload, destGasLimit, instruction); + } + /** * @dev Returns the beacon contract for the Curve StableSwap app. * @return The beacon contract for the Curve StableSwap app. diff --git a/src/apps/nitro/RouterNitroAppBeacon.sol b/src/apps/nitro/RouterNitroAppBeacon.sol index 0b9f8ac..3c152bd 100644 --- a/src/apps/nitro/RouterNitroAppBeacon.sol +++ b/src/apps/nitro/RouterNitroAppBeacon.sol @@ -19,18 +19,39 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.21; +// Importing the base class for application beacons import { AppBeaconBase } from "src/apps/base/AppBeaconBase.sol"; +/** + * @title RouterNitroAppBeacon + * @dev This contract extends AppBeaconBase to provide a beacon for the RouterNitro application. + * The beacon points to the latest implementation of the application and stores addresses for the RouterNitroGateway and + * RouterAssetBridgeGateway. + */ contract RouterNitroAppBeacon is AppBeaconBase { + // Address of the RouterNitroGateway contract address public immutable routerNitroGateway; + // Address of the RouterAssetBridgeGateway contract + address public immutable routerAssetBridgeGateway; + /** + * @dev Constructs a new RouterNitroAppBeacon contract. + * @param _owner The owner of the contract. + * @param _latestAppImplementation The address of the latest implementation of the RouterNitro application. + * @param _routerNitroGateway The address of the RouterNitroGateway contract. + * @param _routerAssetBridgeGateway The address of the RouterAssetBridgeGateway contract. + */ constructor( address _owner, address _latestAppImplementation, - address _routerNitroGateway + address _routerNitroGateway, + address _routerAssetBridgeGateway ) + // Call the constructor of the base class AppBeaconBase(_owner, _latestAppImplementation, "RouterNitro") { + // Initialize the RouterNitroGateway and RouterAssetBridgeGateway addresses routerNitroGateway = _routerNitroGateway; + routerAssetBridgeGateway = _routerAssetBridgeGateway; } } diff --git a/src/interfaces/nitro/IRouterNitroApp.sol b/src/interfaces/nitro/IRouterNitroApp.sol index 9931660..6061eb8 100644 --- a/src/interfaces/nitro/IRouterNitroApp.sol +++ b/src/interfaces/nitro/IRouterNitroApp.sol @@ -3,9 +3,17 @@ pragma solidity >=0.8.21; import { IRouterNitroGateway } from "../nitro/IRouterNitroGateway.sol"; -/// @title Interface for handler contracts that support deposits and deposit executions. -/// @author Router Protocol. +/** + * @title IRouterNitroApp + * @dev Interface for handler contracts that support deposits and deposit executions. + */ interface IRouterNitroApp { + /** + * @dev Bridge assets from the source chain to the destination chain. + * @param depositData The deposit data containing the necessary information for the bridge transaction. + * @param destToken The destination token address. + * @param recipient The recipient address on the destination chain. + */ function bridgeAssets( IRouterNitroGateway.DepositData memory depositData, bytes memory destToken, @@ -14,6 +22,13 @@ interface IRouterNitroApp { external payable; + /** + * @dev Update the bridge transaction data. + * @param srcToken The source token address. + * @param feeAmount The fee amount for the bridge transaction. + * @param depositId The deposit ID. + * @param initiatewithdrawal Flag indicating whether to initiate a withdrawal on the destination chain. + */ function updateBridgeTxnData( address srcToken, uint256 feeAmount, @@ -23,6 +38,13 @@ interface IRouterNitroApp { external payable; + /** + * @dev Bridge assets from the source chain to the destination chain with a message. + * @param depositData The deposit data containing the necessary information for the bridge transaction. + * @param destToken The destination token address. + * @param recipient The recipient address on the destination chain. + * @param message The message to include in the bridge transaction. + */ function bridgeAssetsWithMessage( IRouterNitroGateway.DepositData memory depositData, bytes memory destToken, diff --git a/src/interfaces/nitro/IRouterNitroAppBeacon.sol b/src/interfaces/nitro/IRouterNitroAppBeacon.sol index 5a814ee..019a9ff 100644 --- a/src/interfaces/nitro/IRouterNitroAppBeacon.sol +++ b/src/interfaces/nitro/IRouterNitroAppBeacon.sol @@ -1,8 +1,20 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.21; -/// @title Interface for handler contracts that support deposits and deposit executions. -/// @author Router Protocol. +/** + * @title IRouterNitroAppBeacon + * @dev Interface for the Nitro App Beacon Router. + */ interface IRouterNitroAppBeacon { + /** + * @dev Returns the address of the Nitro Gateway Router. + * @return The address of the Nitro Gateway Router. + */ function routerNitroGateway() external view returns (address); + + /** + * @dev Returns the address of the Asset Bridge Gateway Router. + * @return The address of the Asset Bridge Gateway Router. + */ + function routerAssetBridgeGateway() external view returns (address); } diff --git a/src/interfaces/nitro/IRouterNitroGateway.sol b/src/interfaces/nitro/IRouterNitroGateway.sol index aa1c2c0..4c6fb83 100644 --- a/src/interfaces/nitro/IRouterNitroGateway.sol +++ b/src/interfaces/nitro/IRouterNitroGateway.sol @@ -4,6 +4,18 @@ pragma solidity >=0.8.21; /// @title Interface for handler contracts that support deposits and deposit executions. /// @author Router Protocol. interface IRouterNitroGateway { + /** + * @dev Emitted when funds are deposited. + * @param partnerId The ID of the partner. + * @param amount The amount of funds deposited. + * @param destChainIdBytes The destination chain ID. + * @param destAmount The amount of funds on the destination chain. + * @param depositId The ID of the deposit. + * @param srcToken The address of the source token. + * @param depositor The address of the depositor. + * @param recipient The recipient of the funds. + * @param destToken The address of the destination token. + */ event FundsDeposited( uint256 partnerId, uint256 amount, @@ -16,6 +28,16 @@ interface IRouterNitroGateway { bytes destToken ); + /** + * @dev Emitted when iUSDC is deposited. + * @param partnerId The ID of the partner. + * @param amount The amount of iUSDC deposited. + * @param destChainIdBytes The destination chain ID. + * @param usdcNonce The nonce of the iUSDC deposit. + * @param srcToken The address of the source token. + * @param recipient The recipient of the funds. + * @param depositor The address of the depositor. + */ event iUSDCDeposited( uint256 partnerId, uint256 amount, @@ -26,6 +48,19 @@ interface IRouterNitroGateway { address depositor ); + /** + * @dev Emitted when funds are deposited with a message. + * @param partnerId The ID of the partner. + * @param amount The amount of funds deposited. + * @param destChainIdBytes The destination chain ID. + * @param destAmount The amount of funds on the destination chain. + * @param depositId The ID of the deposit. + * @param srcToken The address of the source token. + * @param recipient The recipient of the funds. + * @param depositor The address of the depositor. + * @param destToken The address of the destination token. + * @param message The message associated with the deposit. + */ event FundsDepositedWithMessage( uint256 partnerId, uint256 amount, @@ -38,8 +73,24 @@ interface IRouterNitroGateway { bytes destToken, bytes message ); + + /** + * @dev Emitted when funds are paid. + * @param messageHash The hash of the message. + * @param forwarder The address of the forwarder. + * @param nonce The nonce of the payment. + */ event FundsPaid(bytes32 messageHash, address forwarder, uint256 nonce); + /** + * @dev Emitted when deposit information is updated. + * @param srcToken The address of the source token. + * @param feeAmount The amount of the fee. + * @param depositId The ID of the deposit. + * @param eventNonce The nonce of the event. + * @param initiatewithdrawal Flag indicating if withdrawal should be initiated. + * @param depositor The address of the depositor. + */ event DepositInfoUpdate( address srcToken, uint256 feeAmount, @@ -49,14 +100,36 @@ interface IRouterNitroGateway { address depositor ); + /** + * @dev Emitted when funds are paid with a message. + * @param messageHash The hash of the message. + * @param forwarder The address of the forwarder. + * @param nonce The nonce of the payment. + * @param execFlag Flag indicating if execution should be performed. + * @param execData The execution data. + */ event FundsPaidWithMessage(bytes32 messageHash, address forwarder, uint256 nonce, bool execFlag, bytes execData); + /** + * @dev Struct representing the destination details. + * @param domainId The ID of the domain. + * @param fee The fee amount. + * @param isSet Flag indicating if the destination is set. + */ struct DestDetails { uint32 domainId; uint256 fee; bool isSet; } + /** + * @dev Struct representing the relay data. + * @param amount The amount of funds. + * @param srcChainId The source chain ID. + * @param depositId The ID of the deposit. + * @param destToken The address of the destination token. + * @param recipient The recipient of the funds. + */ struct RelayData { uint256 amount; bytes32 srcChainId; @@ -65,6 +138,15 @@ interface IRouterNitroGateway { address recipient; } + /** + * @dev Struct representing the relay data with a message. + * @param amount The amount of funds. + * @param srcChainId The source chain ID. + * @param depositId The ID of the deposit. + * @param destToken The address of the destination token. + * @param recipient The recipient of the funds. + * @param message The message associated with the relay. + */ struct RelayDataMessage { uint256 amount; bytes32 srcChainId; @@ -74,6 +156,15 @@ interface IRouterNitroGateway { bytes message; } + /** + * @dev Struct representing the deposit data. + * @param partnerId The ID of the partner. + * @param amount The amount of funds. + * @param destAmount The amount of funds on the destination chain. + * @param srcToken The address of the source token. + * @param refundRecipient The recipient of the refund. + * @param destChainIdBytes The destination chain ID. + */ struct DepositData { uint256 partnerId; uint256 amount; @@ -83,6 +174,29 @@ interface IRouterNitroGateway { bytes32 destChainIdBytes; } + /** + * @dev Struct representing the transfer payload. + * @param destChainIdBytes The destination chain ID. + * @param srcTokenAddress The address of the source token. + * @param srcTokenAmount The amount of the source token. + * @param recipient The recipient of the funds. + * @param partnerId The ID of the partner. + */ + struct TransferPayload { + bytes32 destChainIdBytes; + address srcTokenAddress; + uint256 srcTokenAmount; + bytes recipient; + uint256 partnerId; + } + + /** + * @dev Deposits iUSDC. + * @param partnerId The ID of the partner. + * @param destChainIdBytes The destination chain ID. + * @param recipient The recipient of the funds. + * @param amount The amount of iUSDC to deposit. + */ function iDepositUSDC( uint256 partnerId, bytes32 destChainIdBytes, @@ -92,6 +206,12 @@ interface IRouterNitroGateway { external payable; + /** + * @dev Deposits funds. + * @param depositData The deposit data. + * @param destToken The address of the destination token. + * @param recipient The recipient of the funds. + */ function iDeposit( DepositData memory depositData, bytes memory destToken, @@ -100,6 +220,13 @@ interface IRouterNitroGateway { external payable; + /** + * @dev Updates deposit information. + * @param srcToken The address of the source token. + * @param feeAmount The amount of the fee. + * @param depositId The ID of the deposit. + * @param initiatewithdrawal Flag indicating if withdrawal should be initiated. + */ function iDepositInfoUpdate( address srcToken, uint256 feeAmount, @@ -109,6 +236,13 @@ interface IRouterNitroGateway { external payable; + /** + * @dev Deposits funds with a message. + * @param depositData The deposit data. + * @param destToken The address of the destination token. + * @param recipient The recipient of the funds. + * @param message The message associated with the deposit. + */ function iDepositMessage( DepositData memory depositData, bytes memory destToken, @@ -118,9 +252,41 @@ interface IRouterNitroGateway { external payable; + /** + * @dev Relays funds. + * @param relayData The relay data. + */ function iRelay(RelayData memory relayData) external payable; + /** + * @dev Returns the deposit nonce. + * @return The deposit nonce. + */ function depositNonce() external view returns (uint256); + /** + * @dev Relays funds with a message. + * @param relayData The relay data. + */ function iRelayMessage(RelayDataMessage memory relayData) external payable; + + /** + * @dev Transfers tokens. + * @param transferPayload The transfer payload. + */ + function transferToken(TransferPayload memory transferPayload) external payable; + + /** + * @dev Transfers tokens with instruction. + * @param transferPayload The transfer payload. + * @param destGasLimit The destination gas limit. + * @param instruction The instruction data. + */ + function transferTokenWithInstruction( + TransferPayload memory transferPayload, + uint64 destGasLimit, + bytes calldata instruction + ) + external + payable; }