Sepolia Testnet

Contract

0xb061821EeE3fE903231a4613DCb6bEa7b08a84cB

Overview

ETH Balance

0 ETH

Multichain Info

N/A
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
HyperLaneAdapter

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)

File 1 of 14 : HyperLaneAdapter.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {BaseAdapter, IBaseAdapter} from '../BaseAdapter.sol';
import {IHyperLaneAdapter, IMailbox, IInterchainGasPaymaster} from './IHyperLaneAdapter.sol';
import {IMessageRecipient} from 'hyperlane-monorepo/interfaces/IMessageRecipient.sol';
import {TypeCasts} from 'hyperlane-monorepo/contracts/libs/TypeCasts.sol';
import {MainnetChainIds, TestnetChainIds} from '../../libs/ChainIds.sol';
import {Errors} from '../../libs/Errors.sol';

/**
 * @title HyperLaneAdapter
 * @author BGD Labs
 * @notice HyperLane 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 HyperLaneAdapter is BaseAdapter, IHyperLaneAdapter, IMessageRecipient {
  /// @inheritdoc IHyperLaneAdapter
  IMailbox public immutable HL_MAIL_BOX;

  /// @inheritdoc IHyperLaneAdapter
  IInterchainGasPaymaster public immutable IGP;

  // (standard chain id -> origin forwarder address) saves for every chain the address that can forward messages to this adapter
  mapping(uint256 => address) internal _trustedRemotes;

  /// @notice modifier to check that caller is hyper lane mailBox
  modifier onlyMailbox() {
    require(msg.sender == address(HL_MAIL_BOX), Errors.CALLER_NOT_HL_MAILBOX);
    _;
  }

  /**
   * @param crossChainController address of the cross chain controller that will use this bridge adapter
   * @param mailBox HyperLane router contract address to send / receive cross chain messages
   * @param igp HyperLane contract to get the gas estimation to pay for sending messages
   * @param trustedRemotes list of remote configurations to set as trusted
   */
  constructor(
    address crossChainController,
    address mailBox,
    address igp,
    TrustedRemotesConfig[] memory trustedRemotes
  ) BaseAdapter(crossChainController) {
    HL_MAIL_BOX = IMailbox(mailBox);
    IGP = IInterchainGasPaymaster(igp);
    _updateTrustedRemotes(trustedRemotes);
  }

  /// @inheritdoc IHyperLaneAdapter
  function getTrustedRemoteByChainId(uint256 chainId) external view returns (address) {
    return _trustedRemotes[chainId];
  }

  /// @inheritdoc IBaseAdapter
  function forwardMessage(
    address receiver,
    uint256 destinationGasLimit,
    uint256 destinationChainId,
    bytes memory message
  ) external {
    uint32 nativeChainId = infraToNativeChainId(destinationChainId);
    require(nativeChainId != uint32(0), Errors.DESTINATION_CHAIN_ID_NOT_SUPPORTED);
    require(receiver != address(0), Errors.RECEIVER_NOT_SET);

    bytes32 messageId = HL_MAIL_BOX.dispatch(
      nativeChainId,
      TypeCasts.addressToBytes32(receiver),
      message
    );

    // Get the required payment from the IGP.
    uint256 quotedPayment = IGP.quoteGasPayment(nativeChainId, destinationGasLimit);

    require(quotedPayment <= address(this).balance, Errors.NOT_ENOUGH_VALUE_TO_PAY_BRIDGE_FEES);

    // Pay from the contract's balance
    IGP.payForGas{value: quotedPayment}(
      messageId, // The ID of the message that was just dispatched
      nativeChainId, // The destination domain of the message
      destinationGasLimit,
      address(this) // refunds go to msg.sender, who paid the msg.value
    );

    emit MessageForwarded(receiver, nativeChainId, message);
  }

  /// @inheritdoc IMessageRecipient
  function handle(
    uint32 _origin,
    bytes32 _sender,
    bytes calldata _messageBody
  ) external onlyMailbox {
    address srcAddress = TypeCasts.bytes32ToAddress(_sender);

    uint256 originChainId = nativeToInfraChainId(_origin);

    require(originChainId != 0, Errors.INCORRECT_ORIGIN_CHAIN_ID);

    require(_trustedRemotes[originChainId] == srcAddress, Errors.REMOTE_NOT_TRUSTED);
    _registerReceivedMessage(_messageBody, originChainId);
    emit HLPayloadProcessed(originChainId, srcAddress, _messageBody);
  }

  /// @inheritdoc IHyperLaneAdapter
  function nativeToInfraChainId(uint32 nativeChainId) public pure returns (uint256) {
    if (nativeChainId == uint32(MainnetChainIds.ETHEREUM)) {
      return MainnetChainIds.ETHEREUM;
    } else if (nativeChainId == uint32(MainnetChainIds.AVALANCHE)) {
      return MainnetChainIds.AVALANCHE;
    } else if (nativeChainId == uint32(MainnetChainIds.POLYGON)) {
      return MainnetChainIds.POLYGON;
    } else if (nativeChainId == uint32(MainnetChainIds.ARBITRUM)) {
      return MainnetChainIds.ARBITRUM;
    } else if (nativeChainId == uint32(MainnetChainIds.OPTIMISM)) {
      return MainnetChainIds.OPTIMISM;
    } else if (nativeChainId == uint32(TestnetChainIds.ETHEREUM_GOERLI)) {
      return TestnetChainIds.ETHEREUM_GOERLI;
    } else if (nativeChainId == uint32(TestnetChainIds.AVALANCHE_FUJI)) {
      return TestnetChainIds.AVALANCHE_FUJI;
    } else if (nativeChainId == uint32(TestnetChainIds.OPTIMISM_GOERLI)) {
      return TestnetChainIds.OPTIMISM_GOERLI;
    } else if (nativeChainId == uint32(TestnetChainIds.POLYGON_MUMBAI)) {
      return TestnetChainIds.POLYGON_MUMBAI;
    } else if (nativeChainId == uint32(TestnetChainIds.ARBITRUM_GOERLI)) {
      return TestnetChainIds.ARBITRUM_GOERLI;
    } else if (nativeChainId == uint32(TestnetChainIds.ETHEREUM_SEPOLIA)) {
      return TestnetChainIds.ETHEREUM_SEPOLIA;
    } else {
      return 0;
    }
  }

  /// @inheritdoc IHyperLaneAdapter
  function infraToNativeChainId(uint256 infraChainId) public pure returns (uint32) {
    if (infraChainId == MainnetChainIds.ETHEREUM) {
      return uint32(MainnetChainIds.ETHEREUM);
    } else if (infraChainId == MainnetChainIds.AVALANCHE) {
      return uint32(MainnetChainIds.AVALANCHE);
    } else if (infraChainId == MainnetChainIds.POLYGON) {
      return uint32(MainnetChainIds.POLYGON);
    } else if (infraChainId == MainnetChainIds.ARBITRUM) {
      return uint32(MainnetChainIds.ARBITRUM);
    } else if (infraChainId == MainnetChainIds.OPTIMISM) {
      return uint32(MainnetChainIds.OPTIMISM);
    } else if (infraChainId == TestnetChainIds.ETHEREUM_GOERLI) {
      return uint32(TestnetChainIds.ETHEREUM_GOERLI);
    } else if (infraChainId == TestnetChainIds.AVALANCHE_FUJI) {
      return uint32(TestnetChainIds.AVALANCHE_FUJI);
    } else if (infraChainId == TestnetChainIds.OPTIMISM_GOERLI) {
      return uint32(TestnetChainIds.OPTIMISM_GOERLI);
    } else if (infraChainId == TestnetChainIds.POLYGON_MUMBAI) {
      return uint32(TestnetChainIds.POLYGON_MUMBAI);
    } else if (infraChainId == TestnetChainIds.ARBITRUM_GOERLI) {
      return uint32(TestnetChainIds.ARBITRUM_GOERLI);
    } else if (infraChainId == TestnetChainIds.ETHEREUM_SEPOLIA) {
      return uint32(TestnetChainIds.ETHEREUM_SEPOLIA);
    } else {
      return uint32(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);
    }
  }
}

File 2 of 14 : TypeCasts.sol
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity >=0.6.11;

library TypeCasts {
    // treat it as a null-terminated string of max 32 bytes
    function coerceString(bytes32 _buf)
        internal
        pure
        returns (string memory _newStr)
    {
        uint8 _slen = 0;
        while (_slen < 32 && _buf[_slen] != 0) {
            _slen++;
        }

        // solhint-disable-next-line no-inline-assembly
        assembly {
            _newStr := mload(0x40)
            mstore(0x40, add(_newStr, 0x40)) // may end up with extra
            mstore(_newStr, _slen)
            mstore(add(_newStr, 0x20), _buf)
        }
    }

    // alignment preserving cast
    function addressToBytes32(address _addr) internal pure returns (bytes32) {
        return bytes32(uint256(uint160(_addr)));
    }

    // alignment preserving cast
    function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {
        return address(uint160(uint256(_buf)));
    }
}

File 3 of 14 : IInterchainGasPaymaster.sol
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity >=0.6.11;

/**
 * @title IInterchainGasPaymaster
 * @notice Manages payments on a source chain to cover gas costs of relaying
 * messages to destination chains.
 */
interface IInterchainGasPaymaster {
    function payForGas(
        bytes32 _messageId,
        uint32 _destinationDomain,
        uint256 _gasAmount,
        address _refundAddress
    ) external payable;

    function quoteGasPayment(uint32 _destinationDomain, uint256 _gasAmount)
        external
        view
        returns (uint256);
}

File 4 of 14 : IInterchainSecurityModule.sol
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity >=0.6.11;

interface IInterchainSecurityModule {
    /**
     * @notice Returns an enum that represents the type of security model
     * encoded by this ISM.
     * @dev Relayers infer how to fetch and format metadata.
     */
    function moduleType() external view returns (uint8);

    /**
     * @notice Defines a security model responsible for verifying interchain
     * messages based on the provided metadata.
     * @param _metadata Off-chain metadata provided by a relayer, specific to
     * the security model encoded by the module (e.g. validator signatures)
     * @param _message Hyperlane encoded interchain message
     * @return True if the message was verified
     */
    function verify(bytes calldata _metadata, bytes calldata _message)
        external
        returns (bool);
}

interface ISpecifiesInterchainSecurityModule {
    function interchainSecurityModule()
        external
        view
        returns (IInterchainSecurityModule);
}

File 5 of 14 : IMailbox.sol
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity >=0.8.0;

import {IInterchainSecurityModule} from "./IInterchainSecurityModule.sol";

interface IMailbox {
    function localDomain() external view returns (uint32);

    function dispatch(
        uint32 _destinationDomain,
        bytes32 _recipientAddress,
        bytes calldata _messageBody
    ) external returns (bytes32);

    function process(bytes calldata _metadata, bytes calldata _message)
        external;

    function count() external view returns (uint32);

    function root() external view returns (bytes32);

    function latestCheckpoint() external view returns (bytes32, uint32);

    function recipientIsm(address _recipient)
        external
        view
        returns (IInterchainSecurityModule);
}

File 6 of 14 : IMessageRecipient.sol
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity >=0.6.11;

interface IMessageRecipient {
    function handle(
        uint32 _origin,
        bytes32 _sender,
        bytes calldata _message
    ) external;
}

File 7 of 14 : BaseAdapter.sol
// 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);
  }
}

File 8 of 14 : IBaseAdapter.sol
// 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;
}

File 9 of 14 : IHyperLaneAdapter.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IMailbox} from 'hyperlane-monorepo/interfaces/IMailbox.sol';
import {IInterchainGasPaymaster} from 'hyperlane-monorepo/interfaces/IInterchainGasPaymaster.sol';

/**
 * @title IHyperLaneAdapter
 * @author BGD Labs
 * @notice interface containing the events, objects and method definitions used in the HyperLane bridge adapter
 */
interface IHyperLaneAdapter {
  /**
   * @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 message object to be bridged
   */
  event MessageForwarded(
    address indexed receiver,
    uint32 indexed destinationChainId,
    bytes message
  );

  /**
   * @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 emitted when a message is received and has been correctly processed
   * @param originChainId id of the chain where the message originated from
   * @param srcAddress address that sent the message (origin CrossChainContract)
   * @param _messageBody bridged message
   */
  event HLPayloadProcessed(
    uint256 indexed originChainId,
    address indexed srcAddress,
    bytes _messageBody
  );

  /**
   * @notice method to get the current Mail Box address
   * @return the address of the HyperLane Mail Box
   */
  function HL_MAIL_BOX() external view returns (IMailbox);

  /**
   * @notice method to get the current IGP address
   * @return the address of the HyperLane IGP
   */
  function IGP() external view returns (IInterchainGasPaymaster);

  /**
   * @notice method to get the trusted remote for a chain
   * @param chainId id of the chain to get the trusted remote address from
   * @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 bridgeChainId bridge native chain id
   */
  function nativeToInfraChainId(uint32 bridgeChainId) external 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 returns (uint32);
}

File 10 of 14 : ICrossChainController.sol
// 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;
}

File 11 of 14 : ICrossChainForwarder.sol
// 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);
}

File 12 of 14 : ICrossChainReceiver.sol
// 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;
}

File 13 of 14 : ChainIds.sol
// 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;
}

File 14 of 14 : Errors.sol
// 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
}

Settings
{
  "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": {}
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"crossChainController","type":"address"},{"internalType":"address","name":"mailBox","type":"address"},{"internalType":"address","name":"igp","type":"address"},{"components":[{"internalType":"address","name":"originForwarder","type":"address"},{"internalType":"uint256","name":"originChainId","type":"uint256"}],"internalType":"struct IHyperLaneAdapter.TrustedRemotesConfig[]","name":"trustedRemotes","type":"tuple[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"originChainId","type":"uint256"},{"indexed":true,"internalType":"address","name":"srcAddress","type":"address"},{"indexed":false,"internalType":"bytes","name":"_messageBody","type":"bytes"}],"name":"HLPayloadProcessed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"uint32","name":"destinationChainId","type":"uint32"},{"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":"CROSS_CHAIN_CONTROLLER","outputs":[{"internalType":"contract ICrossChainController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HL_MAIL_BOX","outputs":[{"internalType":"contract IMailbox","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"IGP","outputs":[{"internalType":"contract IInterchainGasPaymaster","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"destinationGasLimit","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":"uint32","name":"_origin","type":"uint32"},{"internalType":"bytes32","name":"_sender","type":"bytes32"},{"internalType":"bytes","name":"_messageBody","type":"bytes"}],"name":"handle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"infraChainId","type":"uint256"}],"name":"infraToNativeChainId","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint32","name":"nativeChainId","type":"uint32"}],"name":"nativeToInfraChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"}]

60e06040523480156200001157600080fd5b5060405162000f6838038062000f68833981016040819052620000349162000207565b6001600160a01b0380851660805283811660a052821660c052620000588162000062565b5050505062000362565b60005b8151811015620001725781818151811062000084576200008462000322565b602002602001015160000151600080848481518110620000a857620000a862000322565b602002602001015160200151815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b03160217905550818181518110620000fb57620000fb62000322565b6020026020010151600001516001600160a01b031682828151811062000125576200012562000322565b6020026020010151602001517fa214744f665691ef0eb9e4277cfa3c9198106c8925d6fa6880b6813f705c1aab60405160405180910390a380620001698162000338565b91505062000065565b5050565b80516001600160a01b03811681146200018e57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620001ce57620001ce62000193565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620001ff57620001ff62000193565b604052919050565b600080600080608085870312156200021e57600080fd5b620002298562000176565b935060206200023a81870162000176565b935060406200024b81880162000176565b60608801519094506001600160401b03808211156200026957600080fd5b818901915089601f8301126200027e57600080fd5b81518181111562000293576200029362000193565b620002a3858260051b01620001d4565b818152858101925060069190911b83018501908b821115620002c457600080fd5b928501925b81841015620003125784848d031215620002e35760008081fd5b620002ed620001a9565b620002f88562000176565b8152848701518782015283529284019291850191620002c9565b989b979a50959850505050505050565b634e487b7160e01b600052603260045260246000fd5b60006000198214156200035b57634e487b7160e01b600052601160045260246000fd5b5060010190565b60805160a05160c051610bb3620003b5600039600081816101970152818161032301526103fd0152600081816101210152818161025301526104d801526000818161014801526108490152610bb36000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063be8733381161005b578063be8733381461011c578063c495636614610143578063d68875811461016a578063fd6681f31461019257600080fd5b806336da7a061461008d57806356d5d475146100a2578063b66089ef146100b5578063b86a6161146100db575b600080fd5b6100a061009b3660046108cc565b6101b9565b005b6100a06100b03660046109c3565b6104b4565b6100c86100c3366004610a4a565b610641565b6040519081526020015b60405180910390f35b6101046100e9366004610a6c565b6000908152602081905260409020546001600160a01b031690565b6040516001600160a01b0390911681526020016100d2565b6101047f000000000000000000000000000000000000000000000000000000000000000081565b6101047f000000000000000000000000000000000000000000000000000000000000000081565b61017d610178366004610a6c565b610761565b60405163ffffffff90911681526020016100d2565b6101047f000000000000000000000000000000000000000000000000000000000000000081565b60006101c483610761565b604080518082019091526002815261313160f01b602082015290915063ffffffff821661020d5760405162461bcd60e51b81526004016102049190610ad2565b60405180910390fd5b50604080518082019091526002815261031360f41b60208201526001600160a01b03861661024e5760405162461bcd60e51b81526004016102049190610ad2565b5060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663fa31de0183610291896001600160a01b031690565b866040518463ffffffff1660e01b81526004016102b093929190610ae5565b6020604051808303816000875af11580156102cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102f39190610b13565b60405163a692979360e01b815263ffffffff84166004820152602481018790529091506000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a692979390604401602060405180830381865afa15801561036a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038e9190610b13565b90504781111560405180604001604052806002815260200161189960f11b815250906103cd5760405162461bcd60e51b81526004016102049190610ad2565b50604051630237e58360e31b81526004810183905263ffffffff84166024820152604481018790523060648201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906311bf2c189083906084016000604051808303818588803b15801561044a57600080fd5b505af115801561045e573d6000803e3d6000fd5b50505050508263ffffffff16876001600160a01b03167fbcdcb1b18653e9791181944aa4eb1ac394765d914e8ae8f002d72e3dce7a7245866040516104a39190610ad2565b60405180910390a350505050505050565b604080518082019091526002815261313560f01b6020820152336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105165760405162461bcd60e51b81526004016102049190610ad2565b5082600061052386610641565b604080518082019091526002815261313360f01b60208201529091508161055d5760405162461bcd60e51b81526004016102049190610ad2565b506000818152602081815260409182902054825180840190935260028352610c4d60f21b918301919091526001600160a01b038481169116146105b35760405162461bcd60e51b81526004016102049190610ad2565b506105f584848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250859250610832915050565b816001600160a01b0316817ff74dcc0277fde76753c314aef7999fbfe4658346037035d2c61733d2255a3cb38686604051610631929190610b2c565b60405180910390a3505050505050565b600063ffffffff82166001141561065a57506001919050565b63ffffffff821661a86a1415610673575061a86a919050565b63ffffffff82166089141561068a57506089919050565b63ffffffff821661a4b114156106a3575061a4b1919050565b63ffffffff8216600a14156106ba5750600a919050565b63ffffffff8216600514156106d157506005919050565b63ffffffff821661a86914156106ea575061a869919050565b63ffffffff82166101a4141561070357506101a4919050565b63ffffffff821662013881141561071e575062013881919050565b63ffffffff821662066eed1415610739575062066eed919050565b63ffffffff821662aa36a71415610754575062aa36a7919050565b506000919050565b919050565b6000600182141561077457506001919050565b61a86a821415610787575061a86a919050565b608982141561079857506089919050565b61a4b18214156107ab575061a4b1919050565b600a8214156107bc5750600a919050565b60058214156107cd57506005919050565b61a8698214156107e0575061a869919050565b6101a48214156107f357506101a4919050565b62013881821415610808575062013881919050565b62066eed82141561081d575062066eed919050565b62aa36a7821415610754575062aa36a7919050565b6040516376b42cad60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063ed68595a906108809085908590600401610b5b565b600060405180830381600087803b15801561089a57600080fd5b505af11580156108ae573d6000803e3d6000fd5b505050505050565b634e487b7160e01b600052604160045260246000fd5b600080600080608085870312156108e257600080fd5b84356001600160a01b03811681146108f957600080fd5b93506020850135925060408501359150606085013567ffffffffffffffff8082111561092457600080fd5b818701915087601f83011261093857600080fd5b81358181111561094a5761094a6108b6565b604051601f8201601f19908116603f01168101908382118183101715610972576109726108b6565b816040528281528a602084870101111561098b57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b803563ffffffff8116811461075c57600080fd5b600080600080606085870312156109d957600080fd5b6109e2856109af565b935060208501359250604085013567ffffffffffffffff80821115610a0657600080fd5b818701915087601f830112610a1a57600080fd5b813581811115610a2957600080fd5b886020828501011115610a3b57600080fd5b95989497505060200194505050565b600060208284031215610a5c57600080fd5b610a65826109af565b9392505050565b600060208284031215610a7e57600080fd5b5035919050565b6000815180845260005b81811015610aab57602081850181015186830182015201610a8f565b81811115610abd576000602083870101525b50601f01601f19169290920160200192915050565b602081526000610a656020830184610a85565b63ffffffff84168152826020820152606060408201526000610b0a6060830184610a85565b95945050505050565b600060208284031215610b2557600080fd5b5051919050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b604081526000610b6e6040830185610a85565b9050826020830152939250505056fea26469706673582212206d25d68eee9aa2ca1f28db2f64cbe23079f9b75da95b1cf7bf4ad8c1df1e0ed764736f6c634300080a00330000000000000000000000004d2f1c99bce324b9ba486d704a0235a754d188a2000000000000000000000000cc737a94fecaec165abcf12ded095bb13f037685000000000000000000000000f987d7edcb5890cb321437d8145e3d51131298b600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000002000000000000000000000000f640cea278e94708c358d79e5872afda5601011700000000000000000000000000000000000000000000000000000000000001a4000000000000000000000000f640cea278e94708c358d79e5872afda5601011700000000000000000000000000000000000000000000000000000000000001a4

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063be8733381161005b578063be8733381461011c578063c495636614610143578063d68875811461016a578063fd6681f31461019257600080fd5b806336da7a061461008d57806356d5d475146100a2578063b66089ef146100b5578063b86a6161146100db575b600080fd5b6100a061009b3660046108cc565b6101b9565b005b6100a06100b03660046109c3565b6104b4565b6100c86100c3366004610a4a565b610641565b6040519081526020015b60405180910390f35b6101046100e9366004610a6c565b6000908152602081905260409020546001600160a01b031690565b6040516001600160a01b0390911681526020016100d2565b6101047f000000000000000000000000cc737a94fecaec165abcf12ded095bb13f03768581565b6101047f0000000000000000000000004d2f1c99bce324b9ba486d704a0235a754d188a281565b61017d610178366004610a6c565b610761565b60405163ffffffff90911681526020016100d2565b6101047f000000000000000000000000f987d7edcb5890cb321437d8145e3d51131298b681565b60006101c483610761565b604080518082019091526002815261313160f01b602082015290915063ffffffff821661020d5760405162461bcd60e51b81526004016102049190610ad2565b60405180910390fd5b50604080518082019091526002815261031360f41b60208201526001600160a01b03861661024e5760405162461bcd60e51b81526004016102049190610ad2565b5060007f000000000000000000000000cc737a94fecaec165abcf12ded095bb13f0376856001600160a01b031663fa31de0183610291896001600160a01b031690565b866040518463ffffffff1660e01b81526004016102b093929190610ae5565b6020604051808303816000875af11580156102cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102f39190610b13565b60405163a692979360e01b815263ffffffff84166004820152602481018790529091506000906001600160a01b037f000000000000000000000000f987d7edcb5890cb321437d8145e3d51131298b6169063a692979390604401602060405180830381865afa15801561036a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038e9190610b13565b90504781111560405180604001604052806002815260200161189960f11b815250906103cd5760405162461bcd60e51b81526004016102049190610ad2565b50604051630237e58360e31b81526004810183905263ffffffff84166024820152604481018790523060648201527f000000000000000000000000f987d7edcb5890cb321437d8145e3d51131298b66001600160a01b0316906311bf2c189083906084016000604051808303818588803b15801561044a57600080fd5b505af115801561045e573d6000803e3d6000fd5b50505050508263ffffffff16876001600160a01b03167fbcdcb1b18653e9791181944aa4eb1ac394765d914e8ae8f002d72e3dce7a7245866040516104a39190610ad2565b60405180910390a350505050505050565b604080518082019091526002815261313560f01b6020820152336001600160a01b037f000000000000000000000000cc737a94fecaec165abcf12ded095bb13f03768516146105165760405162461bcd60e51b81526004016102049190610ad2565b5082600061052386610641565b604080518082019091526002815261313360f01b60208201529091508161055d5760405162461bcd60e51b81526004016102049190610ad2565b506000818152602081815260409182902054825180840190935260028352610c4d60f21b918301919091526001600160a01b038481169116146105b35760405162461bcd60e51b81526004016102049190610ad2565b506105f584848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250859250610832915050565b816001600160a01b0316817ff74dcc0277fde76753c314aef7999fbfe4658346037035d2c61733d2255a3cb38686604051610631929190610b2c565b60405180910390a3505050505050565b600063ffffffff82166001141561065a57506001919050565b63ffffffff821661a86a1415610673575061a86a919050565b63ffffffff82166089141561068a57506089919050565b63ffffffff821661a4b114156106a3575061a4b1919050565b63ffffffff8216600a14156106ba5750600a919050565b63ffffffff8216600514156106d157506005919050565b63ffffffff821661a86914156106ea575061a869919050565b63ffffffff82166101a4141561070357506101a4919050565b63ffffffff821662013881141561071e575062013881919050565b63ffffffff821662066eed1415610739575062066eed919050565b63ffffffff821662aa36a71415610754575062aa36a7919050565b506000919050565b919050565b6000600182141561077457506001919050565b61a86a821415610787575061a86a919050565b608982141561079857506089919050565b61a4b18214156107ab575061a4b1919050565b600a8214156107bc5750600a919050565b60058214156107cd57506005919050565b61a8698214156107e0575061a869919050565b6101a48214156107f357506101a4919050565b62013881821415610808575062013881919050565b62066eed82141561081d575062066eed919050565b62aa36a7821415610754575062aa36a7919050565b6040516376b42cad60e11b81526001600160a01b037f0000000000000000000000004d2f1c99bce324b9ba486d704a0235a754d188a2169063ed68595a906108809085908590600401610b5b565b600060405180830381600087803b15801561089a57600080fd5b505af11580156108ae573d6000803e3d6000fd5b505050505050565b634e487b7160e01b600052604160045260246000fd5b600080600080608085870312156108e257600080fd5b84356001600160a01b03811681146108f957600080fd5b93506020850135925060408501359150606085013567ffffffffffffffff8082111561092457600080fd5b818701915087601f83011261093857600080fd5b81358181111561094a5761094a6108b6565b604051601f8201601f19908116603f01168101908382118183101715610972576109726108b6565b816040528281528a602084870101111561098b57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b803563ffffffff8116811461075c57600080fd5b600080600080606085870312156109d957600080fd5b6109e2856109af565b935060208501359250604085013567ffffffffffffffff80821115610a0657600080fd5b818701915087601f830112610a1a57600080fd5b813581811115610a2957600080fd5b886020828501011115610a3b57600080fd5b95989497505060200194505050565b600060208284031215610a5c57600080fd5b610a65826109af565b9392505050565b600060208284031215610a7e57600080fd5b5035919050565b6000815180845260005b81811015610aab57602081850181015186830182015201610a8f565b81811115610abd576000602083870101525b50601f01601f19169290920160200192915050565b602081526000610a656020830184610a85565b63ffffffff84168152826020820152606060408201526000610b0a6060830184610a85565b95945050505050565b600060208284031215610b2557600080fd5b5051919050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b604081526000610b6e6040830185610a85565b9050826020830152939250505056fea26469706673582212206d25d68eee9aa2ca1f28db2f64cbe23079f9b75da95b1cf7bf4ad8c1df1e0ed764736f6c634300080a0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000004d2f1c99bce324b9ba486d704a0235a754d188a2000000000000000000000000cc737a94fecaec165abcf12ded095bb13f037685000000000000000000000000f987d7edcb5890cb321437d8145e3d51131298b600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000002000000000000000000000000f640cea278e94708c358d79e5872afda5601011700000000000000000000000000000000000000000000000000000000000001a4000000000000000000000000f640cea278e94708c358d79e5872afda5601011700000000000000000000000000000000000000000000000000000000000001a4

-----Decoded View---------------
Arg [0] : crossChainController (address): 0x4d2F1C99BCE324B9Ba486d704A0235A754D188a2
Arg [1] : mailBox (address): 0xCC737a94FecaeC165AbCf12dED095BB13F037685
Arg [2] : igp (address): 0xF987d7edcb5890cB321437d8145E3D51131298b6
Arg [3] : trustedRemotes (tuple[]): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]

-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 0000000000000000000000004d2f1c99bce324b9ba486d704a0235a754d188a2
Arg [1] : 000000000000000000000000cc737a94fecaec165abcf12ded095bb13f037685
Arg [2] : 000000000000000000000000f987d7edcb5890cb321437d8145e3d51131298b6
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [5] : 000000000000000000000000f640cea278e94708c358d79e5872afda56010117
Arg [6] : 00000000000000000000000000000000000000000000000000000000000001a4
Arg [7] : 000000000000000000000000f640cea278e94708c358d79e5872afda56010117
Arg [8] : 00000000000000000000000000000000000000000000000000000000000001a4


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits

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.