Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
CCIPAdapter
Compiler Version
v0.8.10+commit.fc410830
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {BaseAdapter, IBaseAdapter} from '../BaseAdapter.sol'; import {ICCIPAdapter, IRouterClient} from './ICCIPAdapter.sol'; import {IAny2EVMMessageReceiver, Client} from './interfaces/IAny2EVMMessageReceiver.sol'; import {IERC165} from './interfaces/IERC165.sol'; import {MainnetChainIds, TestnetChainIds} from '../../libs/ChainIds.sol'; import {Errors} from '../../libs/Errors.sol'; /** * @title CCIPAdapter * @author BGD Labs * @notice CCIP bridge adapter. Used to send and receive messages cross chain * @dev it uses the eth balance of CrossChainController contract to pay for message bridging as the method to bridge is called via delegate call */ contract CCIPAdapter is ICCIPAdapter, BaseAdapter, IAny2EVMMessageReceiver, IERC165 { /// @inheritdoc ICCIPAdapter IRouterClient public immutable CCIP_ROUTER; // (chain -> origin forwarder address) saves for every chain the address that can forward messages to this adapter mapping(uint256 => address) internal _trustedRemotes; /** * @notice only calls from the set router are accepted. */ modifier onlyRouter() { require(msg.sender == address(CCIP_ROUTER), Errors.CALLER_NOT_CCIP_ROUTER); _; } /** * @param crossChainController address of the cross chain controller that will use this bridge adapter * @param ccipRouter ccip entry point address * @param trustedRemotes list of remote configurations to set as trusted */ constructor( address crossChainController, address ccipRouter, TrustedRemotesConfig[] memory trustedRemotes ) BaseAdapter(crossChainController) { require(ccipRouter != address(0), Errors.CCIP_ROUTER_CANT_BE_ADDRESS_0); CCIP_ROUTER = IRouterClient(ccipRouter); _updateTrustedRemotes(trustedRemotes); } /// @inheritdoc ICCIPAdapter function getTrustedRemoteByChainId(uint256 chainId) external view returns (address) { return _trustedRemotes[chainId]; } /// @inheritdoc IERC165 function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { return interfaceId == type(IAny2EVMMessageReceiver).interfaceId || interfaceId == type(IERC165).interfaceId; } /// @inheritdoc IBaseAdapter function forwardMessage( address receiver, uint256 gasLimit, uint256 destinationChainId, bytes memory message ) external { uint64 nativeDestinationChainId = infraToNativeChainId(destinationChainId); require( CCIP_ROUTER.isChainSupported(nativeDestinationChainId), Errors.DESTINATION_CHAIN_ID_NOT_SUPPORTED ); require(receiver != address(0), Errors.RECEIVER_NOT_SET); Client.EVMExtraArgsV1 memory evmExtraArgs = Client.EVMExtraArgsV1({ gasLimit: gasLimit, strict: false }); bytes memory extraArgs = Client._argsToBytes(evmExtraArgs); Client.EVM2AnyMessage memory payload = Client.EVM2AnyMessage({ receiver: abi.encode(receiver), data: message, tokenAmounts: new Client.EVMTokenAmount[](0), feeToken: address(0), // We leave the feeToken empty indicating we'll pay with native gas tokens., extraArgs: extraArgs }); uint256 clFee = CCIP_ROUTER.getFee(nativeDestinationChainId, payload); require(address(this).balance >= clFee, Errors.NOT_ENOUGH_VALUE_TO_PAY_BRIDGE_FEES); bytes32 messageId = CCIP_ROUTER.ccipSend{value: clFee}(nativeDestinationChainId, payload); emit MessageForwarded(receiver, nativeDestinationChainId, messageId, message); } /// @inheritdoc IAny2EVMMessageReceiver function ccipReceive(Client.Any2EVMMessage calldata message) external onlyRouter { address srcAddress = abi.decode(message.sender, (address)); uint256 originChainId = nativeToInfraChainId(message.sourceChainId); require(originChainId != 0, Errors.INCORRECT_ORIGIN_CHAIN_ID); require(_trustedRemotes[originChainId] == srcAddress, Errors.REMOTE_NOT_TRUSTED); _registerReceivedMessage(message.data, originChainId); emit CCIPPayloadProcessed(originChainId, srcAddress, message.data); } /// @inheritdoc ICCIPAdapter function nativeToInfraChainId(uint64 nativeChainId) public pure returns (uint256) { if (nativeChainId == uint64(MainnetChainIds.ETHEREUM)) { return MainnetChainIds.ETHEREUM; } else if (nativeChainId == uint64(MainnetChainIds.AVALANCHE)) { return MainnetChainIds.AVALANCHE; } else if (nativeChainId == uint64(MainnetChainIds.POLYGON)) { return MainnetChainIds.POLYGON; } else if (nativeChainId == uint64(MainnetChainIds.ARBITRUM)) { return MainnetChainIds.ARBITRUM; } else if (nativeChainId == uint64(MainnetChainIds.OPTIMISM)) { return MainnetChainIds.OPTIMISM; } else if (nativeChainId == uint64(MainnetChainIds.FANTOM)) { return MainnetChainIds.FANTOM; } else if (nativeChainId == uint64(MainnetChainIds.HARMONY)) { return MainnetChainIds.HARMONY; } else if (nativeChainId == uint64(TestnetChainIds.ETHEREUM_GOERLI)) { return TestnetChainIds.ETHEREUM_GOERLI; } else if (nativeChainId == uint64(TestnetChainIds.AVALANCHE_FUJI)) { return TestnetChainIds.AVALANCHE_FUJI; } else if (nativeChainId == uint64(TestnetChainIds.OPTIMISM_GOERLI)) { return TestnetChainIds.OPTIMISM_GOERLI; } else if (nativeChainId == uint64(TestnetChainIds.POLYGON_MUMBAI)) { return TestnetChainIds.POLYGON_MUMBAI; } else if (nativeChainId == uint64(TestnetChainIds.ETHEREUM_SEPOLIA)) { return TestnetChainIds.ETHEREUM_SEPOLIA; } else { return 0; } } /// @inheritdoc ICCIPAdapter function infraToNativeChainId(uint256 infraChainId) public pure returns (uint64) { if (infraChainId == MainnetChainIds.ETHEREUM) { return uint64(MainnetChainIds.ETHEREUM); } else if (infraChainId == MainnetChainIds.AVALANCHE) { return uint64(MainnetChainIds.AVALANCHE); } else if (infraChainId == MainnetChainIds.POLYGON) { return uint64(MainnetChainIds.POLYGON); } else if (infraChainId == MainnetChainIds.ARBITRUM) { return uint64(MainnetChainIds.ARBITRUM); } else if (infraChainId == MainnetChainIds.OPTIMISM) { return uint64(MainnetChainIds.OPTIMISM); } else if (infraChainId == MainnetChainIds.FANTOM) { return uint64(MainnetChainIds.FANTOM); } else if (infraChainId == MainnetChainIds.HARMONY) { return uint64(MainnetChainIds.HARMONY); } else if (infraChainId == TestnetChainIds.ETHEREUM_GOERLI) { return uint64(TestnetChainIds.ETHEREUM_GOERLI); } else if (infraChainId == TestnetChainIds.AVALANCHE_FUJI) { return uint64(TestnetChainIds.AVALANCHE_FUJI); } else if (infraChainId == TestnetChainIds.OPTIMISM_GOERLI) { return uint64(TestnetChainIds.OPTIMISM_GOERLI); } else if (infraChainId == TestnetChainIds.POLYGON_MUMBAI) { return uint64(TestnetChainIds.POLYGON_MUMBAI); } else if (infraChainId == TestnetChainIds.ETHEREUM_SEPOLIA) { return uint64(TestnetChainIds.ETHEREUM_SEPOLIA); } else { return uint64(0); } } /** * @notice method to set trusted remotes. These are addresses that are allowed to receive messages from * @param trustedRemotes list of objects with the trusted remotes configurations **/ function _updateTrustedRemotes(TrustedRemotesConfig[] memory trustedRemotes) internal { for (uint256 i = 0; i < trustedRemotes.length; i++) { _trustedRemotes[trustedRemotes[i].originChainId] = trustedRemotes[i].originForwarder; emit SetTrustedRemote(trustedRemotes[i].originChainId, trustedRemotes[i].originForwarder); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import {IBaseAdapter} from './IBaseAdapter.sol'; import {ICrossChainController} from '../interfaces/ICrossChainController.sol'; /** * @title BaseAdapter * @author BGD Labs * @notice base contract implementing the method to route a bridged message to the CrossChainController contract. * @dev All bridge adapters must implement this contract */ abstract contract BaseAdapter is IBaseAdapter { ICrossChainController public immutable CROSS_CHAIN_CONTROLLER; /** * @param crossChainController address of the CrossChainController the bridged messages will be routed to */ constructor(address crossChainController) { CROSS_CHAIN_CONTROLLER = ICrossChainController(crossChainController); } /** * @notice calls CrossChainController to register the bridged payload * @param _payload bytes containing the bridged message * @param originChainId id of the chain where the message originated */ function _registerReceivedMessage(bytes memory _payload, uint256 originChainId) internal { CROSS_CHAIN_CONTROLLER.receiveCrossChainMessage(_payload, originChainId); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IBaseAdapter * @author BGD Labs * @notice interface containing the event and method used in all bridge adapters */ interface IBaseAdapter { /** * @notice method that will bridge the payload to the chain specified * @param receiver address of the receiver contract on destination chain * @param gasLimit amount of the gas limit in wei to use for bridging on receiver side. Each adapter will manage this as needed * @param destinationChainId id of the destination chain in the bridge notation * @param message to send to the specified chain */ function forwardMessage( address receiver, // TODO: this should be renamed as is the bridge adapter on receiving side uint256 gasLimit, uint256 destinationChainId, bytes memory message ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IRouterClient} from './interfaces/IRouterClient.sol'; /** * @title ICCIPAdapter * @author BGD Labs * @notice interface containing the events, objects and method definitions used in the CCIP bridge adapter */ interface ICCIPAdapter { /** * @notice pair of origin address and origin chain * @param originForwarder address of the contract that will send the messages * @param originChainId id of the chain where the trusted remote is from */ struct TrustedRemotesConfig { address originForwarder; uint256 originChainId; } /** * @notice emitted when a payload is forwarded * @param receiver address that will receive the payload * @param destinationChainId id of the chain to bridge the payload * @param messageId CCIP id of the message forwarded * @param message object to be bridged */ event MessageForwarded( address indexed receiver, uint64 indexed destinationChainId, bytes32 indexed messageId, bytes message ); /** * @notice emitted when a message is received and has been correctly processed * @param srcChainId id of the chain where the message originated from * @param srcAddress address that sent the message (origin CrossChainContract) * @param data bridged message */ event CCIPPayloadProcessed(uint256 indexed srcChainId, address indexed srcAddress, bytes data); /** * @notice emitted when a trusted remote is set * @param originChainId id of the chain where the trusted remote is from * @param originForwarder address of the contract that will send the messages */ event SetTrustedRemote(uint256 indexed originChainId, address indexed originForwarder); /** * @notice method to get the CCIP router address * @return adddress of the CCIP router */ function CCIP_ROUTER() external view returns (IRouterClient); /** * @notice method to get the trusted remote address from a specified chain id * @param chainId id of the chain from where to get the trusted remote * @return address of the trusted remote */ function getTrustedRemoteByChainId(uint256 chainId) external view returns (address); /** * @notice method to get infrastructure chain id from bridge native chain id * @param nativeChainId bridge native chain id */ function nativeToInfraChainId(uint64 nativeChainId) external pure returns (uint256); /** * @notice method to get bridge native chain id from native bridge chain id * @param infraChainId infrastructure chain id */ function infraToNativeChainId(uint256 infraChainId) external pure returns (uint64); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {Client} from '../lib/Client.sol'; /// @notice Application contracts that intend to receive messages from /// the router should implement this interface. interface IAny2EVMMessageReceiver { /// @notice Router calls this to deliver a message. /// If this reverts, any token transfers also revert. The message /// will move to a FAILED state and become available for manual execution /// as a retry. Fees already paid are NOT currently refunded (may change). /// @param message CCIP Message /// @dev Note ensure you check the msg.sender is the router function ccipReceive(Client.Any2EVMMessage calldata message) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IERC165 { // @dev Should indicate whether the contract implements IAny2EVMMessageReceiver // e.g. return interfaceId == type(IAny2EVMMessageReceiver).interfaceId // This allows CCIP to check if ccipReceive is available before calling it. // If this returns false, only tokens are transferred to the receiver. // If this returns true, tokens are transferred and ccipReceive is called atomically. // Additionally, if the receiver address does not have code associated with // it at the time of execution (EXTCODESIZE returns 0), only tokens will be transferred. function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // Client library above import {Client} from '../lib/Client.sol'; interface IRouterClient { error UnsupportedDestinationChain(uint64 destinationChainId); /// @dev Sender is not whitelisted error SenderNotAllowed(address sender); error InsufficientFeeTokenAmount(); /// @dev Sent msg.value with a non-empty feeToken error InvalidMsgValue(); /// @notice Checks if the given chain ID is supported for sending/receiving. /// @param chainId The chain to check /// @return supported is true if it is supported, false if not function isChainSupported(uint64 chainId) external view returns (bool supported); /// @notice Gets a list of all supported tokens which can be sent or received /// to/from a given chain id. /// @param chainId The chainId. /// @return tokens The addresses of all tokens that are supported. function getSupportedTokens(uint64 chainId) external view returns (address[] memory tokens); /// @param destinationChainId The destination chain ID /// @param message The cross-chain CCIP message including data and/or tokens /// @return fee returns guaranteed execution fee for the specified message /// delivery to destination chain /// @dev returns 0 fee on invalid message. function getFee( uint64 destinationChainId, Client.EVM2AnyMessage memory message ) external view returns (uint256 fee); /// @notice Request a message to be sent to the destination chain /// @param destinationChainId The destination chain ID /// @param message The cross-chain CCIP message including data and/or tokens /// @return messageId The message ID /// @dev Note if msg.value is larger than the required fee (from getFee) we accept /// the overpayment with no refund. function ccipSend( uint64 destinationChainId, Client.EVM2AnyMessage calldata message ) external payable returns (bytes32 messageId); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library Client { struct EVMTokenAmount { address token; // token address on the local chain uint256 amount; } struct Any2EVMMessage { bytes32 messageId; // MessageId corresponding to ccipSend on source uint64 sourceChainId; bytes sender; // abi.decode(sender) if coming from an EVM chain bytes data; // payload sent in original message EVMTokenAmount[] tokenAmounts; } struct EVM2AnyMessage { bytes receiver; // abi.encode(receiver address) for dest EVM chains bytes data; // Data payload EVMTokenAmount[] tokenAmounts; // Token transfers address feeToken; // Address of feeToken. address(0) means you will send msg.value. bytes extraArgs; // Populate this with _argsToBytes(EVMExtraArgsV1) } // extraArgs will evolve to support new features // bytes4(keccak256("CCIP EVMExtraArgsV1")); bytes4 public constant EVM_EXTRA_ARGS_V1_TAG = 0x97a657c9; struct EVMExtraArgsV1 { uint256 gasLimit; // ATTENTION!!! MAX GAS LIMIT 4M FOR ALPHA TESTING bool strict; // See strict sequencing details below. } function _argsToBytes(EVMExtraArgsV1 memory extraArgs) internal pure returns (bytes memory bts) { return abi.encodeWithSelector(EVM_EXTRA_ARGS_V1_TAG, extraArgs); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import './ICrossChainForwarder.sol'; import './ICrossChainReceiver.sol'; /** * @title ICrossChainController * @author BGD Labs * @notice interface containing the objects, events and methods definitions of the CrossChainController contract */ interface ICrossChainController is ICrossChainForwarder, ICrossChainReceiver { /** * @notice method called to initialize the proxy * @param owner address of the owner of the cross chain controller * @param guardian address of the guardian of the cross chain controller * @param clEmergencyOracle address of the chainlink emergency oracle * @param initialRequiredConfirmations number of confirmations the messages need to be accepted as valid * @param receiverBridgeAdaptersToAllow array of addresses of the bridge adapters that can receive messages * @param forwarderBridgeAdaptersToEnable array specifying for every bridgeAdapter, the destinations it can have * @param sendersToApprove array of addresses to allow as forwarders */ function initialize( address owner, address guardian, address clEmergencyOracle, uint256 initialRequiredConfirmations, address[] memory receiverBridgeAdaptersToAllow, BridgeAdapterConfigInput[] memory forwarderBridgeAdaptersToEnable, address[] memory sendersToApprove ) external; /** * @notice method called to rescue tokens sent erroneously to the contract. Only callable by owner * @param erc20Token address of the token to rescue * @param to address to send the tokens * @param amount of tokens to rescue */ function emergencyTokenTransfer(address erc20Token, address to, uint256 amount) external; /** * @notice method called to rescue ether sent erroneously to the contract. Only callable by owner * @param to address to send the eth * @param amount of eth to rescue */ function emergencyEtherTransfer(address to, uint256 amount) external; /** * @notice method to check if there is a new emergency state, indicated by chainlink emergency oracle. This method is callable by anyone as a new emergency will be determined by the oracle, and this way it will be easier / faster to enter into emergency. * @param newConfirmations number of confirmations necessary for a message to be routed to destination * @param newValidityTimestamp timestamp in seconds indicating the point to where not confirmed messages will be * invalidated. * @param receiverBridgeAdaptersToAllow list of bridge adapter addresses to be allowed to receive messages * @param receiverBridgeAdaptersToDisallow list of bridge adapter addresses to be disallowed * @param sendersToApprove list of addresses to be approved as senders * @param sendersToRemove list of sender addresses to be removed * @param forwarderBridgeAdaptersToEnable list of bridge adapters to be enabled to send messages * @param forwarderBridgeAdaptersToDisable list of bridge adapters to be disabled */ function solveEmergency( uint256 newConfirmations, uint120 newValidityTimestamp, address[] memory receiverBridgeAdaptersToAllow, address[] memory receiverBridgeAdaptersToDisallow, address[] memory sendersToApprove, address[] memory sendersToRemove, BridgeAdapterConfigInput[] memory forwarderBridgeAdaptersToEnable, BridgeAdapterToDisable[] memory forwarderBridgeAdaptersToDisable ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; /** * @title ICrossChainForwarder * @author BGD Labs * @notice interface containing the objects, events and methods definitions of the CrossChainForwarder contract */ interface ICrossChainForwarder { /** * @notice object storing the connected pair of bridge adapters, on current and destination chain * @param destinationBridgeAdapter address of the bridge adapter on the destination chain * @param currentChainBridgeAdapter address of the bridge adapter deployed on current network */ struct ChainIdBridgeConfig { address destinationBridgeAdapter; address currentChainBridgeAdapter; } /** * @notice object with the necessary information to remove bridge adapters * @param bridgeAdapter address of the bridge adapter to remove * @param chainIds array of chain ids where the bridge adapter connects */ struct BridgeAdapterToDisable { address bridgeAdapter; uint256[] chainIds; } /** * @notice object storing the pair bridgeAdapter (current deployed chain) destination chain bridge adapter configuration * @param currentChainBridgeAdapter address of the bridge adapter deployed on current chain * @param destinationBridgeAdapter address of the bridge adapter on the destination chain * @param dstChainId id of the destination chain using our own nomenclature */ struct BridgeAdapterConfigInput { address currentChainBridgeAdapter; address destinationBridgeAdapter; uint256 destinationChainId; } /** * @notice emitted when a bridge adapter failed to send a message * @param destinationChainId id of the destination chain in our notation * @param bridgeAdapter address of the bridge adapter that failed (deployed on current network) * @param destinationBridgeAdapter address of the connected bridge adapter on destination chain * @param destinationChainId id of destination chain * @param message bytes intended to be bridged * @param returndata bytes with error information */ event AdapterFailed( uint256 indexed destinationChainId, address indexed bridgeAdapter, address indexed destinationBridgeAdapter, bytes message, bytes returndata ); /** * @notice emitted when a message is successfully forwarded through a bridge adapter * @param destinationChainId id of the destination chain in our notation * @param bridgeAdapter address of the bridge adapter that failed (deployed on current network) * @param destinationBridgeAdapter address of the connected bridge adapter on destination chain * @param destinationChainId id of destination chain * @param message bytes intended to be bridged */ event MessageForwarded( uint256 indexed destinationChainId, address indexed bridgeAdapter, address indexed destinationBridgeAdapter, bytes message ); /** * @notice emitted when a bridge adapter has been added to the allowed list * @param destinationChainId id of the destination chain in our notation * @param bridgeAdapter address of the bridge adapter added (deployed on current network) * @param destinationBridgeAdapter address of the connected bridge adapter on destination chain * @param allowed boolean indicating if the bridge adapter is allowed or disallowed */ event BridgeAdapterUpdated( uint256 indexed destinationChainId, address indexed bridgeAdapter, address destinationBridgeAdapter, bool indexed allowed ); /** * @notice emitted when a sender has been updated * @param sender address of the updated sender * @param isApproved boolean that indicates if the sender has been approved or removed */ event SenderUpdated(address indexed sender, bool indexed isApproved); /** * @notice method to get the current sent message nonce * @return the current nonce */ function getCurrentNonce() external view returns (uint256); /** * @notice method to check if a message has been previously forwarded. * @param destinationChainId id of the destination chain where the message needs to be bridged * @param origin address where the message originates from * @param destination address where the message is intended for * @param message bytes that need to be bridged * @return boolean indicating if the message has been forwarded */ function isMessageForwarded( uint256 destinationChainId, address origin, address destination, bytes memory message ) external view returns (bool); /** * @notice method called to initiate message forwarding to other networks. * @param destinationChainId id of the destination chain where the message needs to be bridged * @param destination address where the message is intended for * @param gasLimit gas cost on receiving side of the message * @param message bytes that need to be bridged */ function forwardMessage( uint256 destinationChainId, address destination, uint256 gasLimit, bytes memory message ) external; /** * @notice method called to re forward a previously sent message. * @param destinationChainId id of the destination chain where the message needs to be bridged * @param origin address where the message originates from * @param destination address where the message is intended for * @param gasLimit gas cost on receiving side of the message * @param message bytes that need to be bridged */ function retryMessage( uint256 destinationChainId, address origin, address destination, uint256 gasLimit, bytes memory message ) external; /** * @notice method to enable bridge adapters * @param bridgeAdapters array of new bridge adapter configurations */ function enableBridgeAdapters(BridgeAdapterConfigInput[] memory bridgeAdapters) external; /** * @notice method to disable bridge adapters * @param bridgeAdapters array of bridge adapter addresses to disable */ function disableBridgeAdapters(BridgeAdapterToDisable[] memory bridgeAdapters) external; /** * @notice method to remove sender addresses * @param senders list of addresses to remove */ function removeSenders(address[] memory senders) external; /** * @notice method to approve new sender addresses * @param senders list of addresses to approve */ function approveSenders(address[] memory senders) external; /** * @notice method to get all the bridge adapters of a chain * @param chainId id of the chain we want to get the adateprs from * @return an array of chain configurations where the bridge adapter can communicate */ function getBridgeAdaptersByChain( uint256 chainId ) external view returns (ChainIdBridgeConfig[] memory); /** * @notice method to get if a sender is approved * @param sender address that we want to check if approved * @return boolean indicating if the address has been approved as sender */ function isSenderApproved(address sender) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; /** * @title ICrossChainReceiver * @author BGD Labs * @notice interface containing the objects, events and methods definitions of the CrossChainReceiver contract */ interface ICrossChainReceiver { /** * @notice object that stores the internal information of the message * @param confirmations number of times that this message has been bridged * @param bridgedByAdapterNonce stores the nonce of when the message has been bridged by a determined bridge adapter * @param delivered boolean indicating if the bridged message has been delivered to the destination */ struct InternalBridgedMessageStateWithoutAdapters { uint120 confirmations; uint120 firstBridgedAt; bool delivered; } /** * @notice object that stores the internal information of the message * @param confirmations number of times that this message has been bridged * @param bridgedByAdapterNonce stores the nonce of when the message has been bridged by a determined bridge adapter * @param delivered boolean indicating if the bridged message has been delivered to the destination * @param bridgedByAdapter list of bridge adapters that have bridged the message */ struct InternalBridgedMessage { uint120 confirmations; uint120 firstBridgedAt; bool delivered; mapping(address => bool) bridgedByAdapter; } /** * @notice emitted when a message has reached the necessary number of confirmations * @param msgDestination address of consumer of the message * @param msgOrigin address where the message originated * @param message bytes confirmed */ event MessageConfirmed(address indexed msgDestination, address indexed msgOrigin, bytes message); /** * @notice emitted when a message has been received successfully * @param internalId message id assigned on the controller, used for internal purposes: hash(to, from, message) * @param bridgeAdapter address of the bridge adapter who received the message (deployed on current network) * @param msgDestination address of consumer of the message * @param msgOrigin address where the message originated (CrossChainController on origin chain) * @param message bytes bridged * @param confirmations number of current confirmations for this message */ event MessageReceived( bytes32 internalId, address indexed bridgeAdapter, address indexed msgDestination, address indexed msgOrigin, bytes message, uint256 confirmations ); /** * @notice emitted when a bridge adapter gets disallowed * @param brigeAdapter address of the disallowed bridge adapter * @param allowed boolean indicating if the bridge adapter has been allowed or disallowed */ event ReceiverBridgeAdaptersUpdated(address indexed brigeAdapter, bool indexed allowed); /** * @notice emitted when number of confirmations needed to validate a message changes * @param newConfirmations number of new confirmations needed for a message to be valid */ event ConfirmationsUpdated(uint256 newConfirmations); /** * @notice emitted when a new timestamp for invalidations gets set * @param invalidTimestamp timestamp to invalidate previous messages */ event NewInvalidation(uint256 invalidTimestamp); /** * @notice method to get the needed confirmations for a message to be accepted as valid * @return the number of required bridged message confirmations (how many bridges have bridged the message correctly) * for a message to be sent to destination */ function getRequiredConfirmations() external view returns (uint256); /** * @notice method to get the timestamp from where the messages will be valid * @return timestamp indicating the point from where the messages are valid. */ function getValidityTimestamp() external view returns (uint120); /** * @notice method to get if a bridge adapter is allowed * @param bridgeAdapter address of the brige adapter to check * @return boolean indicating if brige adapter is allowed */ function isReceiverBridgeAdapterAllowed(address bridgeAdapter) external view returns (bool); /** * @notice method to get the internal message information * @param internalId hash(originChain + payload) identifying the message internally * @return number of confirmations of internal message identified by internalId and the updated timestamp */ function getInternalMessageState( bytes32 internalId ) external view returns (InternalBridgedMessageStateWithoutAdapters memory); /** * @notice method to get if message has been received by bridge adapter * @param internalId id of the message as stored internally * @param bridgeAdapter address of the bridge adapter to check if it has bridged the message * @return boolean indicating if the message has been received */ function isInternalMessageReceivedByAdapter( bytes32 internalId, address bridgeAdapter ) external view returns (bool); /** * @notice method to set a new timestamp from where the messages will be valid. * @param newValidityTimestamp timestamp where all the previous unconfirmed messages must be invalidated. */ function updateMessagesValidityTimestamp(uint120 newValidityTimestamp) external; /** * @notice method to update the number of confirmations necessary for the messages to be accepted as valid * @param newConfirmations new number of needed confirmations */ function updateConfirmations(uint256 newConfirmations) external; /** * @notice method that registers a received message, updates the confirmations, and sets it as valid if number of confirmations has been reached. * @param payload bytes of the payload, containing the information to operate with it */ function receiveCrossChainMessage(bytes memory payload, uint256 originChainId) external; /** * @notice method to add bridge adapters to the allowed list * @param bridgeAdapters array of new bridge adapter configurations */ function allowReceiverBridgeAdapters(address[] memory bridgeAdapters) external; /** * @notice method to remove bridge adapters from the allowed list * @param bridgeAdapters array of bridge adapter addresses to remove from the allow list */ function disallowReceiverBridgeAdapters(address[] memory bridgeAdapters) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library MainnetChainIds { uint256 constant ETHEREUM = 1; uint256 constant POLYGON = 137; uint256 constant AVALANCHE = 43114; uint256 constant ARBITRUM = 42161; uint256 constant OPTIMISM = 10; uint256 constant FANTOM = 250; uint256 constant HARMONY = 1666600000; } library TestnetChainIds { uint256 constant ETHEREUM_GOERLI = 5; uint256 constant POLYGON_MUMBAI = 80001; uint256 constant AVALANCHE_FUJI = 43113; uint256 constant ARBITRUM_GOERLI = 421613; uint256 constant OPTIMISM_GOERLI = 420; uint256 constant FANTOM_TESTNET = 4002; uint256 constant HARMONY_TESTNET = 1666700000; uint256 constant ETHEREUM_SEPOLIA = 11155111; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title Errors library * @author BGD Labs * @notice Defines the error messages emitted by the different contracts of the Aave Governance V3 */ library Errors { string public constant ETH_TRANSFER_FAILED = '1'; // failed to transfer eth to destination string public constant CALLER_IS_NOT_APPROVED_SENDER = '2'; // caller must be an approved message sender string public constant MESSAGE_REQUIRED_TO_HAVE_BEEN_PREVIOUSLY_FORWARDED = '3'; // message can only be retried if it has been previously forwarded string public constant NO_MESSAGE_FORWARDED_SUCCESSFULLY = '4'; // message was not able to be forwarded string public constant CURRENT_OR_DESTINATION_CHAIN_ADAPTER_NOT_SET = '5'; // can not enable bridge adapter if the current or destination chain adapter is 0 address string public constant CALLER_NOT_APPROVED_BRIDGE = '6'; // caller must be an approved bridge string public constant TIMESTAMP_ALREADY_PASSED = '7'; // timestamp is older than current timestamp (in the past) string public constant CALLER_NOT_CCIP_ROUTER = '8'; // caller must be bridge provider contract string public constant CCIP_ROUTER_CANT_BE_ADDRESS_0 = '9'; // CCIP bridge adapters needs a CCIP Router string public constant RECEIVER_NOT_SET = '10'; // receiver address on destination chain can not be 0 string public constant DESTINATION_CHAIN_ID_NOT_SUPPORTED = '11'; // destination chain id must be supported by bridge provider string public constant NOT_ENOUGH_VALUE_TO_PAY_BRIDGE_FEES = '12'; // cross chain controller does not have enough funds to forward the message string public constant INCORRECT_ORIGIN_CHAIN_ID = '13'; // message origination chain id is not from a supported chain string public constant REMOTE_NOT_TRUSTED = '14'; // remote address has not been registered as a trusted origin string public constant CALLER_NOT_HL_MAILBOX = '15'; // caller must be the HyperLane Mailbox contract }
{ "remappings": [ "@aave/core-v3/=lib/aave-a-token-with-delegation/lib/aave-address-book/lib/aave-v3-core/", "@aave/periphery-v3/=lib/aave-a-token-with-delegation/lib/aave-address-book/lib/aave-v3-periphery/", "@openzeppelin/=lib/aave-crosschain-infra/lib/openzeppelin-contracts/", "aave-a-token-with-delegation/=lib/aave-a-token-with-delegation/src/", "aave-address-book/=lib/aave-a-token-with-delegation/lib/aave-address-book/src/", "aave-crosschain-infra/=lib/aave-crosschain-infra/src/", "aave-helpers/=lib/aave-stk-gov-v3/lib/aave-helpers/", "aave-stk-gov-v3/=lib/aave-stk-gov-v3/src/", "aave-stk-slashing-mgmt/=lib/aave-stk-slashing-mgmt/src/", "aave-token-v2/=lib/aave-token-v3/lib/aave-token-v2/contracts/", "aave-token-v3/=lib/aave-token-v3/src/", "aave-v3-core/=lib/aave-a-token-with-delegation/lib/aave-v3-core/", "aave-v3-periphery/=lib/aave-a-token-with-delegation/lib/aave-address-book/lib/aave-v3-periphery/", "ds-test/=lib/forge-std/lib/ds-test/src/", "emergency-exit/=lib/emergency-exit/src/", "erc4626-tests/=lib/aave-stk-gov-v3/lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "hyperlane-monorepo/=lib/aave-crosschain-infra/lib/hyperlane-monorepo/solidity/", "openzeppelin-contracts/=lib/aave-crosschain-infra/lib/openzeppelin-contracts/", "solidity-examples/=lib/aave-crosschain-infra/lib/solidity-examples/contracts/", "solidity-utils/=lib/solidity-utils/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
[{"inputs":[{"internalType":"address","name":"crossChainController","type":"address"},{"internalType":"address","name":"ccipRouter","type":"address"},{"components":[{"internalType":"address","name":"originForwarder","type":"address"},{"internalType":"uint256","name":"originChainId","type":"uint256"}],"internalType":"struct ICCIPAdapter.TrustedRemotesConfig[]","name":"trustedRemotes","type":"tuple[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"srcChainId","type":"uint256"},{"indexed":true,"internalType":"address","name":"srcAddress","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"CCIPPayloadProcessed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"uint64","name":"destinationChainId","type":"uint64"},{"indexed":true,"internalType":"bytes32","name":"messageId","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"}],"name":"MessageForwarded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"originChainId","type":"uint256"},{"indexed":true,"internalType":"address","name":"originForwarder","type":"address"}],"name":"SetTrustedRemote","type":"event"},{"inputs":[],"name":"CCIP_ROUTER","outputs":[{"internalType":"contract IRouterClient","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CROSS_CHAIN_CONTROLLER","outputs":[{"internalType":"contract ICrossChainController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"messageId","type":"bytes32"},{"internalType":"uint64","name":"sourceChainId","type":"uint64"},{"internalType":"bytes","name":"sender","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct Client.EVMTokenAmount[]","name":"tokenAmounts","type":"tuple[]"}],"internalType":"struct Client.Any2EVMMessage","name":"message","type":"tuple"}],"name":"ccipReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"internalType":"bytes","name":"message","type":"bytes"}],"name":"forwardMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"}],"name":"getTrustedRemoteByChainId","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"infraChainId","type":"uint256"}],"name":"infraToNativeChainId","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint64","name":"nativeChainId","type":"uint64"}],"name":"nativeToInfraChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"}]
Contract Creation Code
60c06040523480156200001157600080fd5b506040516200128b3803806200128b83398101604081905262000034916200024d565b6001600160a01b038084166080526040805180820190915260018152603960f81b6020820152908316620000865760405162461bcd60e51b81526004016200007d919062000358565b60405180910390fd5b506001600160a01b03821660a0526200009f81620000a8565b505050620003f0565b60005b8151811015620001b857818181518110620000ca57620000ca620003b0565b602002602001015160000151600080848481518110620000ee57620000ee620003b0565b602002602001015160200151815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b03160217905550818181518110620001415762000141620003b0565b6020026020010151600001516001600160a01b03168282815181106200016b576200016b620003b0565b6020026020010151602001517fa214744f665691ef0eb9e4277cfa3c9198106c8925d6fa6880b6813f705c1aab60405160405180910390a380620001af81620003c6565b915050620000ab565b5050565b80516001600160a01b0381168114620001d457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620002145762000214620001d9565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620002455762000245620001d9565b604052919050565b6000806000606084860312156200026357600080fd5b6200026e84620001bc565b925060206200027f818601620001bc565b604086810151919450906001600160401b03808211156200029f57600080fd5b818801915088601f830112620002b457600080fd5b815181811115620002c957620002c9620001d9565b620002d9858260051b016200021a565b818152858101925060069190911b83018501908a821115620002fa57600080fd5b928501925b81841015620003485784848c031215620003195760008081fd5b62000323620001ef565b6200032e85620001bc565b8152848701518782015283529284019291850191620002ff565b8096505050505050509250925092565b600060208083528351808285015260005b81811015620003875785810183015185820160400152820162000369565b818111156200039a576000604083870101525b50601f01601f1916929092016040019392505050565b634e487b7160e01b600052603260045260246000fd5b6000600019821415620003e957634e487b7160e01b600052601160045260246000fd5b5060010190565b60805160a051610e5262000439600039600081816101960152818161021b015281816103fb015281816104cc01526105d901526000818161014401526109cf0152610e526000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063bf7decbf1161005b578063bf7decbf1461011e578063c49563661461013f578063d688758114610166578063fe5f42ca1461019157600080fd5b806301ffc9a71461008d57806336da7a06146100b557806385572ffb146100ca578063b86a6161146100dd575b600080fd5b6100a061009b366004610a3c565b6101b8565b60405190151581526020015b60405180910390f35b6100c86100c3366004610a9b565b6101ef565b005b6100c86100d8366004610b71565b6105b6565b6101066100eb366004610bab565b6000908152602081905260409020546001600160a01b031690565b6040516001600160a01b0390911681526020016100ac565b61013161012c366004610bc4565b61077c565b6040519081526020016100ac565b6101067f000000000000000000000000000000000000000000000000000000000000000081565b610179610174366004610bab565b6108d4565b6040516001600160401b0390911681526020016100ac565b6101067f000000000000000000000000000000000000000000000000000000000000000081565b60006001600160e01b031982166385572ffb60e01b14806101e957506001600160e01b031982166301ffc9a760e01b145b92915050565b60006101fa836108d4565b604051631491520b60e31b81526001600160401b03821660048201529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a48a905890602401602060405180830381865afa15801561026a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061028e9190610bed565b60405180604001604052806002815260200161313160f01b815250906102d05760405162461bcd60e51b81526004016102c79190610c5c565b60405180910390fd5b50604080518082019091526002815261031360f41b60208201526001600160a01b0386166103115760405162461bcd60e51b81526004016102c79190610c5c565b50604080518082018252858152600060208083018281528451602481018a905290511515604480830191909152855180830390910181526064909101855280820180516001600160e01b03166397a657c960e01b179052845160a0810186526001600160a01b038b1660c0808301919091528651808303909101815260e082018752815280830188905285518481529283018652939490939190820190836103db565b60408051808201909152600080825260208201528152602001906001900390816103b45790505b50815260200160006001600160a01b0316815260200183815250905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166320487ded86846040518363ffffffff1660e01b8152600401610447929190610c6f565b602060405180830381865afa158015610464573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104889190610d48565b90508047101560405180604001604052806002815260200161189960f11b815250906104c75760405162461bcd60e51b81526004016102c79190610c5c565b5060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166396f4e9f98388866040518463ffffffff1660e01b8152600401610519929190610c6f565b60206040518083038185885af1158015610537573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061055c9190610d48565b905080866001600160401b03168b6001600160a01b03167f4a9408cab2f56e376c439be33e07d1248efa2ec3336b1c26f6fa178d54df0b0c8a6040516105a29190610c5c565b60405180910390a450505050505050505050565b6040805180820190915260018152600760fb1b6020820152336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146106175760405162461bcd60e51b81526004016102c79190610c5c565b5060006106276040830183610d61565b8101906106349190610dae565b9050600061064b61012c6040850160208601610bc4565b604080518082019091526002815261313360f01b6020820152909150816106855760405162461bcd60e51b81526004016102c79190610c5c565b506000818152602081815260409182902054825180840190935260028352610c4d60f21b918301919091526001600160a01b038481169116146106db5760405162461bcd60e51b81526004016102c79190610c5c565b506107286106ec6060850185610d61565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508592506109b8915050565b6001600160a01b038216817f9fb3f8b434b095acfff7d47cc0daadc9670bf8a385e1b38351aa92b2edfd730d6107616060870187610d61565b60405161076f929190610dcb565b60405180910390a3505050565b60006001600160401b0382166001141561079857506001919050565b6001600160401b03821661a86a14156107b4575061a86a919050565b6001600160401b038216608914156107ce57506089919050565b6001600160401b03821661a4b114156107ea575061a4b1919050565b6001600160401b038216600a14156108045750600a919050565b6001600160401b03821660fa141561081e575060fa919050565b6001600160401b0382166363564c40141561083e57506363564c40919050565b6001600160401b0382166005141561085857506005919050565b6001600160401b03821661a8691415610874575061a869919050565b6001600160401b0382166101a4141561089057506101a4919050565b6001600160401b0382166201388114156108ae575062013881919050565b6001600160401b03821662aa36a714156108cc575062aa36a7919050565b506000919050565b600060018214156108e757506001919050565b61a86a8214156108fa575061a86a919050565b608982141561090b57506089919050565b61a4b182141561091e575061a4b1919050565b600a82141561092f5750600a919050565b60fa821415610940575060fa919050565b6363564c4082141561095757506363564c40919050565b600582141561096857506005919050565b61a86982141561097b575061a869919050565b6101a482141561098e57506101a4919050565b620138818214156109a3575062013881919050565b62aa36a78214156108cc575062aa36a7919050565b6040516376b42cad60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063ed68595a90610a069085908590600401610dfa565b600060405180830381600087803b158015610a2057600080fd5b505af1158015610a34573d6000803e3d6000fd5b505050505050565b600060208284031215610a4e57600080fd5b81356001600160e01b031981168114610a6657600080fd5b9392505050565b6001600160a01b0381168114610a8257600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215610ab157600080fd5b8435610abc81610a6d565b9350602085013592506040850135915060608501356001600160401b0380821115610ae657600080fd5b818701915087601f830112610afa57600080fd5b813581811115610b0c57610b0c610a85565b604051601f8201601f19908116603f01168101908382118183101715610b3457610b34610a85565b816040528281528a6020848701011115610b4d57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b600060208284031215610b8357600080fd5b81356001600160401b03811115610b9957600080fd5b820160a08185031215610a6657600080fd5b600060208284031215610bbd57600080fd5b5035919050565b600060208284031215610bd657600080fd5b81356001600160401b0381168114610a6657600080fd5b600060208284031215610bff57600080fd5b81518015158114610a6657600080fd5b6000815180845260005b81811015610c3557602081850181015186830182015201610c19565b81811115610c47576000602083870101525b50601f01601f19169290920160200192915050565b602081526000610a666020830184610c0f565b600060406001600160401b038516835260208181850152845160a083860152610c9b60e0860182610c0f565b905081860151603f1980878403016060880152610cb88383610c0f565b88860151888203830160808a01528051808352908601945060009350908501905b80841015610d0b57845180516001600160a01b0316835286015186830152938501936001939093019290860190610cd9565b5060608901516001600160a01b031660a08901526080890151888203830160c08a01529550610d3a8187610c0f565b9a9950505050505050505050565b600060208284031215610d5a57600080fd5b5051919050565b6000808335601e19843603018112610d7857600080fd5b8301803591506001600160401b03821115610d9257600080fd5b602001915036819003821315610da757600080fd5b9250929050565b600060208284031215610dc057600080fd5b8135610a6681610a6d565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b604081526000610e0d6040830185610c0f565b9050826020830152939250505056fea26469706673582212203cff96e9ddabdd379e85fcbc430838a3dded52be555fc22a7b2d5456b460c5a664736f6c634300080a00330000000000000000000000004d2f1c99bce324b9ba486d704a0235a754d188a20000000000000000000000000a36795b3006f50088c11ea45b960a1b0406f03b00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000002000000000000000000000000f640cea278e94708c358d79e5872afda5601011700000000000000000000000000000000000000000000000000000000000001a40000000000000000000000004a5d71f7027684d473a1110a412b510354af33e7000000000000000000000000000000000000000000000000000000000000a869
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063bf7decbf1161005b578063bf7decbf1461011e578063c49563661461013f578063d688758114610166578063fe5f42ca1461019157600080fd5b806301ffc9a71461008d57806336da7a06146100b557806385572ffb146100ca578063b86a6161146100dd575b600080fd5b6100a061009b366004610a3c565b6101b8565b60405190151581526020015b60405180910390f35b6100c86100c3366004610a9b565b6101ef565b005b6100c86100d8366004610b71565b6105b6565b6101066100eb366004610bab565b6000908152602081905260409020546001600160a01b031690565b6040516001600160a01b0390911681526020016100ac565b61013161012c366004610bc4565b61077c565b6040519081526020016100ac565b6101067f0000000000000000000000004d2f1c99bce324b9ba486d704a0235a754d188a281565b610179610174366004610bab565b6108d4565b6040516001600160401b0390911681526020016100ac565b6101067f0000000000000000000000000a36795b3006f50088c11ea45b960a1b0406f03b81565b60006001600160e01b031982166385572ffb60e01b14806101e957506001600160e01b031982166301ffc9a760e01b145b92915050565b60006101fa836108d4565b604051631491520b60e31b81526001600160401b03821660048201529091507f0000000000000000000000000a36795b3006f50088c11ea45b960a1b0406f03b6001600160a01b03169063a48a905890602401602060405180830381865afa15801561026a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061028e9190610bed565b60405180604001604052806002815260200161313160f01b815250906102d05760405162461bcd60e51b81526004016102c79190610c5c565b60405180910390fd5b50604080518082019091526002815261031360f41b60208201526001600160a01b0386166103115760405162461bcd60e51b81526004016102c79190610c5c565b50604080518082018252858152600060208083018281528451602481018a905290511515604480830191909152855180830390910181526064909101855280820180516001600160e01b03166397a657c960e01b179052845160a0810186526001600160a01b038b1660c0808301919091528651808303909101815260e082018752815280830188905285518481529283018652939490939190820190836103db565b60408051808201909152600080825260208201528152602001906001900390816103b45790505b50815260200160006001600160a01b0316815260200183815250905060007f0000000000000000000000000a36795b3006f50088c11ea45b960a1b0406f03b6001600160a01b03166320487ded86846040518363ffffffff1660e01b8152600401610447929190610c6f565b602060405180830381865afa158015610464573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104889190610d48565b90508047101560405180604001604052806002815260200161189960f11b815250906104c75760405162461bcd60e51b81526004016102c79190610c5c565b5060007f0000000000000000000000000a36795b3006f50088c11ea45b960a1b0406f03b6001600160a01b03166396f4e9f98388866040518463ffffffff1660e01b8152600401610519929190610c6f565b60206040518083038185885af1158015610537573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061055c9190610d48565b905080866001600160401b03168b6001600160a01b03167f4a9408cab2f56e376c439be33e07d1248efa2ec3336b1c26f6fa178d54df0b0c8a6040516105a29190610c5c565b60405180910390a450505050505050505050565b6040805180820190915260018152600760fb1b6020820152336001600160a01b037f0000000000000000000000000a36795b3006f50088c11ea45b960a1b0406f03b16146106175760405162461bcd60e51b81526004016102c79190610c5c565b5060006106276040830183610d61565b8101906106349190610dae565b9050600061064b61012c6040850160208601610bc4565b604080518082019091526002815261313360f01b6020820152909150816106855760405162461bcd60e51b81526004016102c79190610c5c565b506000818152602081815260409182902054825180840190935260028352610c4d60f21b918301919091526001600160a01b038481169116146106db5760405162461bcd60e51b81526004016102c79190610c5c565b506107286106ec6060850185610d61565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508592506109b8915050565b6001600160a01b038216817f9fb3f8b434b095acfff7d47cc0daadc9670bf8a385e1b38351aa92b2edfd730d6107616060870187610d61565b60405161076f929190610dcb565b60405180910390a3505050565b60006001600160401b0382166001141561079857506001919050565b6001600160401b03821661a86a14156107b4575061a86a919050565b6001600160401b038216608914156107ce57506089919050565b6001600160401b03821661a4b114156107ea575061a4b1919050565b6001600160401b038216600a14156108045750600a919050565b6001600160401b03821660fa141561081e575060fa919050565b6001600160401b0382166363564c40141561083e57506363564c40919050565b6001600160401b0382166005141561085857506005919050565b6001600160401b03821661a8691415610874575061a869919050565b6001600160401b0382166101a4141561089057506101a4919050565b6001600160401b0382166201388114156108ae575062013881919050565b6001600160401b03821662aa36a714156108cc575062aa36a7919050565b506000919050565b600060018214156108e757506001919050565b61a86a8214156108fa575061a86a919050565b608982141561090b57506089919050565b61a4b182141561091e575061a4b1919050565b600a82141561092f5750600a919050565b60fa821415610940575060fa919050565b6363564c4082141561095757506363564c40919050565b600582141561096857506005919050565b61a86982141561097b575061a869919050565b6101a482141561098e57506101a4919050565b620138818214156109a3575062013881919050565b62aa36a78214156108cc575062aa36a7919050565b6040516376b42cad60e11b81526001600160a01b037f0000000000000000000000004d2f1c99bce324b9ba486d704a0235a754d188a2169063ed68595a90610a069085908590600401610dfa565b600060405180830381600087803b158015610a2057600080fd5b505af1158015610a34573d6000803e3d6000fd5b505050505050565b600060208284031215610a4e57600080fd5b81356001600160e01b031981168114610a6657600080fd5b9392505050565b6001600160a01b0381168114610a8257600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215610ab157600080fd5b8435610abc81610a6d565b9350602085013592506040850135915060608501356001600160401b0380821115610ae657600080fd5b818701915087601f830112610afa57600080fd5b813581811115610b0c57610b0c610a85565b604051601f8201601f19908116603f01168101908382118183101715610b3457610b34610a85565b816040528281528a6020848701011115610b4d57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b600060208284031215610b8357600080fd5b81356001600160401b03811115610b9957600080fd5b820160a08185031215610a6657600080fd5b600060208284031215610bbd57600080fd5b5035919050565b600060208284031215610bd657600080fd5b81356001600160401b0381168114610a6657600080fd5b600060208284031215610bff57600080fd5b81518015158114610a6657600080fd5b6000815180845260005b81811015610c3557602081850181015186830182015201610c19565b81811115610c47576000602083870101525b50601f01601f19169290920160200192915050565b602081526000610a666020830184610c0f565b600060406001600160401b038516835260208181850152845160a083860152610c9b60e0860182610c0f565b905081860151603f1980878403016060880152610cb88383610c0f565b88860151888203830160808a01528051808352908601945060009350908501905b80841015610d0b57845180516001600160a01b0316835286015186830152938501936001939093019290860190610cd9565b5060608901516001600160a01b031660a08901526080890151888203830160c08a01529550610d3a8187610c0f565b9a9950505050505050505050565b600060208284031215610d5a57600080fd5b5051919050565b6000808335601e19843603018112610d7857600080fd5b8301803591506001600160401b03821115610d9257600080fd5b602001915036819003821315610da757600080fd5b9250929050565b600060208284031215610dc057600080fd5b8135610a6681610a6d565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b604081526000610e0d6040830185610c0f565b9050826020830152939250505056fea26469706673582212203cff96e9ddabdd379e85fcbc430838a3dded52be555fc22a7b2d5456b460c5a664736f6c634300080a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000004d2f1c99bce324b9ba486d704a0235a754d188a20000000000000000000000000a36795b3006f50088c11ea45b960a1b0406f03b00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000002000000000000000000000000f640cea278e94708c358d79e5872afda5601011700000000000000000000000000000000000000000000000000000000000001a40000000000000000000000004a5d71f7027684d473a1110a412b510354af33e7000000000000000000000000000000000000000000000000000000000000a869
-----Decoded View---------------
Arg [0] : crossChainController (address): 0x4d2F1C99BCE324B9Ba486d704A0235A754D188a2
Arg [1] : ccipRouter (address): 0x0A36795B3006f50088c11ea45b960A1b0406f03b
Arg [2] : trustedRemotes (tuple[]): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 0000000000000000000000004d2f1c99bce324b9ba486d704a0235a754d188a2
Arg [1] : 0000000000000000000000000a36795b3006f50088c11ea45b960a1b0406f03b
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [4] : 000000000000000000000000f640cea278e94708c358d79e5872afda56010117
Arg [5] : 00000000000000000000000000000000000000000000000000000000000001a4
Arg [6] : 0000000000000000000000004a5d71f7027684d473a1110a412b510354af33e7
Arg [7] : 000000000000000000000000000000000000000000000000000000000000a869
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.