Overview
ETH Balance
0.000001 ETH
Eth Value
Less Than $0.01 (@ $2,377.93/ETH)More Info
Private Name Tags
ContractCreator
Latest 5 from a total of 5 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Set Refund Addre... | 17674332 | 594 days ago | IN | 0 ETH | 0.00043052 | ||||
Propose New Owne... | 17672420 | 594 days ago | IN | 0 ETH | 0.00169092 | ||||
Set Refund Addre... | 17672319 | 594 days ago | IN | 0 ETH | 0.00076406 | ||||
Transfer | 17641273 | 599 days ago | IN | 0.000001 ETH | 0.00037229 | ||||
Set Mirror Conne... | 17640476 | 599 days ago | IN | 0 ETH | 0.00128471 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
18812582 | 435 days ago | 0.00022832 ETH | ||||
18812582 | 435 days ago | 0.00022832 ETH | ||||
18811987 | 435 days ago | 0.00022832 ETH | ||||
18811987 | 435 days ago | 0.00022832 ETH | ||||
18811419 | 435 days ago | 0.00022832 ETH | ||||
18811419 | 435 days ago | 0.00022832 ETH | ||||
18810802 | 435 days ago | 0.00022832 ETH | ||||
18810802 | 435 days ago | 0.00022832 ETH | ||||
18810206 | 435 days ago | 0.00022832 ETH | ||||
18810206 | 435 days ago | 0.00022832 ETH | ||||
18809611 | 435 days ago | 0.00022832 ETH | ||||
18809611 | 435 days ago | 0.00022832 ETH | ||||
18809013 | 435 days ago | 0.00022832 ETH | ||||
18809013 | 435 days ago | 0.00022832 ETH | ||||
18806045 | 436 days ago | 0.00023023 ETH | ||||
18806045 | 436 days ago | 0.00023023 ETH | ||||
18805449 | 436 days ago | 0.00023023 ETH | ||||
18805449 | 436 days ago | 0.00023023 ETH | ||||
18804857 | 436 days ago | 0.00023023 ETH | ||||
18804857 | 436 days ago | 0.00023023 ETH | ||||
18804270 | 436 days ago | 0.00023023 ETH | ||||
18804270 | 436 days ago | 0.00023023 ETH | ||||
18803677 | 436 days ago | 0.00023023 ETH | ||||
18803677 | 436 days ago | 0.00023023 ETH | ||||
18803081 | 436 days ago | 0.00023023 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
WormholeHubConnector
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity 0.8.17; import {IRootManager} from "../../interfaces/IRootManager.sol"; import {IWormholeReceiver} from "../../interfaces/ambs/wormhole/IWormholeReceiver.sol"; import {HubConnector, Connector} from "../HubConnector.sol"; import {BaseWormhole} from "./BaseWormhole.sol"; contract WormholeHubConnector is HubConnector, BaseWormhole, IWormholeReceiver { // ============ Constructor ============ constructor( uint32 _domain, uint32 _mirrorDomain, address _amb, address _rootManager, address _mirrorConnector, uint256 _gasCap, uint16 _mirrorWormholeChainId ) HubConnector(_domain, _mirrorDomain, _amb, _rootManager, _mirrorConnector) BaseWormhole(_gasCap, _mirrorWormholeChainId) {} // ============ Override Fns ============ function _verifySender(address _expected) internal view override returns (bool) { return _verifySender(mirrorConnector, _expected); } // ============ Public fns ============ /** * @notice This function is called to receive messages through the wormhole relayer module * https://book.wormhole.com/technical/evm/relayer.html * @dev This is defined here instead of the `BaseWormhole` to avoid storing AMB values twice. */ function receiveWormholeMessages( bytes memory _payload, bytes[] memory, // additionalVaas, bytes32 _sourceAddress, uint16 _sourceChain, bytes32 _deliveryHash ) public payable override { _wormholeSanityChecks(_sourceChain, AMB, _deliveryHash); _processMessageFrom(_fromWormholeFormat(_sourceAddress), _payload); } // ============ Private fns ============ /** * @dev Handles an incoming `outboundRoot` */ function _processMessageFrom(address _sender, bytes memory _data) internal override(BaseWormhole) { // enforce this came from connector on l2 require(_verifySender(_sender), "!l2Connector"); // get the data (should be the outbound root) require(_data.length == 32, "!length"); // set the outbound root for BSC domain IRootManager(ROOT_MANAGER).aggregate(MIRROR_DOMAIN, bytes32(_data)); emit MessageProcessed(_data, msg.sender); } function _sendMessage(bytes memory _data, bytes memory _encodedData) internal override { _sendMessage(AMB, mirrorConnector, _data, _encodedData); } }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity 0.8.17; import {ProposedOwnable} from "../../shared/ProposedOwnable.sol"; import {IConnector} from "../interfaces/IConnector.sol"; /** * @title Connector * @author Connext Labs, Inc. * @notice This contract has the messaging interface functions used by all connectors. * * @dev This contract stores information about mirror connectors, but can be used as a * base for contracts that do not have a mirror (i.e. the connector handling messaging on * mainnet). In this case, the `mirrorConnector` and `MIRROR_DOMAIN` * will be empty * * @dev If ownership is renounced, this contract will be unable to update its `mirrorConnector` * or `mirrorGas` */ abstract contract Connector is ProposedOwnable, IConnector { // ========== Custom Errors =========== error Connector__processMessage_notUsed(); // ============ Events ============ event NewConnector( uint32 indexed domain, uint32 indexed mirrorDomain, address amb, address rootManager, address mirrorConnector ); event MirrorConnectorUpdated(address previous, address current); // ============ Public Storage ============ /** * @notice The domain of this Messaging (i.e. Connector) contract. */ uint32 public immutable DOMAIN; /** * @notice Address of the AMB on this domain. */ address public immutable AMB; /** * @notice RootManager contract address. */ address public immutable ROOT_MANAGER; /** * @notice The domain of the corresponding messaging (i.e. Connector) contract. */ uint32 public immutable MIRROR_DOMAIN; /** * @notice Connector on L2 for L1 connectors, and vice versa. */ address public mirrorConnector; // ============ Modifiers ============ /** * @notice Errors if the msg.sender is not the registered AMB */ modifier onlyAMB() { require(msg.sender == AMB, "!AMB"); _; } /** * @notice Errors if the msg.sender is not the registered ROOT_MANAGER */ modifier onlyRootManager() { // NOTE: RootManager will be zero address for spoke connectors. // Only root manager can dispatch a message to spokes/L2s via the hub connector. require(msg.sender == ROOT_MANAGER, "!rootManager"); _; } // ============ Constructor ============ /** * @notice Creates a new HubConnector instance * @dev The connectors are deployed such that there is one on each side of an AMB (i.e. * for optimism, there is one connector on optimism and one connector on mainnet) * @param _domain The domain this connector lives on * @param _mirrorDomain The spoke domain * @param _amb The address of the amb on the domain this connector lives on * @param _rootManager The address of the RootManager on mainnet * @param _mirrorConnector The address of the spoke connector */ constructor( uint32 _domain, uint32 _mirrorDomain, address _amb, address _rootManager, address _mirrorConnector ) ProposedOwnable() { // set the owner _setOwner(msg.sender); // sanity checks on values require(_domain != 0, "empty domain"); require(_rootManager != address(0), "empty rootManager"); // see note at top of contract on why the mirror values are not sanity checked // set immutables DOMAIN = _domain; AMB = _amb; ROOT_MANAGER = _rootManager; MIRROR_DOMAIN = _mirrorDomain; // set mutables if defined if (_mirrorConnector != address(0)) { _setMirrorConnector(_mirrorConnector); } emit NewConnector(_domain, _mirrorDomain, _amb, _rootManager, _mirrorConnector); } // ============ Receivable ============ /** * @notice Connectors may need to receive native asset to handle fees when sending a * message */ receive() external payable {} // ============ Admin Functions ============ /** * @notice Sets the address of the l2Connector for this domain */ function setMirrorConnector(address _mirrorConnector) public onlyOwner { _setMirrorConnector(_mirrorConnector); } // ============ Public Functions ============ /** * @notice Processes a message received by an AMB * @dev This is called by AMBs to process messages originating from mirror connector */ function processMessage(bytes memory _data) external virtual onlyAMB { _processMessage(_data); emit MessageProcessed(_data, msg.sender); } /** * @notice Checks the cross domain sender for a given address */ function verifySender(address _expected) external returns (bool) { return _verifySender(_expected); } // ============ Virtual Functions ============ /** * @notice This function is used by the Connext contract on the l2 domain to send a message to the * l1 domain (i.e. called by Connext on optimism to send a message to mainnet with roots) * @param _data The contents of the message * @param _encodedData Data used to send the message; specific to connector */ function _sendMessage(bytes memory _data, bytes memory _encodedData) internal virtual; /** * @notice This function is used by the AMBs to handle incoming messages. Should store the latest * root generated on the l2 domain. */ function _processMessage( bytes memory /* _data */ ) internal virtual { // By default, reverts. This is to ensure the call path is not used unless this function is // overridden by the inheriting class revert Connector__processMessage_notUsed(); } /** * @notice Verify that the msg.sender is the correct AMB contract, and that the message's origin sender * is the expected address. * @dev Should be overridden by the implementing Connector contract. */ function _verifySender(address _expected) internal virtual returns (bool); // ============ Private Functions ============ function _setMirrorConnector(address _mirrorConnector) internal virtual { emit MirrorConnectorUpdated(mirrorConnector, _mirrorConnector); mirrorConnector = _mirrorConnector; } }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity 0.8.17; import {ProposedOwnable} from "../../shared/ProposedOwnable.sol"; abstract contract GasCap is ProposedOwnable { // ============ Storage ============ /** * @notice The gnosis amb requires destination gas to be specified on the origin. * The gas used will be passed in by the relayer to allow for real-time estimates, * but will be capped at the admin-set cap. */ uint256 gasCap; // ============ Events ============ /** * @notice Emitted when admin updates the gas cap * @param _previous The starting value * @param _updated The final value */ event GasCapUpdated(uint256 _previous, uint256 _updated); // ============ Constructor ============ constructor(uint256 _gasCap) { _setGasCap(_gasCap); } // ============ Admin Fns ============ function setGasCap(uint256 _gasCap) public onlyOwner { _setGasCap(_gasCap); } // ============ Internal Fns ============ /** * @notice Used (by admin) to update the gas cap * @param _gasCap The new value */ function _setGasCap(uint256 _gasCap) internal { emit GasCapUpdated(gasCap, _gasCap); gasCap = _gasCap; } /** * @notice Used to get the gas to use. Will be the original value IFF it * is less than the cap * @param _gas The proposed gas value */ function _getGas(uint256 _gas) internal view returns (uint256) { if (_gas > gasCap) { _gas = gasCap; } return _gas; } }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity 0.8.17; import {Connector} from "./Connector.sol"; /** * @title HubConnector * @author Connext Labs, Inc. * @notice This contract implements the messaging functions needed on the hub-side of a given AMB. * The HubConnector has a limited set of functionality compared to the SpokeConnector, namely that * it contains no logic to store or prove messages. * * @dev This contract should be deployed on the hub-side of an AMB (i.e. on L1), and contracts * which extend this should implement the virtual functions defined in the BaseConnector class */ abstract contract HubConnector is Connector { /** * @notice Creates a new HubConnector instance * @dev The connectors are deployed such that there is one on each side of an AMB (i.e. * for optimism, there is one connector on optimism and one connector on mainnet) * @param _domain The domain this connector lives on * @param _mirrorDomain The spoke domain * @param _amb The address of the amb on the domain this connector lives on * @param _rootManager The address of the RootManager on mainnet * @param _mirrorConnector The address of the spoke connector */ constructor( uint32 _domain, uint32 _mirrorDomain, address _amb, address _rootManager, address _mirrorConnector ) Connector(_domain, _mirrorDomain, _amb, _rootManager, _mirrorConnector) {} // ============ Public fns ============ /** * @notice Sends a message over the amb * @dev This is called by the root manager *only* on mainnet to propagate the aggregate root */ function sendMessage(bytes memory _data, bytes memory _encodedData) external payable onlyRootManager { _sendMessage(_data, _encodedData); emit MessageSent(_data, _encodedData, msg.sender); } }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity 0.8.17; import {IWormholeRelayer} from "../../interfaces/ambs/wormhole/IWormholeRelayer.sol"; import {GasCap} from "../GasCap.sol"; abstract contract BaseWormhole is GasCap { // ============ Events ============ event RefundAddressUpdated(address indexed previous, address indexed updated); // ============ Storage ============ /** * @notice The wormhole id for the mirror network */ uint16 public immutable MIRROR_WORMHOLE_ID; /** * @notice The address on this chain any refunds from wormhole fees will be * sent to */ address public refundAddress; /** * @notice Mapping of processed messages from wormhole. * @dev Used for replay protection. */ mapping(bytes32 => bool) public processedWhMessages; // ============ Constructor ============ constructor(uint256 _gasCap, uint16 _mirrorWormholeChainId) GasCap(_gasCap) { MIRROR_WORMHOLE_ID = _mirrorWormholeChainId; _setRefundAddress(msg.sender); } // ============ Admin fns ============ /** * @notice Allows the owner to set a new address to collect excess wormhole fees. * @param _updated The updated refund address */ function setRefundAddress(address _updated) public onlyOwner { _setRefundAddress(_updated); } // ============ Public fns ============ /** * @dev calculcate gas to call `receiveWormholeMessages` on target chain * https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/relayer/deliveryProvider/DeliveryProvider.sol */ function quoteEVMDeliveryPrice(uint256 _gasLimit, address _amb) public view returns (uint256 _cost) { // First Get the gas, if it is more than the cap use the cap // And calculcate delievery price with gasCap (_cost, ) = IWormholeRelayer(_amb).quoteEVMDeliveryPrice(MIRROR_WORMHOLE_ID, 0, _getGas(_gasLimit)); } // ============ Private fns ============ function _setRefundAddress(address _updated) internal { require(_updated != refundAddress, "!changed"); emit RefundAddressUpdated(refundAddress, _updated); refundAddress = _updated; } /** * @dev Asserts the sender of a cross domain message */ function _verifySender(address _mirrorConnector, address _expected) internal pure returns (bool) { return _mirrorConnector == _expected; } // DO NOT override _processMessage, should revert from `Connector` class. All messages must use the _processMessageFrom function /** * @notice This function is called to handle incoming messages. Should store the latest * root generated on the l2 domain. */ function _processMessageFrom(address _sender, bytes memory _data) internal virtual; /** * @notice Performs sanity checks specific to receiving wormhole messages. * @dev Checks the sender is the AMB, the chain is the mirror, and replay. */ function _wormholeSanityChecks(uint16 _sourceChain, address _amb, bytes32 _deliveryHash) internal { require(_sourceChain == MIRROR_WORMHOLE_ID, "!source chain"); require(msg.sender == _amb, "!relayer"); // Check that the VAA hasn't already been processed (replay protection) require(!processedWhMessages[_deliveryHash], "already processed"); // Add the VAA to processed messages so it can't be replayed // you can alternatively rely on the replay protection // of something like transferWithPayload from the Token Bridge module processedWhMessages[_deliveryHash] = true; } /** * @dev send message via wormhole. * https://book.wormhole.com/technical/evm/relayer.html#sending-messages */ function _sendMessage( address _amb, address _mirrorConnector, bytes memory _data, bytes memory _encodedData ) internal { // Should always be sending a merkle root require(_data.length == 32, "!data length"); // Should include gas limit info in specialized calldata require(_encodedData.length == 32, "!encoded data length"); //calculate cost to deliver message uint256 gasLimit = abi.decode(_encodedData, (uint256)); uint256 deliveryCost = quoteEVMDeliveryPrice(gasLimit, _amb); require(deliveryCost == msg.value, "!msg.value"); // publish delivery request IWormholeRelayer(_amb).sendPayloadToEvm{value: deliveryCost}( MIRROR_WORMHOLE_ID, _mirrorConnector, _data, 0, gasLimit, MIRROR_WORMHOLE_ID, // refundChain refundAddress // refundAddress ); } /** * @notice Converts from wormhole 32 byte identifier format to evm address */ function _fromWormholeFormat(bytes32 _whFormatAddress) internal pure returns (address) { require(uint256(_whFormatAddress) >> 160 == 0, "!evm address"); return address(uint160(uint256(_whFormatAddress))); } }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity 0.8.17; import {IProposedOwnable} from "../../shared/interfaces/IProposedOwnable.sol"; /** * @notice This interface is what the Connext contract will send and receive messages through. * The messaging layer should conform to this interface, and should be interchangeable (i.e. * could be Nomad or a generic AMB under the hood). * * @dev This uses the nomad format to ensure nomad can be added in as it comes back online. * * Flow from transfer from polygon to optimism: * 1. User calls `xcall` with destination specified * 2. This will swap in to the bridge assets * 3. The swapped assets will get burned * 4. The Connext contract will call `dispatch` on the messaging contract to add the transfer * to the root * 5. [At some time interval] Relayers call `send` to send the current root from polygon to * mainnet. This is done on all "spoke" domains. * 6. [At some time interval] Relayers call `propagate` [better name] on mainnet, this generates a new merkle * root from all of the AMBs * - This function must be able to read root data from all AMBs and aggregate them into a single merkle * tree root * - Will send the mixed root from all chains back through the respective AMBs to all other chains * 7. AMB will call `update` to update the latest root on the messaging contract on spoke domains * 8. [At any point] Relayers can call `proveAndProcess` to prove inclusion of dispatched message, and call * process on the `Connext` contract * 9. Takes minted bridge tokens and credits the LP * * AMB requirements: * - Access `msg.sender` both from mainnet -> spoke and vice versa * - Ability to read *our root* from the AMB * * AMBs: * - PoS bridge from polygon * - arbitrum bridge * - optimism bridge * - gnosis chain * - bsc (use multichain for messaging) */ interface IConnector is IProposedOwnable { // ============ Events ============ /** * @notice Emitted whenever a message is successfully sent over an AMB * @param data The contents of the message * @param encodedData Data used to send the message; specific to connector * @param caller Who called the function (sent the message) */ event MessageSent(bytes data, bytes encodedData, address caller); /** * @notice Emitted whenever a message is successfully received over an AMB * @param data The contents of the message * @param caller Who called the function */ event MessageProcessed(bytes data, address caller); // ============ Public fns ============ function processMessage(bytes memory _data) external; function verifySender(address _expected) external returns (bool); }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity 0.8.17; interface IRootManager { /** * @notice This is called by relayers to generate + send the mixed root from mainnet via AMB to * spoke domains. * @dev This must read information for the root from the registered AMBs. */ function propagate( address[] calldata _connectors, uint256[] calldata _fees, bytes[] memory _encodedData ) external payable; /** * @notice Called by the connectors for various domains on the hub to aggregate their latest * inbound root. * @dev This must read information for the root from the registered AMBs */ function aggregate(uint32 _domain, bytes32 _outbound) external; }
// SPDX-License-Identifier: Apache 2 pragma solidity ^0.8.0; /** * @notice Interface for a contract which can receive Wormhole messages. */ interface IWormholeReceiver { /** * @notice When a `send` is performed with this contract as the target, this function will be * invoked by the WormholeRelayer contract * * NOTE: This function should be restricted such that only the Wormhole Relayer contract can call it. * * We also recommend that this function: * - Stores all received `deliveryHash`s in a mapping `(bytes32 => bool)`, and * on every call, checks that deliveryHash has not already been stored in the * map (This is to prevent other users maliciously trying to relay the same message) * - Checks that `sourceChain` and `sourceAddress` are indeed who * you expect to have requested the calling of `send` or `forward` on the source chain * * The invocation of this function corresponding to the `send` request will have msg.value equal * to the receiverValue specified in the send request. * * If the invocation of this function reverts or exceeds the gas limit * specified by the send requester, this delivery will result in a `ReceiverFailure`. * * @param payload - an arbitrary message which was included in the delivery by the * requester. * @param additionalVaas - Additional VAAs which were requested to be included in this delivery. * They are guaranteed to all be included and in the same order as was specified in the * delivery request. * @param sourceAddress - the (wormhole format) address on the sending chain which requested * this delivery. * @param sourceChain - the wormhole chain ID where this delivery was requested. * @param deliveryHash - the VAA hash of the deliveryVAA. * * NOTE: These signedVaas are NOT verified by the Wormhole core contract prior to being provided * to this call. Always make sure `parseAndVerify()` is called on the Wormhole core contract * before trusting the content of a raw VAA, otherwise the VAA may be invalid or malicious. */ function receiveWormholeMessages( bytes memory payload, bytes[] memory additionalVaas, bytes32 sourceAddress, uint16 sourceChain, bytes32 deliveryHash ) external payable; }
// SPDX-License-Identifier: Apache 2 pragma solidity ^0.8.0; /** * @title WormholeRelayer * @author * @notice This project allows developers to build cross-chain applications powered by Wormhole without needing to * write and run their own relaying infrastructure * * We implement the IWormholeRelayer interface that allows users to request a delivery provider to relay a payload (and/or additional VAAs) * to a chain and address of their choice. */ /** * @notice VaaKey identifies a wormhole message * * @custom:member chainId Wormhole chain ID of the chain where this VAA was emitted from * @custom:member emitterAddress Address of the emitter of the VAA, in Wormhole bytes32 format * @custom:member sequence Sequence number of the VAA */ struct VaaKey { uint16 chainId; bytes32 emitterAddress; uint64 sequence; } interface IWormholeRelayerBase { event SendEvent(uint64 indexed sequence, uint256 deliveryQuote, uint256 paymentForExtraReceiverValue); function getRegisteredWormholeRelayerContract(uint16 chainId) external view returns (bytes32); } /** * @title IWormholeRelayerSend * @notice The interface to request deliveries */ interface IWormholeRelayerSend is IWormholeRelayerBase { /** * @notice Publishes an instruction for the default delivery provider * to relay a payload to the address `targetAddress` on chain `targetChain` * with gas limit `gasLimit` and `msg.value` equal to `receiverValue` * * `targetAddress` must implement the IWormholeReceiver interface * * This function must be called with `msg.value` equal to `quoteEVMDeliveryPrice(targetChain, receiverValue, gasLimit)` * * Any refunds (from leftover gas) will be paid to the delivery provider. In order to receive the refunds, use the `sendPayloadToEvm` function * with `refundChain` and `refundAddress` as parameters * * @param targetChain in Wormhole Chain ID format * @param targetAddress address to call on targetChain (that implements IWormholeReceiver) * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress` * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param gasLimit gas limit with which to call `targetAddress`. * @return sequence sequence number of published VAA containing delivery instructions */ function sendPayloadToEvm( uint16 targetChain, address targetAddress, bytes memory payload, uint256 receiverValue, uint256 gasLimit ) external payable returns (uint64 sequence); /** * @notice Publishes an instruction for the default delivery provider * to relay a payload to the address `targetAddress` on chain `targetChain` * with gas limit `gasLimit` and `msg.value` equal to `receiverValue` * * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain` * `targetAddress` must implement the IWormholeReceiver interface * * This function must be called with `msg.value` equal to `quoteEVMDeliveryPrice(targetChain, receiverValue, gasLimit)` * * @param targetChain in Wormhole Chain ID format * @param targetAddress address to call on targetChain (that implements IWormholeReceiver) * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress` * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param gasLimit gas limit with which to call `targetAddress`. Any units of gas unused will be refunded according to the * `targetChainRefundPerGasUnused` rate quoted by the delivery provider * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format * @param refundAddress The address on `refundChain` to deliver any refund to * @return sequence sequence number of published VAA containing delivery instructions */ function sendPayloadToEvm( uint16 targetChain, address targetAddress, bytes memory payload, uint256 receiverValue, uint256 gasLimit, uint16 refundChain, address refundAddress ) external payable returns (uint64 sequence); /** * @notice Publishes an instruction for the default delivery provider * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain` * with gas limit `gasLimit` and `msg.value` equal to `receiverValue` * * `targetAddress` must implement the IWormholeReceiver interface * * This function must be called with `msg.value` equal to `quoteEVMDeliveryPrice(targetChain, receiverValue, gasLimit)` * * Any refunds (from leftover gas) will be paid to the delivery provider. In order to receive the refunds, use the `sendVaasToEvm` function * with `refundChain` and `refundAddress` as parameters * * @param targetChain in Wormhole Chain ID format * @param targetAddress address to call on targetChain (that implements IWormholeReceiver) * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress` * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param gasLimit gas limit with which to call `targetAddress`. * @param vaaKeys Additional VAAs to pass in as parameter in call to `targetAddress` * @return sequence sequence number of published VAA containing delivery instructions */ function sendVaasToEvm( uint16 targetChain, address targetAddress, bytes memory payload, uint256 receiverValue, uint256 gasLimit, VaaKey[] memory vaaKeys ) external payable returns (uint64 sequence); /** * @notice Publishes an instruction for the default delivery provider * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain` * with gas limit `gasLimit` and `msg.value` equal to `receiverValue` * * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain` * `targetAddress` must implement the IWormholeReceiver interface * * This function must be called with `msg.value` equal to `quoteEVMDeliveryPrice(targetChain, receiverValue, gasLimit)` * * @param targetChain in Wormhole Chain ID format * @param targetAddress address to call on targetChain (that implements IWormholeReceiver) * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress` * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param gasLimit gas limit with which to call `targetAddress`. Any units of gas unused will be refunded according to the * `targetChainRefundPerGasUnused` rate quoted by the delivery provider * @param vaaKeys Additional VAAs to pass in as parameter in call to `targetAddress` * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format * @param refundAddress The address on `refundChain` to deliver any refund to * @return sequence sequence number of published VAA containing delivery instructions */ function sendVaasToEvm( uint16 targetChain, address targetAddress, bytes memory payload, uint256 receiverValue, uint256 gasLimit, VaaKey[] memory vaaKeys, uint16 refundChain, address refundAddress ) external payable returns (uint64 sequence); /** * @notice Publishes an instruction for the delivery provider at `deliveryProviderAddress` * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain` * with gas limit `gasLimit` and `msg.value` equal to * receiverValue + (arbitrary amount that is paid for by paymentForExtraReceiverValue of this chain's wei) in targetChain wei. * * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain` * `targetAddress` must implement the IWormholeReceiver interface * * This function must be called with `msg.value` equal to * quoteEVMDeliveryPrice(targetChain, receiverValue, gasLimit, deliveryProviderAddress) + paymentForExtraReceiverValue * * @param targetChain in Wormhole Chain ID format * @param targetAddress address to call on targetChain (that implements IWormholeReceiver) * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress` * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param paymentForExtraReceiverValue amount (in current chain currency units) to spend on extra receiverValue * (in addition to the `receiverValue` specified) * @param gasLimit gas limit with which to call `targetAddress`. Any units of gas unused will be refunded according to the * `targetChainRefundPerGasUnused` rate quoted by the delivery provider * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format * @param refundAddress The address on `refundChain` to deliver any refund to * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider * @param vaaKeys Additional VAAs to pass in as parameter in call to `targetAddress` * @param consistencyLevel Consistency level with which to publish the delivery instructions - see * https://book.wormhole.com/wormhole/3_coreLayerContracts.html?highlight=consistency#consistency-levels * @return sequence sequence number of published VAA containing delivery instructions */ function sendToEvm( uint16 targetChain, address targetAddress, bytes memory payload, uint256 receiverValue, uint256 paymentForExtraReceiverValue, uint256 gasLimit, uint16 refundChain, address refundAddress, address deliveryProviderAddress, VaaKey[] memory vaaKeys, uint8 consistencyLevel ) external payable returns (uint64 sequence); /** * @notice Publishes an instruction for the delivery provider at `deliveryProviderAddress` * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain` * with `msg.value` equal to * receiverValue + (arbitrary amount that is paid for by paymentForExtraReceiverValue of this chain's wei) in targetChain wei. * * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain` * `targetAddress` must implement the IWormholeReceiver interface * * This function must be called with `msg.value` equal to * quoteDeliveryPrice(targetChain, receiverValue, encodedExecutionParameters, deliveryProviderAddress) + paymentForExtraReceiverValue * * @param targetChain in Wormhole Chain ID format * @param targetAddress address to call on targetChain (that implements IWormholeReceiver), in Wormhole bytes32 format * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress` * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param paymentForExtraReceiverValue amount (in current chain currency units) to spend on extra receiverValue * (in addition to the `receiverValue` specified) * @param encodedExecutionParameters encoded information on how to execute delivery that may impact pricing * e.g. for version EVM_V1, this is a struct that encodes the `gasLimit` with which to call `targetAddress` * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format * @param refundAddress The address on `refundChain` to deliver any refund to, in Wormhole bytes32 format * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider * @param vaaKeys Additional VAAs to pass in as parameter in call to `targetAddress` * @param consistencyLevel Consistency level with which to publish the delivery instructions - see * https://book.wormhole.com/wormhole/3_coreLayerContracts.html?highlight=consistency#consistency-levels * @return sequence sequence number of published VAA containing delivery instructions */ function send( uint16 targetChain, bytes32 targetAddress, bytes memory payload, uint256 receiverValue, uint256 paymentForExtraReceiverValue, bytes memory encodedExecutionParameters, uint16 refundChain, bytes32 refundAddress, address deliveryProviderAddress, VaaKey[] memory vaaKeys, uint8 consistencyLevel ) external payable returns (uint64 sequence); /** * @notice Performs the same function as a `send`, except: * 1) Can only be used during a delivery (i.e. in execution of `receiveWormholeMessages`) * 2) Is paid for (along with any other calls to forward) by (any msg.value passed in) + (refund leftover from current delivery) * 3) Only executes after `receiveWormholeMessages` is completed (and thus does not return a sequence number) * * The refund from the delivery currently in progress will not be sent to the user; it will instead * be paid to the delivery provider to perform the instruction specified here * * Publishes an instruction for the same delivery provider (or default, if the same one doesn't support the new target chain) * to relay a payload to the address `targetAddress` on chain `targetChain` * with gas limit `gasLimit` and with `msg.value` equal to `receiverValue` * * The following equation must be satisfied (sum_f indicates summing over all forwards requested in `receiveWormholeMessages`): * (refund amount from current execution of receiveWormholeMessages) + sum_f [msg.value_f] * >= sum_f [quoteEVMDeliveryPrice(targetChain_f, receiverValue_f, gasLimit_f)] * * The difference between the two sides of the above inequality will be added to `paymentForExtraReceiverValue` of the first forward requested * * Any refunds (from leftover gas) from this forward will be paid to the same refundChain and refundAddress specified for the current delivery. * * @param targetChain in Wormhole Chain ID format * @param targetAddress address to call on targetChain (that implements IWormholeReceiver), in Wormhole bytes32 format * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress` * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param gasLimit gas limit with which to call `targetAddress`. */ function forwardPayloadToEvm( uint16 targetChain, address targetAddress, bytes memory payload, uint256 receiverValue, uint256 gasLimit ) external payable; /** * @notice Performs the same function as a `send`, except: * 1) Can only be used during a delivery (i.e. in execution of `receiveWormholeMessages`) * 2) Is paid for (along with any other calls to forward) by (any msg.value passed in) + (refund leftover from current delivery) * 3) Only executes after `receiveWormholeMessages` is completed (and thus does not return a sequence number) * * The refund from the delivery currently in progress will not be sent to the user; it will instead * be paid to the delivery provider to perform the instruction specified here * * Publishes an instruction for the same delivery provider (or default, if the same one doesn't support the new target chain) * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain` * with gas limit `gasLimit` and with `msg.value` equal to `receiverValue` * * The following equation must be satisfied (sum_f indicates summing over all forwards requested in `receiveWormholeMessages`): * (refund amount from current execution of receiveWormholeMessages) + sum_f [msg.value_f] * >= sum_f [quoteEVMDeliveryPrice(targetChain_f, receiverValue_f, gasLimit_f)] * * The difference between the two sides of the above inequality will be added to `paymentForExtraReceiverValue` of the first forward requested * * Any refunds (from leftover gas) from this forward will be paid to the same refundChain and refundAddress specified for the current delivery. * * @param targetChain in Wormhole Chain ID format * @param targetAddress address to call on targetChain (that implements IWormholeReceiver), in Wormhole bytes32 format * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress` * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param gasLimit gas limit with which to call `targetAddress`. * @param vaaKeys Additional VAAs to pass in as parameter in call to `targetAddress` */ function forwardVaasToEvm( uint16 targetChain, address targetAddress, bytes memory payload, uint256 receiverValue, uint256 gasLimit, VaaKey[] memory vaaKeys ) external payable; /** * @notice Performs the same function as a `send`, except: * 1) Can only be used during a delivery (i.e. in execution of `receiveWormholeMessages`) * 2) Is paid for (along with any other calls to forward) by (any msg.value passed in) + (refund leftover from current delivery) * 3) Only executes after `receiveWormholeMessages` is completed (and thus does not return a sequence number) * * The refund from the delivery currently in progress will not be sent to the user; it will instead * be paid to the delivery provider to perform the instruction specified here * * Publishes an instruction for the delivery provider at `deliveryProviderAddress` * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain` * with gas limit `gasLimit` and with `msg.value` equal to * receiverValue + (arbitrary amount that is paid for by paymentForExtraReceiverValue of this chain's wei) in targetChain wei. * * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain` * `targetAddress` must implement the IWormholeReceiver interface * * The following equation must be satisfied (sum_f indicates summing over all forwards requested in `receiveWormholeMessages`): * (refund amount from current execution of receiveWormholeMessages) + sum_f [msg.value_f] * >= sum_f [quoteEVMDeliveryPrice(targetChain_f, receiverValue_f, gasLimit_f, deliveryProviderAddress_f) + paymentForExtraReceiverValue_f] * * The difference between the two sides of the above inequality will be added to `paymentForExtraReceiverValue` of the first forward requested * * @param targetChain in Wormhole Chain ID format * @param targetAddress address to call on targetChain (that implements IWormholeReceiver), in Wormhole bytes32 format * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress` * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param paymentForExtraReceiverValue amount (in current chain currency units) to spend on extra receiverValue * (in addition to the `receiverValue` specified) * @param gasLimit gas limit with which to call `targetAddress`. Any units of gas unused will be refunded according to the * `targetChainRefundPerGasUnused` rate quoted by the delivery provider * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format * @param refundAddress The address on `refundChain` to deliver any refund to, in Wormhole bytes32 format * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider * @param vaaKeys Additional VAAs to pass in as parameter in call to `targetAddress` * @param consistencyLevel Consistency level with which to publish the delivery instructions - see * https://book.wormhole.com/wormhole/3_coreLayerContracts.html?highlight=consistency#consistency-levels */ function forwardToEvm( uint16 targetChain, address targetAddress, bytes memory payload, uint256 receiverValue, uint256 paymentForExtraReceiverValue, uint256 gasLimit, uint16 refundChain, address refundAddress, address deliveryProviderAddress, VaaKey[] memory vaaKeys, uint8 consistencyLevel ) external payable; /** * @notice Performs the same function as a `send`, except: * 1) Can only be used during a delivery (i.e. in execution of `receiveWormholeMessages`) * 2) Is paid for (along with any other calls to forward) by (any msg.value passed in) + (refund leftover from current delivery) * 3) Only executes after `receiveWormholeMessages` is completed (and thus does not return a sequence number) * * The refund from the delivery currently in progress will not be sent to the user; it will instead * be paid to the delivery provider to perform the instruction specified here * * Publishes an instruction for the delivery provider at `deliveryProviderAddress` * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain` * with `msg.value` equal to * receiverValue + (arbitrary amount that is paid for by paymentForExtraReceiverValue of this chain's wei) in targetChain wei. * * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain` * `targetAddress` must implement the IWormholeReceiver interface * * The following equation must be satisfied (sum_f indicates summing over all forwards requested in `receiveWormholeMessages`): * (refund amount from current execution of receiveWormholeMessages) + sum_f [msg.value_f] * >= sum_f [quoteDeliveryPrice(targetChain_f, receiverValue_f, encodedExecutionParameters_f, deliveryProviderAddress_f) + paymentForExtraReceiverValue_f] * * The difference between the two sides of the above inequality will be added to `paymentForExtraReceiverValue` of the first forward requested * * @param targetChain in Wormhole Chain ID format * @param targetAddress address to call on targetChain (that implements IWormholeReceiver), in Wormhole bytes32 format * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress` * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param paymentForExtraReceiverValue amount (in current chain currency units) to spend on extra receiverValue * (in addition to the `receiverValue` specified) * @param encodedExecutionParameters encoded information on how to execute delivery that may impact pricing * e.g. for version EVM_V1, this is a struct that encodes the `gasLimit` with which to call `targetAddress` * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format * @param refundAddress The address on `refundChain` to deliver any refund to, in Wormhole bytes32 format * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider * @param vaaKeys Additional VAAs to pass in as parameter in call to `targetAddress` * @param consistencyLevel Consistency level with which to publish the delivery instructions - see * https://book.wormhole.com/wormhole/3_coreLayerContracts.html?highlight=consistency#consistency-levels */ function forward( uint16 targetChain, bytes32 targetAddress, bytes memory payload, uint256 receiverValue, uint256 paymentForExtraReceiverValue, bytes memory encodedExecutionParameters, uint16 refundChain, bytes32 refundAddress, address deliveryProviderAddress, VaaKey[] memory vaaKeys, uint8 consistencyLevel ) external payable; /** * @notice Requests a previously published delivery instruction to be redelivered * (e.g. with a different delivery provider) * * This function must be called with `msg.value` equal to * quoteEVMDeliveryPrice(targetChain, newReceiverValue, newGasLimit, newDeliveryProviderAddress) * * @param deliveryVaaKey VaaKey identifying the wormhole message containing the * previously published delivery instructions * @param targetChain The target chain that the original delivery targeted. Must match targetChain from original delivery instructions * @param newReceiverValue new msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param newGasLimit gas limit with which to call `targetAddress`. Any units of gas unused will be refunded according to the * `targetChainRefundPerGasUnused` rate quoted by the delivery provider, to the refund chain and address specified in the original request * @param newDeliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider * @return sequence sequence number of published VAA containing redelivery instructions */ function resendToEvm( VaaKey memory deliveryVaaKey, uint16 targetChain, uint256 newReceiverValue, uint256 newGasLimit, address newDeliveryProviderAddress ) external payable returns (uint64 sequence); /** * @notice Requests a previously published delivery instruction to be redelivered * * * This function must be called with `msg.value` equal to * quoteDeliveryPrice(targetChain, newReceiverValue, newEncodedExecutionParameters, newDeliveryProviderAddress) * * @param deliveryVaaKey VaaKey identifying the wormhole message containing the * previously published delivery instructions * @param targetChain The target chain that the original delivery targeted. Must match targetChain from original delivery instructions * @param newReceiverValue new msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param newEncodedExecutionParameters new encoded information on how to execute delivery that may impact pricing * e.g. for version EVM_V1, this is a struct that encodes the `gasLimit` with which to call `targetAddress` * @param newDeliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider * @return sequence sequence number of published VAA containing redelivery instructions */ function resend( VaaKey memory deliveryVaaKey, uint16 targetChain, uint256 newReceiverValue, bytes memory newEncodedExecutionParameters, address newDeliveryProviderAddress ) external payable returns (uint64 sequence); /** * @notice Returns the price to request a relay to chain `targetChain`, using the default delivery provider * * @param targetChain in Wormhole Chain ID format * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param gasLimit gas limit with which to call `targetAddress`. * @return nativePriceQuote Price, in units of current chain currency, that the delivery provider charges to perform the relay * @return targetChainRefundPerGasUnused amount of target chain currency that will be refunded per unit of gas unused, * if a refundAddress is specified */ function quoteEVMDeliveryPrice( uint16 targetChain, uint256 receiverValue, uint256 gasLimit ) external view returns (uint256 nativePriceQuote, uint256 targetChainRefundPerGasUnused); /** * @notice Returns the price to request a relay to chain `targetChain`, using delivery provider `deliveryProviderAddress` * * @param targetChain in Wormhole Chain ID format * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param gasLimit gas limit with which to call `targetAddress`. * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider * @return nativePriceQuote Price, in units of current chain currency, that the delivery provider charges to perform the relay * @return targetChainRefundPerGasUnused amount of target chain currency that will be refunded per unit of gas unused, * if a refundAddress is specified */ function quoteEVMDeliveryPrice( uint16 targetChain, uint256 receiverValue, uint256 gasLimit, address deliveryProviderAddress ) external view returns (uint256 nativePriceQuote, uint256 targetChainRefundPerGasUnused); /** * @notice Returns the price to request a relay to chain `targetChain`, using delivery provider `deliveryProviderAddress` * * @param targetChain in Wormhole Chain ID format * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units) * @param encodedExecutionParameters encoded information on how to execute delivery that may impact pricing * e.g. for version EVM_V1, this is a struct that encodes the `gasLimit` with which to call `targetAddress` * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider * @return nativePriceQuote Price, in units of current chain currency, that the delivery provider charges to perform the relay * @return encodedExecutionInfo encoded information on how the delivery will be executed * e.g. for version EVM_V1, this is a struct that encodes the `gasLimit` and `targetChainRefundPerGasUnused` * (which is the amount of target chain currency that will be refunded per unit of gas unused, * if a refundAddress is specified) */ function quoteDeliveryPrice( uint16 targetChain, uint256 receiverValue, bytes memory encodedExecutionParameters, address deliveryProviderAddress ) external view returns (uint256 nativePriceQuote, bytes memory encodedExecutionInfo); /** * @notice Returns the (extra) amount of target chain currency that `targetAddress` * will be called with, if the `paymentForExtraReceiverValue` field is set to `currentChainAmount` * * @param targetChain in Wormhole Chain ID format * @param currentChainAmount The value that `paymentForExtraReceiverValue` will be set to * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider * @return targetChainAmount The amount such that if `targetAddress` will be called with `msg.value` equal to * receiverValue + targetChainAmount */ function quoteNativeForChain( uint16 targetChain, uint256 currentChainAmount, address deliveryProviderAddress ) external view returns (uint256 targetChainAmount); /** * @notice Returns the address of the current default delivery provider * @return deliveryProvider The address of (the default delivery provider)'s contract on this source * chain. This must be a contract that implements IDeliveryProvider. */ function getDefaultDeliveryProvider() external view returns (address deliveryProvider); } /** * @title IWormholeRelayerDelivery * @notice The interface to execute deliveries. Only relevant for Delivery Providers */ interface IWormholeRelayerDelivery is IWormholeRelayerBase { enum DeliveryStatus { SUCCESS, RECEIVER_FAILURE, FORWARD_REQUEST_FAILURE, FORWARD_REQUEST_SUCCESS } enum RefundStatus { REFUND_SENT, REFUND_FAIL, CROSS_CHAIN_REFUND_SENT, CROSS_CHAIN_REFUND_FAIL_PROVIDER_NOT_SUPPORTED, CROSS_CHAIN_REFUND_FAIL_NOT_ENOUGH } /** * @custom:member recipientContract - The target contract address * @custom:member sourceChain - The chain which this delivery was requested from (in wormhole * ChainID format) * @custom:member sequence - The wormhole sequence number of the delivery VAA on the source chain * corresponding to this delivery request * @custom:member deliveryVaaHash - The hash of the delivery VAA corresponding to this delivery * request * @custom:member gasUsed - The amount of gas that was used to call your target contract * @custom:member status: * - RECEIVER_FAILURE, if the target contract reverts * - SUCCESS, if the target contract doesn't revert and no forwards were requested * - FORWARD_REQUEST_FAILURE, if the target contract doesn't revert, forwards were requested, * but provided/leftover funds were not sufficient to cover them all * - FORWARD_REQUEST_SUCCESS, if the target contract doesn't revert and all forwards are covered * @custom:member additionalStatusInfo: * - If status is SUCCESS or FORWARD_REQUEST_SUCCESS, then this is empty. * - If status is RECEIVER_FAILURE, this is `RETURNDATA_TRUNCATION_THRESHOLD` bytes of the * return data (i.e. potentially truncated revert reason information). * - If status is FORWARD_REQUEST_FAILURE, this is also the revert data - the reason the forward failed. * This will be either an encoded Cancelled, DeliveryProviderReverted, or DeliveryProviderPaymentFailed error * @custom:member refundStatus - Result of the refund. REFUND_SUCCESS or REFUND_FAIL are for * refunds where targetChain=refundChain; the others are for targetChain!=refundChain, * where a cross chain refund is necessary * @custom:member overridesInfo: * - If not an override: empty bytes array * - Otherwise: An encoded `DeliveryOverride` */ event Delivery( address indexed recipientContract, uint16 indexed sourceChain, uint64 indexed sequence, bytes32 deliveryVaaHash, DeliveryStatus status, uint256 gasUsed, RefundStatus refundStatus, bytes additionalStatusInfo, bytes overridesInfo ); /** * @notice The delivery provider calls `deliver` to relay messages as described by one delivery instruction * * The delivery provider must pass in the specified (by VaaKeys[]) signed wormhole messages (VAAs) from the source chain * as well as the signed wormhole message with the delivery instructions (the delivery VAA) * * The messages will be relayed to the target address (with the specified gas limit and receiver value) iff the following checks are met: * - the delivery VAA has a valid signature * - the delivery VAA's emitter is one of these WormholeRelayer contracts * - the delivery provider passed in at least enough of this chain's currency as msg.value (enough meaning the maximum possible refund) * - the instruction's target chain is this chain * - the relayed signed VAAs match the descriptions in container.messages (the VAA hashes match, or the emitter address, sequence number pair matches, depending on the description given) * * @param encodedVMs - An array of signed wormhole messages (all from the same source chain * transaction) * @param encodedDeliveryVAA - Signed wormhole message from the source chain's WormholeRelayer * contract with payload being the encoded delivery instruction container * @param relayerRefundAddress - The address to which any refunds to the delivery provider * should be sent * @param deliveryOverrides - Optional overrides field which must be either an empty bytes array or * an encoded DeliveryOverride struct */ function deliver( bytes[] memory encodedVMs, bytes memory encodedDeliveryVAA, address payable relayerRefundAddress, bytes memory deliveryOverrides ) external payable; } interface IWormholeRelayer is IWormholeRelayerDelivery, IWormholeRelayerSend {} /* * Errors thrown by IWormholeRelayer contract */ // Bound chosen by the following formula: `memoryWord * 4 + selectorSize`. // This means that an error identifier plus four fixed size arguments should be available to developers. // In the case of a `require` revert with error message, this should provide 2 memory word's worth of data. uint256 constant RETURNDATA_TRUNCATION_THRESHOLD = 132; //When msg.value was not equal to `delivery provider's quoted delivery price` + `paymentForExtraReceiverValue` error InvalidMsgValue(uint256 msgValue, uint256 totalFee); error RequestedGasLimitTooLow(); error DeliveryProviderDoesNotSupportTargetChain(address relayer, uint16 chainId); error DeliveryProviderCannotReceivePayment(); //When calling `forward()` on the WormholeRelayer if no delivery is in progress error NoDeliveryInProgress(); //When calling `delivery()` a second time even though a delivery is already in progress error ReentrantDelivery(address msgSender, address lockedBy); //When any other contract but the delivery target calls `forward()` on the WormholeRelayer while a // delivery is in progress error ForwardRequestFromWrongAddress(address msgSender, address deliveryTarget); error InvalidPayloadId(uint8 parsed, uint8 expected); error InvalidPayloadLength(uint256 received, uint256 expected); error InvalidVaaKeyType(uint8 parsed); error InvalidDeliveryVaa(string reason); //When the delivery VAA (signed wormhole message with delivery instructions) was not emitted by the // registered WormholeRelayer contract error InvalidEmitter(bytes32 emitter, bytes32 registered, uint16 chainId); error VaaKeysLengthDoesNotMatchVaasLength(uint256 keys, uint256 vaas); error VaaKeysDoNotMatchVaas(uint8 index); //When someone tries to call an external function of the WormholeRelayer that is only intended to be // called by the WormholeRelayer itself (to allow retroactive reverts for atomicity) error RequesterNotWormholeRelayer(); //When trying to relay a `DeliveryInstruction` to any other chain but the one it was specified for error TargetChainIsNotThisChain(uint16 targetChain); error ForwardNotSufficientlyFunded(uint256 amountOfFunds, uint256 amountOfFundsNeeded); //When a `DeliveryOverride` contains a gas limit that's less than the original error InvalidOverrideGasLimit(); //When a `DeliveryOverride` contains a receiver value that's less than the original error InvalidOverrideReceiverValue(); //When a `DeliveryOverride` contains a 'refund per unit of gas unused' that's less than the original error InvalidOverrideRefundPerGasUnused(); //When the delivery provider doesn't pass in sufficient funds (i.e. msg.value does not cover the // maximum possible refund to the user) error InsufficientRelayerFunds(uint256 msgValue, uint256 minimum); //When a bytes32 field can't be converted into a 20 byte EVM address, because the 12 padding bytes // are non-zero (duplicated from Utils.sol) error NotAnEvmAddress(bytes32);
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.17; import {IProposedOwnable} from "./interfaces/IProposedOwnable.sol"; /** * @title ProposedOwnable * @notice Contract module which provides a basic access control mechanism, * where there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed via a two step process: * 1. Call `proposeOwner` * 2. Wait out the delay period * 3. Call `acceptOwner` * * @dev This module is used through inheritance. It will make available the * modifier `onlyOwner`, which can be applied to your functions to restrict * their use to the owner. * * @dev The majority of this code was taken from the openzeppelin Ownable * contract * */ abstract contract ProposedOwnable is IProposedOwnable { // ========== Custom Errors =========== error ProposedOwnable__onlyOwner_notOwner(); error ProposedOwnable__onlyProposed_notProposedOwner(); error ProposedOwnable__ownershipDelayElapsed_delayNotElapsed(); error ProposedOwnable__proposeNewOwner_invalidProposal(); error ProposedOwnable__proposeNewOwner_noOwnershipChange(); error ProposedOwnable__renounceOwnership_noProposal(); error ProposedOwnable__renounceOwnership_invalidProposal(); // ============ Properties ============ address private _owner; address private _proposed; uint256 private _proposedOwnershipTimestamp; uint256 private constant _delay = 7 days; // ======== Getters ========= /** * @notice Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @notice Returns the address of the proposed owner. */ function proposed() public view virtual returns (address) { return _proposed; } /** * @notice Returns the address of the proposed owner. */ function proposedTimestamp() public view virtual returns (uint256) { return _proposedOwnershipTimestamp; } /** * @notice Returns the delay period before a new owner can be accepted. */ function delay() public view virtual returns (uint256) { return _delay; } /** * @notice Throws if called by any account other than the owner. */ modifier onlyOwner() { if (_owner != msg.sender) revert ProposedOwnable__onlyOwner_notOwner(); _; } /** * @notice Throws if called by any account other than the proposed owner. */ modifier onlyProposed() { if (_proposed != msg.sender) revert ProposedOwnable__onlyProposed_notProposedOwner(); _; } /** * @notice Throws if the ownership delay has not elapsed */ modifier ownershipDelayElapsed() { // Ensure delay has elapsed if ((block.timestamp - _proposedOwnershipTimestamp) <= _delay) revert ProposedOwnable__ownershipDelayElapsed_delayNotElapsed(); _; } /** * @notice Indicates if the ownership has been renounced() by * checking if current owner is address(0) */ function renounced() public view returns (bool) { return _owner == address(0); } // ======== External ========= /** * @notice Sets the timestamp for an owner to be proposed, and sets the * newly proposed owner as step 1 in a 2-step process */ function proposeNewOwner(address newlyProposed) public virtual onlyOwner { // Contract as source of truth if (_proposed == newlyProposed && _proposedOwnershipTimestamp != 0) revert ProposedOwnable__proposeNewOwner_invalidProposal(); // Sanity check: reasonable proposal if (_owner == newlyProposed) revert ProposedOwnable__proposeNewOwner_noOwnershipChange(); _setProposed(newlyProposed); } /** * @notice Renounces ownership of the contract after a delay */ function renounceOwnership() public virtual onlyOwner ownershipDelayElapsed { // Ensure there has been a proposal cycle started if (_proposedOwnershipTimestamp == 0) revert ProposedOwnable__renounceOwnership_noProposal(); // Require proposed is set to 0 if (_proposed != address(0)) revert ProposedOwnable__renounceOwnership_invalidProposal(); // Emit event, set new owner, reset timestamp _setOwner(address(0)); } /** * @notice Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function acceptProposedOwner() public virtual onlyProposed ownershipDelayElapsed { // NOTE: no need to check if _owner == _proposed, because the _proposed // is 0-d out and this check is implicitly enforced by modifier // NOTE: no need to check if _proposedOwnershipTimestamp > 0 because // the only time this would happen is if the _proposed was never // set (will fail from modifier) or if the owner == _proposed (checked // above) // Emit event, set new owner, reset timestamp _setOwner(_proposed); } // ======== Internal ========= function _setOwner(address newOwner) internal { emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; delete _proposedOwnershipTimestamp; delete _proposed; } function _setProposed(address newlyProposed) private { _proposedOwnershipTimestamp = block.timestamp; _proposed = newlyProposed; emit OwnershipProposed(newlyProposed); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; /** * @title IProposedOwnable * @notice Defines a minimal interface for ownership with a two step proposal and acceptance * process */ interface IProposedOwnable { /** * @dev This emits when change in ownership of a contract is proposed. */ event OwnershipProposed(address indexed proposedOwner); /** * @dev This emits when ownership of a contract changes. */ event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @notice Get the address of the owner * @return owner_ The address of the owner. */ function owner() external view returns (address owner_); /** * @notice Get the address of the proposed owner * @return proposed_ The address of the proposed. */ function proposed() external view returns (address proposed_); /** * @notice Set the address of the proposed owner of the contract * @param newlyProposed The proposed new owner of the contract */ function proposeNewOwner(address newlyProposed) external; /** * @notice Set the address of the proposed owner of the contract */ function acceptProposedOwner() external; }
{ "evmVersion": "london", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 200 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"},{"internalType":"uint32","name":"_mirrorDomain","type":"uint32"},{"internalType":"address","name":"_amb","type":"address"},{"internalType":"address","name":"_rootManager","type":"address"},{"internalType":"address","name":"_mirrorConnector","type":"address"},{"internalType":"uint256","name":"_gasCap","type":"uint256"},{"internalType":"uint16","name":"_mirrorWormholeChainId","type":"uint16"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Connector__processMessage_notUsed","type":"error"},{"inputs":[],"name":"ProposedOwnable__onlyOwner_notOwner","type":"error"},{"inputs":[],"name":"ProposedOwnable__onlyProposed_notProposedOwner","type":"error"},{"inputs":[],"name":"ProposedOwnable__ownershipDelayElapsed_delayNotElapsed","type":"error"},{"inputs":[],"name":"ProposedOwnable__proposeNewOwner_invalidProposal","type":"error"},{"inputs":[],"name":"ProposedOwnable__proposeNewOwner_noOwnershipChange","type":"error"},{"inputs":[],"name":"ProposedOwnable__renounceOwnership_invalidProposal","type":"error"},{"inputs":[],"name":"ProposedOwnable__renounceOwnership_noProposal","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_previous","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_updated","type":"uint256"}],"name":"GasCapUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"MessageProcessed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"encodedData","type":"bytes"},{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"MessageSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previous","type":"address"},{"indexed":false,"internalType":"address","name":"current","type":"address"}],"name":"MirrorConnectorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"domain","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"mirrorDomain","type":"uint32"},{"indexed":false,"internalType":"address","name":"amb","type":"address"},{"indexed":false,"internalType":"address","name":"rootManager","type":"address"},{"indexed":false,"internalType":"address","name":"mirrorConnector","type":"address"}],"name":"NewConnector","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"proposedOwner","type":"address"}],"name":"OwnershipProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previous","type":"address"},{"indexed":true,"internalType":"address","name":"updated","type":"address"}],"name":"RefundAddressUpdated","type":"event"},{"inputs":[],"name":"AMB","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIRROR_DOMAIN","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIRROR_WORMHOLE_ID","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROOT_MANAGER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptProposedOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"delay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mirrorConnector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"processMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"processedWhMessages","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newlyProposed","type":"address"}],"name":"proposeNewOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"proposed","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposedTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_gasLimit","type":"uint256"},{"internalType":"address","name":"_amb","type":"address"}],"name":"quoteEVMDeliveryPrice","outputs":[{"internalType":"uint256","name":"_cost","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_payload","type":"bytes"},{"internalType":"bytes[]","name":"","type":"bytes[]"},{"internalType":"bytes32","name":"_sourceAddress","type":"bytes32"},{"internalType":"uint16","name":"_sourceChain","type":"uint16"},{"internalType":"bytes32","name":"_deliveryHash","type":"bytes32"}],"name":"receiveWormholeMessages","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"refundAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounced","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"bytes","name":"_encodedData","type":"bytes"}],"name":"sendMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_gasCap","type":"uint256"}],"name":"setGasCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_mirrorConnector","type":"address"}],"name":"setMirrorConnector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_updated","type":"address"}],"name":"setRefundAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_expected","type":"address"}],"name":"verifySender","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6101206040523480156200001257600080fd5b5060405162001a2038038062001a2083398101604081905262000035916200039b565b818181898989898984848484846200004d33620001b3565b8463ffffffff16600003620000985760405162461bcd60e51b815260206004820152600c60248201526b32b6b83a3c903237b6b0b4b760a11b60448201526064015b60405180910390fd5b6001600160a01b038216620000e45760405162461bcd60e51b815260206004820152601160248201527032b6b83a3c903937b7ba26b0b730b3b2b960791b60448201526064016200008f565b63ffffffff8086166080526001600160a01b0380851660a05283811660c05290851660e0528116156200011c576200011c8162000218565b604080516001600160a01b0385811682528481166020830152831681830152905163ffffffff86811692908816917f4f9c27c2fe3f84576ea469d367d044da53c45e951617e8389f2b5ed8db9d25f09181900360600190a3505050505050505050506200018f816200028160201b60201c565b5061ffff811661010052620001a433620002c2565b50505050505050505062000431565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b039092166001600160a01b0319928316178155600255600180549091169055565b600354604080516001600160a01b03928316815291831660208301527fc77bec288fc88f168427f2f7da682eadb26cac89d8d591af6e443da98dff2bbc910160405180910390a1600380546001600160a01b0319166001600160a01b0392909216919091179055565b60045460408051918252602082018390527f877a02cb809da0364d23adca3cd50c451b53f279d3df632e1fc11eb66335bce5910160405180910390a1600455565b6005546001600160a01b03908116908216036200030d5760405162461bcd60e51b81526020600482015260086024820152670858da185b99d95960c21b60448201526064016200008f565b6005546040516001600160a01b038084169216907f57b5839c3435f5b2eb2d2e286fb44ca7303d01d9b25a5d9c05c489523474285990600090a3600580546001600160a01b0319166001600160a01b0392909216919091179055565b805163ffffffff811681146200037e57600080fd5b919050565b80516001600160a01b03811681146200037e57600080fd5b600080600080600080600060e0888a031215620003b757600080fd5b620003c28862000369565b9650620003d26020890162000369565b9550620003e26040890162000383565b9450620003f26060890162000383565b9350620004026080890162000383565b925060a0880151915060c088015161ffff811681146200042157600080fd5b8091505092959891949750929550565b60805160a05160c05160e0516101005161156b620004b560003960008181610255015281816105e501528181610abe01526110080152600081816101aa0152610cc9015260008181610375015281816105280152610ca20152600081816104a401528181610691015281816107320152610a5901526000610321015261156b6000f3fe60806040526004361061014f5760003560e01c80635f61e3ec116100b6578063c5b350df1161006f578063c5b350df14610420578063cc39428314610435578063d1851c9214610455578063d232c22014610473578063d69f9d6114610492578063db1b7659146104c657600080fd5b80635f61e3ec146103635780636a42b8f814610397578063715018a6146103ad5780637850b020146103c25780638da5cb5b146103e2578063b1f8100d1461040057600080fd5b806348e6fa231161010857806348e6fa23146102a95780634d93538b146102bc5780634ff746f6146102dc578063529dca32146102fc57806352a9674b1461030f5780635bd11efc1461034357600080fd5b80630cb61f6c1461015b578063141684161461019857806315b75bea146101e157806318c8170914610203578063194ea996146102435780633cf52ffb1461028a57600080fd5b3661015657005b600080fd5b34801561016757600080fd5b5060055461017b906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101a457600080fd5b506101cc7f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff909116815260200161018f565b3480156101ed57600080fd5b506102016101fc3660046110a5565b6104e6565b005b34801561020f57600080fd5b5061023361021e3660046110c7565b60066020526000908152604090205460ff1681565b604051901515815260200161018f565b34801561024f57600080fd5b506102777f000000000000000000000000000000000000000000000000000000000000000081565b60405161ffff909116815260200161018f565b34801561029657600080fd5b506002545b60405190815260200161018f565b6102016102b7366004611197565b61051d565b3480156102c857600080fd5b5061029b6102d73660046111fb565b6105d2565b3480156102e857600080fd5b506102016102f7366004611227565b610686565b61020161030a366004611276565b61072c565b34801561031b57600080fd5b506101cc7f000000000000000000000000000000000000000000000000000000000000000081565b34801561034f57600080fd5b5061020161035e3660046110a5565b610770565b34801561036f57600080fd5b5061017b7f000000000000000000000000000000000000000000000000000000000000000081565b3480156103a357600080fd5b5062093a8061029b565b3480156103b957600080fd5b506102016107a4565b3480156103ce57600080fd5b506102016103dd3660046110c7565b610858565b3480156103ee57600080fd5b506000546001600160a01b031661017b565b34801561040c57600080fd5b5061020161041b3660046110a5565b61088c565b34801561042c57600080fd5b5061020161092a565b34801561044157600080fd5b5060035461017b906001600160a01b031681565b34801561046157600080fd5b506001546001600160a01b031661017b565b34801561047f57600080fd5b506000546001600160a01b031615610233565b34801561049e57600080fd5b5061017b7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104d257600080fd5b506102336104e13660046110a5565b61099a565b6000546001600160a01b03163314610511576040516311a8a1bb60e31b815260040160405180910390fd5b61051a816109ab565b50565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105895760405162461bcd60e51b815260206004820152600c60248201526b10b937b7ba26b0b730b3b2b960a11b60448201526064015b60405180910390fd5b6105938282610a50565b7fdcaa37a042a0087de79018c629bbd29cee82ca80bd9be394e1696bf9e93550778282336040516105c6939291906113c5565b60405180910390a15050565b6000816001600160a01b031663c23ee3c37f0000000000000000000000000000000000000000000000000000000000000000600061060f87610a8d565b6040516001600160e01b031960e086901b16815261ffff9093166004840152602483019190915260448201526064016040805180830381865afa15801561065a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067e9190611403565b509392505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146106e75760405162461bcd60e51b81526004016105809060208082526004908201526310a0a6a160e11b604082015260600190565b6106f081610aa3565b7fb3abc57bfeebd2cac918901db582f71972a8e628bccf19f5ae3e3482b98a5ced8133604051610721929190611427565b60405180910390a150565b610757827f000000000000000000000000000000000000000000000000000000000000000083610abc565b61076961076384610bd6565b86610c19565b5050505050565b6000546001600160a01b0316331461079b576040516311a8a1bb60e31b815260040160405180910390fd5b61051a81610d7e565b6000546001600160a01b031633146107cf576040516311a8a1bb60e31b815260040160405180910390fd5b62093a80600254426107e19190611451565b116107ff576040516324e0285f60e21b815260040160405180910390fd5b60025460000361082257604051630e4b303f60e21b815260040160405180910390fd5b6001546001600160a01b03161561084c576040516323295ef960e01b815260040160405180910390fd5b6108566000610de7565b565b6000546001600160a01b03163314610883576040516311a8a1bb60e31b815260040160405180910390fd5b61051a81610e4c565b6000546001600160a01b031633146108b7576040516311a8a1bb60e31b815260040160405180910390fd5b6001546001600160a01b0382811691161480156108d5575060025415155b156108f3576040516311bc066560e11b815260040160405180910390fd5b6000546001600160a01b0380831691160361092157604051634a2fb73f60e11b815260040160405180910390fd5b61051a81610e8d565b6001546001600160a01b03163314610955576040516311a7f27160e11b815260040160405180910390fd5b62093a80600254426109679190611451565b11610985576040516324e0285f60e21b815260040160405180910390fd5b600154610856906001600160a01b0316610de7565b60006109a582610edb565b92915050565b6005546001600160a01b03908116908216036109f45760405162461bcd60e51b81526020600482015260086024820152670858da185b99d95960c21b6044820152606401610580565b6005546040516001600160a01b038084169216907f57b5839c3435f5b2eb2d2e286fb44ca7303d01d9b25a5d9c05c489523474285990600090a3600580546001600160a01b0319166001600160a01b0392909216919091179055565b600354610a89907f0000000000000000000000000000000000000000000000000000000000000000906001600160a01b03168484610ef4565b5050565b6000600454821115610a9f5760045491505b5090565b6040516316c2fdb560e21b815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000061ffff168361ffff1614610b235760405162461bcd60e51b815260206004820152600d60248201526c10b9b7bab931b29031b430b4b760991b6044820152606401610580565b336001600160a01b03831614610b665760405162461bcd60e51b815260206004820152600860248201526710b932b630bcb2b960c11b6044820152606401610580565b60008181526006602052604090205460ff1615610bb95760405162461bcd60e51b8152602060048201526011602482015270185b1c9958591e481c1c9bd8d95cdcd959607a1b6044820152606401610580565b6000908152600660205260409020805460ff191660011790555050565b600060a082901c15610a9f5760405162461bcd60e51b815260206004820152600c60248201526b2165766d206164647265737360a01b6044820152606401610580565b610c2282610edb565b610c5d5760405162461bcd60e51b815260206004820152600c60248201526b10b61921b7b73732b1ba37b960a11b6044820152606401610580565b8051602014610c985760405162461bcd60e51b8152602060048201526007602482015266042d8cadccee8d60cb1b6044820152606401610580565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016638e7d93fa7f0000000000000000000000000000000000000000000000000000000000000000610cf184611472565b6040516001600160e01b031960e085901b16815263ffffffff9290921660048301526024820152604401600060405180830381600087803b158015610d3557600080fd5b505af1158015610d49573d6000803e3d6000fd5b505050507fb3abc57bfeebd2cac918901db582f71972a8e628bccf19f5ae3e3482b98a5ced81336040516105c6929190611427565b600354604080516001600160a01b03928316815291831660208301527fc77bec288fc88f168427f2f7da682eadb26cac89d8d591af6e443da98dff2bbc910160405180910390a1600380546001600160a01b0319166001600160a01b0392909216919091179055565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b039092166001600160a01b0319928316178155600255600180549091169055565b60045460408051918252602082018390527f877a02cb809da0364d23adca3cd50c451b53f279d3df632e1fc11eb66335bce5910160405180910390a1600455565b42600255600180546001600160a01b0319166001600160a01b0383169081179091556040517f6ab4d119f23076e8ad491bc65ce85f017fb0591dce08755ba8591059cc51737a90600090a250565b6003546000906001600160a01b038381169116146109a5565b8151602014610f345760405162461bcd60e51b815260206004820152600c60248201526b042c8c2e8c240d8cadccee8d60a31b6044820152606401610580565b8051602014610f7c5760405162461bcd60e51b8152602060048201526014602482015273042cadcc6dec8cac840c8c2e8c240d8cadccee8d60631b6044820152606401610580565b600081806020019051810190610f929190611499565b90506000610fa082876105d2565b9050348114610fde5760405162461bcd60e51b815260206004820152600a602482015269216d73672e76616c756560b01b6044820152606401610580565b6005546040516312d729bd60e21b81526001600160a01b0380891692634b5ca6f492859261103d927f0000000000000000000000000000000000000000000000000000000000000000928c928c926000928c92879216906004016114b2565b60206040518083038185885af115801561105b573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611080919061150b565b50505050505050565b80356001600160a01b03811681146110a057600080fd5b919050565b6000602082840312156110b757600080fd5b6110c082611089565b9392505050565b6000602082840312156110d957600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561111f5761111f6110e0565b604052919050565b600082601f83011261113857600080fd5b813567ffffffffffffffff811115611152576111526110e0565b611165601f8201601f19166020016110f6565b81815284602083860101111561117a57600080fd5b816020850160208301376000918101602001919091529392505050565b600080604083850312156111aa57600080fd5b823567ffffffffffffffff808211156111c257600080fd5b6111ce86838701611127565b935060208501359150808211156111e457600080fd5b506111f185828601611127565b9150509250929050565b6000806040838503121561120e57600080fd5b8235915061121e60208401611089565b90509250929050565b60006020828403121561123957600080fd5b813567ffffffffffffffff81111561125057600080fd5b61125c84828501611127565b949350505050565b803561ffff811681146110a057600080fd5b600080600080600060a0868803121561128e57600080fd5b853567ffffffffffffffff808211156112a657600080fd5b6112b289838a01611127565b96506020915081880135818111156112c957600080fd5b8801601f81018a136112da57600080fd5b8035828111156112ec576112ec6110e0565b8060051b6112fb8582016110f6565b918252828101850191858101908d84111561131557600080fd5b86850192505b83831015611351578235868111156113335760008081fd5b6113418f8983890101611127565b835250918601919086019061131b565b809a50505050505050506040860135925061136e60608701611264565b949793965091946080013592915050565b6000815180845260005b818110156113a557602081850181015186830182015201611389565b506000602082860101526020601f19601f83011685010191505092915050565b6060815260006113d8606083018661137f565b82810360208401526113ea818661137f565b91505060018060a01b0383166040830152949350505050565b6000806040838503121561141657600080fd5b505080516020909101519092909150565b60408152600061143a604083018561137f565b905060018060a01b03831660208301529392505050565b818103818111156109a557634e487b7160e01b600052601160045260246000fd5b80516020808301519190811015611493576000198160200360031b1b821691505b50919050565b6000602082840312156114ab57600080fd5b5051919050565b600061ffff808a16835260018060a01b03808a16602085015260e060408501526114df60e085018a61137f565b925087606085015286608085015281861660a085015280851660c0850152505098975050505050505050565b60006020828403121561151d57600080fd5b815167ffffffffffffffff811681146110c057600080fdfea26469706673582212207fae5ae139ba9412dd3eb66ea44881835a9cf3d5dfc7e4643f136b945ae492a364736f6c6343000811003300000000000000000000000000000000000000000000000000000000006574680000000000000000000000000000000000000000000000000000000000626e6200000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911000000000000000000000000d5d61e9dfb6680cba8353988ba0337802811c2e1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000493e00000000000000000000000000000000000000000000000000000000000000004
Deployed Bytecode
0x60806040526004361061014f5760003560e01c80635f61e3ec116100b6578063c5b350df1161006f578063c5b350df14610420578063cc39428314610435578063d1851c9214610455578063d232c22014610473578063d69f9d6114610492578063db1b7659146104c657600080fd5b80635f61e3ec146103635780636a42b8f814610397578063715018a6146103ad5780637850b020146103c25780638da5cb5b146103e2578063b1f8100d1461040057600080fd5b806348e6fa231161010857806348e6fa23146102a95780634d93538b146102bc5780634ff746f6146102dc578063529dca32146102fc57806352a9674b1461030f5780635bd11efc1461034357600080fd5b80630cb61f6c1461015b578063141684161461019857806315b75bea146101e157806318c8170914610203578063194ea996146102435780633cf52ffb1461028a57600080fd5b3661015657005b600080fd5b34801561016757600080fd5b5060055461017b906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101a457600080fd5b506101cc7f0000000000000000000000000000000000000000000000000000000000626e6281565b60405163ffffffff909116815260200161018f565b3480156101ed57600080fd5b506102016101fc3660046110a5565b6104e6565b005b34801561020f57600080fd5b5061023361021e3660046110c7565b60066020526000908152604090205460ff1681565b604051901515815260200161018f565b34801561024f57600080fd5b506102777f000000000000000000000000000000000000000000000000000000000000000481565b60405161ffff909116815260200161018f565b34801561029657600080fd5b506002545b60405190815260200161018f565b6102016102b7366004611197565b61051d565b3480156102c857600080fd5b5061029b6102d73660046111fb565b6105d2565b3480156102e857600080fd5b506102016102f7366004611227565b610686565b61020161030a366004611276565b61072c565b34801561031b57600080fd5b506101cc7f000000000000000000000000000000000000000000000000000000000065746881565b34801561034f57600080fd5b5061020161035e3660046110a5565b610770565b34801561036f57600080fd5b5061017b7f000000000000000000000000d5d61e9dfb6680cba8353988ba0337802811c2e181565b3480156103a357600080fd5b5062093a8061029b565b3480156103b957600080fd5b506102016107a4565b3480156103ce57600080fd5b506102016103dd3660046110c7565b610858565b3480156103ee57600080fd5b506000546001600160a01b031661017b565b34801561040c57600080fd5b5061020161041b3660046110a5565b61088c565b34801561042c57600080fd5b5061020161092a565b34801561044157600080fd5b5060035461017b906001600160a01b031681565b34801561046157600080fd5b506001546001600160a01b031661017b565b34801561047f57600080fd5b506000546001600160a01b031615610233565b34801561049e57600080fd5b5061017b7f00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d89491181565b3480156104d257600080fd5b506102336104e13660046110a5565b61099a565b6000546001600160a01b03163314610511576040516311a8a1bb60e31b815260040160405180910390fd5b61051a816109ab565b50565b336001600160a01b037f000000000000000000000000d5d61e9dfb6680cba8353988ba0337802811c2e116146105895760405162461bcd60e51b815260206004820152600c60248201526b10b937b7ba26b0b730b3b2b960a11b60448201526064015b60405180910390fd5b6105938282610a50565b7fdcaa37a042a0087de79018c629bbd29cee82ca80bd9be394e1696bf9e93550778282336040516105c6939291906113c5565b60405180910390a15050565b6000816001600160a01b031663c23ee3c37f0000000000000000000000000000000000000000000000000000000000000004600061060f87610a8d565b6040516001600160e01b031960e086901b16815261ffff9093166004840152602483019190915260448201526064016040805180830381865afa15801561065a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067e9190611403565b509392505050565b336001600160a01b037f00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d89491116146106e75760405162461bcd60e51b81526004016105809060208082526004908201526310a0a6a160e11b604082015260600190565b6106f081610aa3565b7fb3abc57bfeebd2cac918901db582f71972a8e628bccf19f5ae3e3482b98a5ced8133604051610721929190611427565b60405180910390a150565b610757827f00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d89491183610abc565b61076961076384610bd6565b86610c19565b5050505050565b6000546001600160a01b0316331461079b576040516311a8a1bb60e31b815260040160405180910390fd5b61051a81610d7e565b6000546001600160a01b031633146107cf576040516311a8a1bb60e31b815260040160405180910390fd5b62093a80600254426107e19190611451565b116107ff576040516324e0285f60e21b815260040160405180910390fd5b60025460000361082257604051630e4b303f60e21b815260040160405180910390fd5b6001546001600160a01b03161561084c576040516323295ef960e01b815260040160405180910390fd5b6108566000610de7565b565b6000546001600160a01b03163314610883576040516311a8a1bb60e31b815260040160405180910390fd5b61051a81610e4c565b6000546001600160a01b031633146108b7576040516311a8a1bb60e31b815260040160405180910390fd5b6001546001600160a01b0382811691161480156108d5575060025415155b156108f3576040516311bc066560e11b815260040160405180910390fd5b6000546001600160a01b0380831691160361092157604051634a2fb73f60e11b815260040160405180910390fd5b61051a81610e8d565b6001546001600160a01b03163314610955576040516311a7f27160e11b815260040160405180910390fd5b62093a80600254426109679190611451565b11610985576040516324e0285f60e21b815260040160405180910390fd5b600154610856906001600160a01b0316610de7565b60006109a582610edb565b92915050565b6005546001600160a01b03908116908216036109f45760405162461bcd60e51b81526020600482015260086024820152670858da185b99d95960c21b6044820152606401610580565b6005546040516001600160a01b038084169216907f57b5839c3435f5b2eb2d2e286fb44ca7303d01d9b25a5d9c05c489523474285990600090a3600580546001600160a01b0319166001600160a01b0392909216919091179055565b600354610a89907f00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911906001600160a01b03168484610ef4565b5050565b6000600454821115610a9f5760045491505b5090565b6040516316c2fdb560e21b815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000461ffff168361ffff1614610b235760405162461bcd60e51b815260206004820152600d60248201526c10b9b7bab931b29031b430b4b760991b6044820152606401610580565b336001600160a01b03831614610b665760405162461bcd60e51b815260206004820152600860248201526710b932b630bcb2b960c11b6044820152606401610580565b60008181526006602052604090205460ff1615610bb95760405162461bcd60e51b8152602060048201526011602482015270185b1c9958591e481c1c9bd8d95cdcd959607a1b6044820152606401610580565b6000908152600660205260409020805460ff191660011790555050565b600060a082901c15610a9f5760405162461bcd60e51b815260206004820152600c60248201526b2165766d206164647265737360a01b6044820152606401610580565b610c2282610edb565b610c5d5760405162461bcd60e51b815260206004820152600c60248201526b10b61921b7b73732b1ba37b960a11b6044820152606401610580565b8051602014610c985760405162461bcd60e51b8152602060048201526007602482015266042d8cadccee8d60cb1b6044820152606401610580565b6001600160a01b037f000000000000000000000000d5d61e9dfb6680cba8353988ba0337802811c2e116638e7d93fa7f0000000000000000000000000000000000000000000000000000000000626e62610cf184611472565b6040516001600160e01b031960e085901b16815263ffffffff9290921660048301526024820152604401600060405180830381600087803b158015610d3557600080fd5b505af1158015610d49573d6000803e3d6000fd5b505050507fb3abc57bfeebd2cac918901db582f71972a8e628bccf19f5ae3e3482b98a5ced81336040516105c6929190611427565b600354604080516001600160a01b03928316815291831660208301527fc77bec288fc88f168427f2f7da682eadb26cac89d8d591af6e443da98dff2bbc910160405180910390a1600380546001600160a01b0319166001600160a01b0392909216919091179055565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b039092166001600160a01b0319928316178155600255600180549091169055565b60045460408051918252602082018390527f877a02cb809da0364d23adca3cd50c451b53f279d3df632e1fc11eb66335bce5910160405180910390a1600455565b42600255600180546001600160a01b0319166001600160a01b0383169081179091556040517f6ab4d119f23076e8ad491bc65ce85f017fb0591dce08755ba8591059cc51737a90600090a250565b6003546000906001600160a01b038381169116146109a5565b8151602014610f345760405162461bcd60e51b815260206004820152600c60248201526b042c8c2e8c240d8cadccee8d60a31b6044820152606401610580565b8051602014610f7c5760405162461bcd60e51b8152602060048201526014602482015273042cadcc6dec8cac840c8c2e8c240d8cadccee8d60631b6044820152606401610580565b600081806020019051810190610f929190611499565b90506000610fa082876105d2565b9050348114610fde5760405162461bcd60e51b815260206004820152600a602482015269216d73672e76616c756560b01b6044820152606401610580565b6005546040516312d729bd60e21b81526001600160a01b0380891692634b5ca6f492859261103d927f0000000000000000000000000000000000000000000000000000000000000004928c928c926000928c92879216906004016114b2565b60206040518083038185885af115801561105b573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611080919061150b565b50505050505050565b80356001600160a01b03811681146110a057600080fd5b919050565b6000602082840312156110b757600080fd5b6110c082611089565b9392505050565b6000602082840312156110d957600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561111f5761111f6110e0565b604052919050565b600082601f83011261113857600080fd5b813567ffffffffffffffff811115611152576111526110e0565b611165601f8201601f19166020016110f6565b81815284602083860101111561117a57600080fd5b816020850160208301376000918101602001919091529392505050565b600080604083850312156111aa57600080fd5b823567ffffffffffffffff808211156111c257600080fd5b6111ce86838701611127565b935060208501359150808211156111e457600080fd5b506111f185828601611127565b9150509250929050565b6000806040838503121561120e57600080fd5b8235915061121e60208401611089565b90509250929050565b60006020828403121561123957600080fd5b813567ffffffffffffffff81111561125057600080fd5b61125c84828501611127565b949350505050565b803561ffff811681146110a057600080fd5b600080600080600060a0868803121561128e57600080fd5b853567ffffffffffffffff808211156112a657600080fd5b6112b289838a01611127565b96506020915081880135818111156112c957600080fd5b8801601f81018a136112da57600080fd5b8035828111156112ec576112ec6110e0565b8060051b6112fb8582016110f6565b918252828101850191858101908d84111561131557600080fd5b86850192505b83831015611351578235868111156113335760008081fd5b6113418f8983890101611127565b835250918601919086019061131b565b809a50505050505050506040860135925061136e60608701611264565b949793965091946080013592915050565b6000815180845260005b818110156113a557602081850181015186830182015201611389565b506000602082860101526020601f19601f83011685010191505092915050565b6060815260006113d8606083018661137f565b82810360208401526113ea818661137f565b91505060018060a01b0383166040830152949350505050565b6000806040838503121561141657600080fd5b505080516020909101519092909150565b60408152600061143a604083018561137f565b905060018060a01b03831660208301529392505050565b818103818111156109a557634e487b7160e01b600052601160045260246000fd5b80516020808301519190811015611493576000198160200360031b1b821691505b50919050565b6000602082840312156114ab57600080fd5b5051919050565b600061ffff808a16835260018060a01b03808a16602085015260e060408501526114df60e085018a61137f565b925087606085015286608085015281861660a085015280851660c0850152505098975050505050505050565b60006020828403121561151d57600080fd5b815167ffffffffffffffff811681146110c057600080fdfea26469706673582212207fae5ae139ba9412dd3eb66ea44881835a9cf3d5dfc7e4643f136b945ae492a364736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000006574680000000000000000000000000000000000000000000000000000000000626e6200000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911000000000000000000000000d5d61e9dfb6680cba8353988ba0337802811c2e1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000493e00000000000000000000000000000000000000000000000000000000000000004
-----Decoded View---------------
Arg [0] : _domain (uint32): 6648936
Arg [1] : _mirrorDomain (uint32): 6450786
Arg [2] : _amb (address): 0x27428DD2d3DD32A4D7f7C497eAaa23130d894911
Arg [3] : _rootManager (address): 0xd5d61E9dfb6680Cba8353988Ba0337802811C2e1
Arg [4] : _mirrorConnector (address): 0x0000000000000000000000000000000000000000
Arg [5] : _gasCap (uint256): 300000
Arg [6] : _mirrorWormholeChainId (uint16): 4
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000657468
Arg [1] : 0000000000000000000000000000000000000000000000000000000000626e62
Arg [2] : 00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
Arg [3] : 000000000000000000000000d5d61e9dfb6680cba8353988ba0337802811c2e1
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [5] : 00000000000000000000000000000000000000000000000000000000000493e0
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000004
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $2,381.98 | 0.000001 | $0.002382 |
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
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.