More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 451 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Claim | 263125325 | 192 days ago | IN | 0 ETH | 0.0000079 | ||||
Claim | 262405554 | 194 days ago | IN | 0 ETH | 0.00000954 | ||||
Claim | 256668558 | 211 days ago | IN | 0 ETH | 0.00000608 | ||||
Claim | 256560824 | 211 days ago | IN | 0 ETH | 0.00001161 | ||||
Withdraw Zro | 255935053 | 213 days ago | IN | 0 ETH | 0.00000159 | ||||
Set Donate And C... | 255934853 | 213 days ago | IN | 0 ETH | 0.00000134 | ||||
Set Donate And C... | 255934803 | 213 days ago | IN | 0 ETH | 0.00000134 | ||||
Claim | 255824086 | 213 days ago | IN | 0.0075 ETH | 0.00000427 | ||||
Claim | 255823264 | 213 days ago | IN | 0.008 ETH | 0.00000417 | ||||
Claim | 255823173 | 213 days ago | IN | 0.008 ETH | 0.00000414 | ||||
Claim | 255823109 | 213 days ago | IN | 0.0074 ETH | 0.00000412 | ||||
Claim | 255823032 | 213 days ago | IN | 0.0074 ETH | 0.00000415 | ||||
Claim | 255822936 | 213 days ago | IN | 0.0074 ETH | 0.00000451 | ||||
Claim | 255805053 | 214 days ago | IN | 0 ETH | 0.00000295 | ||||
Claim | 255772406 | 214 days ago | IN | 0 ETH | 0.00000304 | ||||
Claim | 255772122 | 214 days ago | IN | 0 ETH | 0.0000028 | ||||
Claim | 255772104 | 214 days ago | IN | 0 ETH | 0.00000324 | ||||
Claim | 255772038 | 214 days ago | IN | 0 ETH | 0.00000264 | ||||
Claim | 255771914 | 214 days ago | IN | 0 ETH | 0.00000266 | ||||
Claim | 255771453 | 214 days ago | IN | 0 ETH | 0.00000265 | ||||
Claim | 255771365 | 214 days ago | IN | 0 ETH | 0.00000273 | ||||
Donate And Claim | 255759571 | 214 days ago | IN | 0.0015 ETH | 0.00000317 | ||||
Claim | 255741814 | 214 days ago | IN | 0.00055718 ETH | 0.00000265 | ||||
Claim | 255642299 | 214 days ago | IN | 0 ETH | 0.00000516 | ||||
Claim | 255628892 | 214 days ago | IN | 0 ETH | 0.00000869 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
279633484 | 144 days ago | 54.39742005 ETH | ||||
267175073 | 180 days ago | 0.0002 ETH | ||||
267174861 | 180 days ago | 0.0002 ETH | ||||
267174778 | 180 days ago | 0.00019761 ETH | ||||
266812086 | 181 days ago | 0.00002151 ETH | ||||
266811957 | 181 days ago | 0.00002151 ETH | ||||
266730103 | 182 days ago | 0.00205763 ETH | ||||
266477934 | 182 days ago | 0.0048 ETH | ||||
266472447 | 182 days ago | 0.0048 ETH | ||||
266194063 | 183 days ago | 54.39742005 ETH | ||||
266194063 | 183 days ago | 54.39748108 ETH | ||||
266194063 | 183 days ago | 0.00011108 ETH | ||||
266191954 | 183 days ago | 54.39737 ETH | ||||
266191954 | 183 days ago | 54.39747097 ETH | ||||
266191954 | 183 days ago | 0.00018501 ETH | ||||
266191502 | 183 days ago | 54.39728595 ETH | ||||
266191502 | 183 days ago | 54.39734698 ETH | ||||
266191502 | 183 days ago | 0.00011108 ETH | ||||
266190839 | 183 days ago | 54.3972359 ETH | ||||
266190839 | 183 days ago | 54.39733687 ETH | ||||
266190839 | 183 days ago | 0.00018501 ETH | ||||
266190491 | 183 days ago | 54.39715185 ETH | ||||
266190491 | 183 days ago | 54.39721288 ETH | ||||
266190491 | 183 days ago | 0.00011108 ETH | ||||
266190105 | 183 days ago | 54.3971018 ETH |
Loading...
Loading
Contract Name:
ClaimLocal
Compiler Version
v0.8.22+commit.4fc1097e
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.22; import { SafeERC20, IERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { IOFT, SendParam } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oft/interfaces/IOFT.sol"; import { OAppReceiver } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oapp/OAppReceiver.sol"; import { OAppCore } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oapp/OAppCore.sol"; // solhint-disable-next-line max-line-length import { Origin, MessagingFee, MessagingReceipt } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; import { ClaimCore, Currency } from "./ClaimCore.sol"; /** * @title ZROClaimLocal */ contract ClaimLocal is ClaimCore, OAppReceiver { using SafeERC20 for IERC20; address public immutable zroToken; mapping(address user => uint256 amount) public zroClaimed; event Claim(address claimer, uint256 expectedAmount, uint256 actualAmount, address to); event ClaimRemote(address claimer, uint256 expectedAmount, uint256 actualAmount, uint32 dstEid, address to); constructor( address _zroToken, address _endpoint, bytes32 _merkleRoot, address _donateContract, address _stargateUsdc, address _stargateUsdt, address _stargateNative, uint256 _nativePrice, address _owner ) ClaimCore(_merkleRoot, _donateContract, _stargateUsdc, _stargateUsdt, _stargateNative, _nativePrice, _owner) OAppCore(_endpoint, _owner) { zroToken = _zroToken; } /** * @notice Withdraw ZRO tokens from the contract * @param _to The address to send the tokens to * @param _amount The amount of tokens to withdraw */ function withdrawZro(address _to, uint256 _amount) external onlyOwner { IERC20(zroToken).safeTransfer(_to, _amount); emit ZroWithdrawn(_to, _amount); } // Withdraw accumulated b->a msg values that are refunded into here function withdrawNative(address _to, uint256 _amount) external onlyOwner { (bool sent, ) = payable(_to).call{ value: _amount }(""); if (!sent) revert WithdrawFailed(); emit NativeWithdrawn(_to, _amount); } /** * @notice Claim tokens locally. Pay for the donation and receive the ZRO tokens to the provided 'to' address * @param _currency The currency of the donation to be paid to claim * @param _zroAmount The amount of ZRO tokens to claim * @param _proof The Merkle proof for the redemption * @param _to The address to send the tokens to */ function claim( Currency _currency, uint256 _zroAmount, bytes32[] calldata _proof, address _to, bytes calldata /*_extraOptions*/ // unused in this implementation, used for interface purposes ) external payable returns (MessagingReceipt memory receipt) { return _claim(msg.sender, _currency, _zroAmount, _proof, _to); } // Allows the wrapper to pass in a user address to claim on their behalf function claim( address _user, Currency _currency, uint256 _zroAmount, bytes32[] calldata _proof, address _to, bytes calldata /*_extraOptions*/ // unused in this implementation, used for interface purposes ) external payable onlyDonateAndClaim returns (MessagingReceipt memory receipt) { return _claim(_user, _currency, _zroAmount, _proof, _to); } function _claim( address _user, Currency _currency, uint256 _zroAmount, bytes32[] calldata _proof, address _to ) internal returns (MessagingReceipt memory receipt) { if (_to == address(0)) revert InvalidToAddress(); // No need to pass msgValue for local claims if (msg.value != 0) revert MsgValueNotSupported(); // step 1: assert user has donated sufficient amount assertDonation(_currency, _user, _zroAmount); // step 2: assert the proof if (!_verifyProof(_user, _zroAmount, _proof)) revert InvalidProof(); // step 3: get availableToClaim uint256 availableToClaim = _availableToClaim(_user, _zroAmount); if (availableToClaim == 0) revert AlreadyClaimed(_user); // step 4: transfer the ZRO tokens IERC20(zroToken).safeTransfer(_to, availableToClaim); emit Claim(_user, _zroAmount, availableToClaim, _to); } function _lzReceive( Origin calldata _origin, bytes32 /*_guid*/, bytes calldata _payload, address /*_executor*/, bytes calldata /*_extraData*/ ) internal override { (address user, uint256 zroAmount, address to) = abi.decode(_payload, (address, uint256, address)); // msg.sender in this case is the endpoint uint256 availableToClaim = _availableToClaim(user, zroAmount); // @dev We only proceed to send the tokens if there is still something to be claimed if (availableToClaim != 0) { bytes memory emptyBytes = new bytes(0); SendParam memory sendParams = SendParam({ dstEid: _origin.srcEid, to: addressToBytes32(to), amountLD: availableToClaim, minAmountLD: 0, // No fees on ZRO token, only slippage is dust removal extraOptions: emptyBytes, composeMsg: emptyBytes, oftCmd: emptyBytes }); // Pass all the balance of this contract, including msg.value to fund the b->a lz fee // The ClaimRemote contracts will have an enforced option that should cover the fare back, but to ease UX // We can maintain a balance in this contract to cover slippage // solhint-disable-next-line check-send-result IOFT(zroToken).send{ value: address(this).balance }( sendParams, MessagingFee(address(this).balance, 0), address(this) ); } // @dev The event will be emitted in either case - regardless of whether there still was something to claim or not emit ClaimRemote(user, zroAmount, availableToClaim, _origin.srcEid, to); } function _availableToClaim(address _user, uint256 _zroAmount) internal returns (uint256) { // prevents a user from claiming more than once uint256 alreadyClaimed = zroClaimed[_user]; // @dev If there is nothing left to claim, we'll return 0 // @dev This then needs to be further handled by the caller of this method if (_zroAmount <= alreadyClaimed) return 0; zroClaimed[_user] = _zroAmount; return _zroAmount - alreadyClaimed; } /** * @notice Quote the native amount to send ZRO across chains * @param _dstEid The destination endpoint ID * @param _zroAmount The amount of ZRO tokens to send * @return msgFee The fee for the message */ function quoteClaimCallback(uint32 _dstEid, uint256 _zroAmount) external view returns (MessagingFee memory msgFee) { // provides the ability to determine how much "msg.value" to pass in the executor options on a remote claim bytes memory emptyBytes = new bytes(0); SendParam memory sendParams = SendParam({ dstEid: _dstEid, to: addressToBytes32(msg.sender), amountLD: _zroAmount, minAmountLD: 0, // No fees on ZRO token, only slippage is dust removal extraOptions: emptyBytes, composeMsg: emptyBytes, oftCmd: emptyBytes }); return IOFT(zroToken).quoteSend(sendParams, false); } function addressToBytes32(address _addr) internal pure returns (bytes32) { return bytes32(uint256(uint160(_addr))); } receive() external payable {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { ILayerZeroEndpointV2 } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; /** * @title IOAppCore */ interface IOAppCore { // Custom error messages error OnlyPeer(uint32 eid, bytes32 sender); error NoPeer(uint32 eid); error InvalidEndpointCall(); error InvalidDelegate(); // Event emitted when a peer (OApp) is set for a corresponding endpoint event PeerSet(uint32 eid, bytes32 peer); /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol contract. * @return receiverVersion The version of the OAppReceiver.sol contract. */ function oAppVersion() external view returns (uint64 senderVersion, uint64 receiverVersion); /** * @notice Retrieves the LayerZero endpoint associated with the OApp. * @return iEndpoint The LayerZero endpoint as an interface. */ function endpoint() external view returns (ILayerZeroEndpointV2 iEndpoint); /** * @notice Retrieves the peer (OApp) associated with a corresponding endpoint. * @param _eid The endpoint ID. * @return peer The peer address (OApp instance) associated with the corresponding endpoint. */ function peers(uint32 _eid) external view returns (bytes32 peer); /** * @notice Sets the peer address (OApp instance) for a corresponding endpoint. * @param _eid The endpoint ID. * @param _peer The address of the peer to be associated with the corresponding endpoint. */ function setPeer(uint32 _eid, bytes32 _peer) external; /** * @notice Sets the delegate address for the OApp Core. * @param _delegate The address of the delegate to be set. */ function setDelegate(address _delegate) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @dev Struct representing enforced option parameters. */ struct EnforcedOptionParam { uint32 eid; // Endpoint ID uint16 msgType; // Message Type bytes options; // Additional options } /** * @title IOAppOptionsType3 * @dev Interface for the OApp with Type 3 Options, allowing the setting and combining of enforced options. */ interface IOAppOptionsType3 { // Custom error message for invalid options error InvalidOptions(bytes options); // Event emitted when enforced options are set event EnforcedOptionSet(EnforcedOptionParam[] _enforcedOptions); /** * @notice Sets enforced options for specific endpoint and message type combinations. * @param _enforcedOptions An array of EnforcedOptionParam structures specifying enforced options. */ function setEnforcedOptions(EnforcedOptionParam[] calldata _enforcedOptions) external; /** * @notice Combines options for a given endpoint and message type. * @param _eid The endpoint ID. * @param _msgType The OApp message type. * @param _extraOptions Additional options passed by the caller. * @return options The combination of caller specified options AND enforced options. */ function combineOptions( uint32 _eid, uint16 _msgType, bytes calldata _extraOptions ) external view returns (bytes memory options); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { ILayerZeroReceiver, Origin } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroReceiver.sol"; interface IOAppReceiver is ILayerZeroReceiver { /** * @notice Indicates whether an address is an approved composeMsg sender to the Endpoint. * @param _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @param _message The lzReceive payload. * @param _sender The sender address. * @return isSender Is a valid sender. * * @dev Applications can optionally choose to implement a separate composeMsg sender that is NOT the bridging layer. * @dev The default sender IS the OAppReceiver implementer. */ function isComposeMsgSender( Origin calldata _origin, bytes calldata _message, address _sender ) external view returns (bool isSender); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { IOAppOptionsType3, EnforcedOptionParam } from "../interfaces/IOAppOptionsType3.sol"; /** * @title OAppOptionsType3 * @dev Abstract contract implementing the IOAppOptionsType3 interface with type 3 options. */ abstract contract OAppOptionsType3 is IOAppOptionsType3, Ownable { uint16 internal constant OPTION_TYPE_3 = 3; // @dev The "msgType" should be defined in the child contract. mapping(uint32 eid => mapping(uint16 msgType => bytes enforcedOption)) public enforcedOptions; /** * @dev Sets the enforced options for specific endpoint and message type combinations. * @param _enforcedOptions An array of EnforcedOptionParam structures specifying enforced options. * * @dev Only the owner/admin of the OApp can call this function. * @dev Provides a way for the OApp to enforce things like paying for PreCrime, AND/OR minimum dst lzReceive gas amounts etc. * @dev These enforced options can vary as the potential options/execution on the remote may differ as per the msgType. * eg. Amount of lzReceive() gas necessary to deliver a lzCompose() message adds overhead you dont want to pay * if you are only making a standard LayerZero message ie. lzReceive() WITHOUT sendCompose(). */ function setEnforcedOptions(EnforcedOptionParam[] calldata _enforcedOptions) public virtual onlyOwner { _setEnforcedOptions(_enforcedOptions); } /** * @dev Sets the enforced options for specific endpoint and message type combinations. * @param _enforcedOptions An array of EnforcedOptionParam structures specifying enforced options. * * @dev Provides a way for the OApp to enforce things like paying for PreCrime, AND/OR minimum dst lzReceive gas amounts etc. * @dev These enforced options can vary as the potential options/execution on the remote may differ as per the msgType. * eg. Amount of lzReceive() gas necessary to deliver a lzCompose() message adds overhead you dont want to pay * if you are only making a standard LayerZero message ie. lzReceive() WITHOUT sendCompose(). */ function _setEnforcedOptions(EnforcedOptionParam[] memory _enforcedOptions) internal virtual { for (uint256 i = 0; i < _enforcedOptions.length; i++) { // @dev Enforced options are only available for optionType 3, as type 1 and 2 dont support combining. _assertOptionsType3(_enforcedOptions[i].options); enforcedOptions[_enforcedOptions[i].eid][_enforcedOptions[i].msgType] = _enforcedOptions[i].options; } emit EnforcedOptionSet(_enforcedOptions); } /** * @notice Combines options for a given endpoint and message type. * @param _eid The endpoint ID. * @param _msgType The OAPP message type. * @param _extraOptions Additional options passed by the caller. * @return options The combination of caller specified options AND enforced options. * * @dev If there is an enforced lzReceive option: * - {gasLimit: 200k, msg.value: 1 ether} AND a caller supplies a lzReceive option: {gasLimit: 100k, msg.value: 0.5 ether} * - The resulting options will be {gasLimit: 300k, msg.value: 1.5 ether} when the message is executed on the remote lzReceive() function. * @dev This presence of duplicated options is handled off-chain in the verifier/executor. */ function combineOptions( uint32 _eid, uint16 _msgType, bytes calldata _extraOptions ) public view virtual returns (bytes memory) { bytes memory enforced = enforcedOptions[_eid][_msgType]; // No enforced options, pass whatever the caller supplied, even if it's empty or legacy type 1/2 options. if (enforced.length == 0) return _extraOptions; // No caller options, return enforced if (_extraOptions.length == 0) return enforced; // @dev If caller provided _extraOptions, must be type 3 as its the ONLY type that can be combined. if (_extraOptions.length >= 2) { _assertOptionsType3(_extraOptions); // @dev Remove the first 2 bytes containing the type from the _extraOptions and combine with enforced. return bytes.concat(enforced, _extraOptions[2:]); } // No valid set of options was found. revert InvalidOptions(_extraOptions); } /** * @dev Internal function to assert that options are of type 3. * @param _options The options to be checked. */ function _assertOptionsType3(bytes memory _options) internal pure virtual { uint16 optionsType; assembly { optionsType := mload(add(_options, 2)) } if (optionsType != OPTION_TYPE_3) revert InvalidOptions(_options); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { IOAppCore, ILayerZeroEndpointV2 } from "./interfaces/IOAppCore.sol"; /** * @title OAppCore * @dev Abstract contract implementing the IOAppCore interface with basic OApp configurations. */ abstract contract OAppCore is IOAppCore, Ownable { // The LayerZero endpoint associated with the given OApp ILayerZeroEndpointV2 public immutable endpoint; // Mapping to store peers associated with corresponding endpoints mapping(uint32 eid => bytes32 peer) public peers; /** * @dev Constructor to initialize the OAppCore with the provided endpoint and delegate. * @param _endpoint The address of the LOCAL Layer Zero endpoint. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. * * @dev The delegate typically should be set as the owner of the contract. */ constructor(address _endpoint, address _delegate) { endpoint = ILayerZeroEndpointV2(_endpoint); if (_delegate == address(0)) revert InvalidDelegate(); endpoint.setDelegate(_delegate); } /** * @notice Sets the peer address (OApp instance) for a corresponding endpoint. * @param _eid The endpoint ID. * @param _peer The address of the peer to be associated with the corresponding endpoint. * * @dev Only the owner/admin of the OApp can call this function. * @dev Indicates that the peer is trusted to send LayerZero messages to this OApp. * @dev Set this to bytes32(0) to remove the peer address. * @dev Peer is a bytes32 to accommodate non-evm chains. */ function setPeer(uint32 _eid, bytes32 _peer) public virtual onlyOwner { _setPeer(_eid, _peer); } /** * @notice Sets the peer address (OApp instance) for a corresponding endpoint. * @param _eid The endpoint ID. * @param _peer The address of the peer to be associated with the corresponding endpoint. * * @dev Indicates that the peer is trusted to send LayerZero messages to this OApp. * @dev Set this to bytes32(0) to remove the peer address. * @dev Peer is a bytes32 to accommodate non-evm chains. */ function _setPeer(uint32 _eid, bytes32 _peer) internal virtual { peers[_eid] = _peer; emit PeerSet(_eid, _peer); } /** * @notice Internal function to get the peer address associated with a specific endpoint; reverts if NOT set. * ie. the peer is set to bytes32(0). * @param _eid The endpoint ID. * @return peer The address of the peer associated with the specified endpoint. */ function _getPeerOrRevert(uint32 _eid) internal view virtual returns (bytes32) { bytes32 peer = peers[_eid]; if (peer == bytes32(0)) revert NoPeer(_eid); return peer; } /** * @notice Sets the delegate address for the OApp. * @param _delegate The address of the delegate to be set. * * @dev Only the owner/admin of the OApp can call this function. * @dev Provides the ability for a delegate to set configs, on behalf of the OApp, directly on the Endpoint contract. */ function setDelegate(address _delegate) public onlyOwner { endpoint.setDelegate(_delegate); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { IOAppReceiver, Origin } from "./interfaces/IOAppReceiver.sol"; import { OAppCore } from "./OAppCore.sol"; /** * @title OAppReceiver * @dev Abstract contract implementing the ILayerZeroReceiver interface and extending OAppCore for OApp receivers. */ abstract contract OAppReceiver is IOAppReceiver, OAppCore { // Custom error message for when the caller is not the registered endpoint/ error OnlyEndpoint(address addr); // @dev The version of the OAppReceiver implementation. // @dev Version is bumped when changes are made to this contract. uint64 internal constant RECEIVER_VERSION = 2; /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol contract. * @return receiverVersion The version of the OAppReceiver.sol contract. * * @dev Providing 0 as the default for OAppSender version. Indicates that the OAppSender is not implemented. * ie. this is a RECEIVE only OApp. * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct versions. */ function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) { return (0, RECEIVER_VERSION); } /** * @notice Indicates whether an address is an approved composeMsg sender to the Endpoint. * @dev _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @dev _message The lzReceive payload. * @param _sender The sender address. * @return isSender Is a valid sender. * * @dev Applications can optionally choose to implement separate composeMsg senders that are NOT the bridging layer. * @dev The default sender IS the OAppReceiver implementer. */ function isComposeMsgSender( Origin calldata /*_origin*/, bytes calldata /*_message*/, address _sender ) public view virtual returns (bool) { return _sender == address(this); } /** * @notice Checks if the path initialization is allowed based on the provided origin. * @param origin The origin information containing the source endpoint and sender address. * @return Whether the path has been initialized. * * @dev This indicates to the endpoint that the OApp has enabled msgs for this particular path to be received. * @dev This defaults to assuming if a peer has been set, its initialized. * Can be overridden by the OApp if there is other logic to determine this. */ function allowInitializePath(Origin calldata origin) public view virtual returns (bool) { return peers[origin.srcEid] == origin.sender; } /** * @notice Retrieves the next nonce for a given source endpoint and sender address. * @dev _srcEid The source endpoint ID. * @dev _sender The sender address. * @return nonce The next nonce. * * @dev The path nonce starts from 1. If 0 is returned it means that there is NO nonce ordered enforcement. * @dev Is required by the off-chain executor to determine the OApp expects msg execution is ordered. * @dev This is also enforced by the OApp. * @dev By default this is NOT enabled. ie. nextNonce is hardcoded to return 0. */ function nextNonce(uint32 /*_srcEid*/, bytes32 /*_sender*/) public view virtual returns (uint64 nonce) { return 0; } /** * @dev Entry point for receiving messages or packets from the endpoint. * @param _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @param _guid The unique identifier for the received LayerZero message. * @param _message The payload of the received message. * @param _executor The address of the executor for the received message. * @param _extraData Additional arbitrary data provided by the corresponding executor. * * @dev Entry point for receiving msg/packet from the LayerZero endpoint. */ function lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) public payable virtual { // Ensures that only the endpoint can attempt to lzReceive() messages to this OApp. if (address(endpoint) != msg.sender) revert OnlyEndpoint(msg.sender); // Ensure that the sender matches the expected peer for the source endpoint. if (_getPeerOrRevert(_origin.srcEid) != _origin.sender) revert OnlyPeer(_origin.srcEid, _origin.sender); // Call the internal OApp implementation of lzReceive. _lzReceive(_origin, _guid, _message, _executor, _extraData); } /** * @dev Internal function to implement lzReceive logic without needing to copy the basic parameter validation. */ function _lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) internal virtual; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { SafeERC20, IERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { MessagingParams, MessagingFee, MessagingReceipt } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; import { OAppCore } from "./OAppCore.sol"; /** * @title OAppSender * @dev Abstract contract implementing the OAppSender functionality for sending messages to a LayerZero endpoint. */ abstract contract OAppSender is OAppCore { using SafeERC20 for IERC20; // Custom error messages error NotEnoughNative(uint256 msgValue); error LzTokenUnavailable(); // @dev The version of the OAppSender implementation. // @dev Version is bumped when changes are made to this contract. uint64 internal constant SENDER_VERSION = 1; /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol contract. * @return receiverVersion The version of the OAppReceiver.sol contract. * * @dev Providing 0 as the default for OAppReceiver version. Indicates that the OAppReceiver is not implemented. * ie. this is a SEND only OApp. * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct versions */ function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) { return (SENDER_VERSION, 0); } /** * @dev Internal function to interact with the LayerZero EndpointV2.quote() for fee calculation. * @param _dstEid The destination endpoint ID. * @param _message The message payload. * @param _options Additional options for the message. * @param _payInLzToken Flag indicating whether to pay the fee in LZ tokens. * @return fee The calculated MessagingFee for the message. * - nativeFee: The native fee for the message. * - lzTokenFee: The LZ token fee for the message. */ function _quote( uint32 _dstEid, bytes memory _message, bytes memory _options, bool _payInLzToken ) internal view virtual returns (MessagingFee memory fee) { return endpoint.quote( MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _payInLzToken), address(this) ); } /** * @dev Internal function to interact with the LayerZero EndpointV2.send() for sending a message. * @param _dstEid The destination endpoint ID. * @param _message The message payload. * @param _options Additional options for the message. * @param _fee The calculated LayerZero fee for the message. * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. * @param _refundAddress The address to receive any excess fee values sent to the endpoint. * @return receipt The receipt for the sent message. * - guid: The unique identifier for the sent message. * - nonce: The nonce of the sent message. * - fee: The LayerZero fee incurred for the message. */ function _lzSend( uint32 _dstEid, bytes memory _message, bytes memory _options, MessagingFee memory _fee, address _refundAddress ) internal virtual returns (MessagingReceipt memory receipt) { // @dev Push corresponding fees to the endpoint, any excess is sent back to the _refundAddress from the endpoint. uint256 messageValue = _payNative(_fee.nativeFee); if (_fee.lzTokenFee > 0) _payLzToken(_fee.lzTokenFee); return // solhint-disable-next-line check-send-result endpoint.send{ value: messageValue }( MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _fee.lzTokenFee > 0), _refundAddress ); } /** * @dev Internal function to pay the native fee associated with the message. * @param _nativeFee The native fee to be paid. * @return nativeFee The amount of native currency paid. * * @dev If the OApp needs to initiate MULTIPLE LayerZero messages in a single transaction, * this will need to be overridden because msg.value would contain multiple lzFees. * @dev Should be overridden in the event the LayerZero endpoint requires a different native currency. * @dev Some EVMs use an ERC20 as a method for paying transactions/gasFees. * @dev The endpoint is EITHER/OR, ie. it will NOT support both types of native payment at a time. */ function _payNative(uint256 _nativeFee) internal virtual returns (uint256 nativeFee) { if (msg.value != _nativeFee) revert NotEnoughNative(msg.value); return _nativeFee; } /** * @dev Internal function to pay the LZ token fee associated with the message. * @param _lzTokenFee The LZ token fee to be paid. * * @dev If the caller is trying to pay in the specified lzToken, then the lzTokenFee is passed to the endpoint. * @dev Any excess sent, is passed back to the specified _refundAddress in the _lzSend(). */ function _payLzToken(uint256 _lzTokenFee) internal virtual { // @dev Cannot cache the token because it is not immutable in the endpoint. address lzToken = endpoint.lzToken(); if (lzToken == address(0)) revert LzTokenUnavailable(); // Pay LZ token fee by sending tokens to the endpoint. IERC20(lzToken).safeTransferFrom(msg.sender, address(endpoint), _lzTokenFee); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title RateLimiter * @dev Abstract contract for implementing rate limiting functionality. This contract provides a basic framework for * rate limiting how often a function can be executed. It is designed to be inherited by other contracts requiring rate * limiting capabilities to protect resources or services from excessive use. * * Example 1: Max rate limit reached at beginning of window. As time continues the amount of in flights comes down. * * Rate Limit Config: * limit: 100 units * window: 60 seconds * * Amount in Flight (units) vs. Time Graph (seconds) * * 100 | * - (Max limit reached at beginning of window) * | * * | * * | * * 50 | * (After 30 seconds only 50 units in flight) * | * * | * * | * * 0 +--|---|---|---|---|-->(After 60 seconds 0 units are in flight) * 0 15 30 45 60 (seconds) * * Example 2: Max rate limit reached at beginning of window. As time continues the amount of in flights comes down * allowing for more to be sent. At the 90 second mark, more in flights come in. * * Rate Limit Config: * limit: 100 units * window: 60 seconds * * Amount in Flight (units) vs. Time Graph (seconds) * * 100 | * - (Max limit reached at beginning of window) * | * * | * * | * * 50 | * * (50 inflight) * | * * * | * * * | * * * 0 +--|--|--|--|--|--|--|--|--|--> Time * 0 15 30 45 60 75 90 105 120 (seconds) * * Example 3: Max rate limit reached at beginning of window. At the 15 second mark, the window gets updated to 60 * seconds and the limit gets updated to 50 units. This scenario shows the direct depiction of "in flight" from the * previous window affecting the current window. * * Initial Rate Limit Config: For first 15 seconds * limit: 100 units * window: 30 seconds * * Updated Rate Limit Config: Updated at 15 second mark * limit: 50 units * window: 60 seconds * * Amount in Flight (units) vs. Time Graph (seconds) * 100 - * * |* * | * * | * * | * * | * * | * * 75 - | * * | * * | * * | * * | * * | * * | * * | * * 50 - | 𐫰 <--(Slope changes at the 15 second mark because of the update. * | ✧ * Window extended to 60 seconds and limit reduced to 50 units. * | ✧ ︎ * Because amountInFlight/lastUpdated do not reset, 50 units are * | ✧ * considered in flight from the previous window and the corresponding * | ✧ ︎ * decay from the previous rate.) * | ✧ * * 25 - | ✧ * * | ✧ * * | ✧ * * | ✧ * * | ✧ * * | ✧ * * | ✧ * * | ✧ * * 0 - +---|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----> Time * 0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 (seconds) * [ Initial 30 Second Window ] * [ --------------- Extended 60 Second Window --------------- ] */ abstract contract RateLimiter { /** * @notice Rate Limit struct. * @param amountInFlight The amount in the current window. * @param lastUpdated Timestamp representing the last time the rate limit was checked or updated. * @param limit This represents the maximum allowed amount within a given window. * @param window Defines the duration of the rate limiting window. */ struct RateLimit { uint256 amountInFlight; uint256 lastUpdated; uint256 limit; uint256 window; } /** * @notice Rate Limit Configuration struct. * @param dstEid The destination endpoint id. * @param limit This represents the maximum allowed amount within a given window. * @param window Defines the duration of the rate limiting window. */ struct RateLimitConfig { uint32 dstEid; uint256 limit; uint256 window; } /** * @dev Mapping from destination endpoint id to RateLimit Configurations. */ mapping(uint32 dstEid => RateLimit limit) public rateLimits; /** * @notice Emitted when _setRateLimits occurs. * @param rateLimitConfigs An array of `RateLimitConfig` structs representing the rate limit configurations set. * - `dstEid`: The destination endpoint id. * - `limit`: This represents the maximum allowed amount within a given window. * - `window`: Defines the duration of the rate limiting window. */ event RateLimitsChanged(RateLimitConfig[] rateLimitConfigs); /** * @notice Error that is thrown when an amount exceeds the rate_limit. */ error RateLimitExceeded(); /** * @notice Get the current amount that can be sent to this destination endpoint id for the given rate limit window. * @param _dstEid The destination endpoint id. * @return currentAmountInFlight The current amount that was sent. * @return amountCanBeSent The amount that can be sent. */ function getAmountCanBeSent( uint32 _dstEid ) external view virtual returns (uint256 currentAmountInFlight, uint256 amountCanBeSent) { RateLimit memory rl = rateLimits[_dstEid]; return _amountCanBeSent(rl.amountInFlight, rl.lastUpdated, rl.limit, rl.window); } /** * @notice Sets the Rate Limit. * @param _rateLimitConfigs A `RateLimitConfig` struct representing the rate limit configuration. * - `dstEid`: The destination endpoint id. * - `limit`: This represents the maximum allowed amount within a given window. * - `window`: Defines the duration of the rate limiting window. */ function _setRateLimits(RateLimitConfig[] memory _rateLimitConfigs) internal virtual { unchecked { for (uint256 i = 0; i < _rateLimitConfigs.length; i++) { RateLimit storage rl = rateLimits[_rateLimitConfigs[i].dstEid]; // @dev Ensure we checkpoint the existing rate limit as to not retroactively apply the new decay rate. _checkAndUpdateRateLimit(_rateLimitConfigs[i].dstEid, 0); // @dev Does NOT reset the amountInFlight/lastUpdated of an existing rate limit. rl.limit = _rateLimitConfigs[i].limit; rl.window = _rateLimitConfigs[i].window; } } emit RateLimitsChanged(_rateLimitConfigs); } /** * @notice Checks current amount in flight and amount that can be sent for a given rate limit window. * @param _amountInFlight The amount in the current window. * @param _lastUpdated Timestamp representing the last time the rate limit was checked or updated. * @param _limit This represents the maximum allowed amount within a given window. * @param _window Defines the duration of the rate limiting window. * @return currentAmountInFlight The amount in the current window. * @return amountCanBeSent The amount that can be sent. */ function _amountCanBeSent( uint256 _amountInFlight, uint256 _lastUpdated, uint256 _limit, uint256 _window ) internal view virtual returns (uint256 currentAmountInFlight, uint256 amountCanBeSent) { uint256 timeSinceLastDeposit = block.timestamp - _lastUpdated; if (timeSinceLastDeposit >= _window) { currentAmountInFlight = 0; amountCanBeSent = _limit; } else { // @dev Presumes linear decay. uint256 decay = (_limit * timeSinceLastDeposit) / _window; currentAmountInFlight = _amountInFlight <= decay ? 0 : _amountInFlight - decay; // @dev In the event the _limit is lowered, and the 'in-flight' amount is higher than the _limit, set to 0. amountCanBeSent = _limit <= currentAmountInFlight ? 0 : _limit - currentAmountInFlight; } } /** * @notice Verifies whether the specified amount falls within the rate limit constraints for the targeted * endpoint ID. On successful verification, it updates amountInFlight and lastUpdated. If the amount exceeds * the rate limit, the operation reverts. * @param _dstEid The destination endpoint id. * @param _amount The amount to check for rate limit constraints. */ function _checkAndUpdateRateLimit(uint32 _dstEid, uint256 _amount) internal virtual { // @dev By default dstEid that have not been explicitly set will return amountCanBeSent == 0. RateLimit storage rl = rateLimits[_dstEid]; (uint256 currentAmountInFlight, uint256 amountCanBeSent) = _amountCanBeSent( rl.amountInFlight, rl.lastUpdated, rl.limit, rl.window ); if (_amount > amountCanBeSent) revert RateLimitExceeded(); // @dev Update the storage to contain the new amount and current timestamp. rl.amountInFlight = currentAmountInFlight + _amount; rl.lastUpdated = block.timestamp; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { MessagingReceipt, MessagingFee } from "../../oapp/OAppSender.sol"; /** * @dev Struct representing token parameters for the OFT send() operation. */ struct SendParam { uint32 dstEid; // Destination endpoint ID. bytes32 to; // Recipient address. uint256 amountLD; // Amount to send in local decimals. uint256 minAmountLD; // Minimum amount to send in local decimals. bytes extraOptions; // Additional options supplied by the caller to be used in the LayerZero message. bytes composeMsg; // The composed message for the send() operation. bytes oftCmd; // The OFT command to be executed, unused in default OFT implementations. } /** * @dev Struct representing OFT limit information. * @dev These amounts can change dynamically and are up the the specific oft implementation. */ struct OFTLimit { uint256 minAmountLD; // Minimum amount in local decimals that can be sent to the recipient. uint256 maxAmountLD; // Maximum amount in local decimals that can be sent to the recipient. } /** * @dev Struct representing OFT receipt information. */ struct OFTReceipt { uint256 amountSentLD; // Amount of tokens ACTUALLY debited from the sender in local decimals. // @dev In non-default implementations, the amountReceivedLD COULD differ from this value. uint256 amountReceivedLD; // Amount of tokens to be received on the remote side. } /** * @dev Struct representing OFT fee details. * @dev Future proof mechanism to provide a standardized way to communicate fees to things like a UI. */ struct OFTFeeDetail { int256 feeAmountLD; // Amount of the fee in local decimals. string description; // Description of the fee. } /** * @title IOFT * @dev Interface for the OftChain (OFT) token. * @dev Does not inherit ERC20 to accommodate usage by OFTAdapter as well. * @dev This specific interface ID is '0x02e49c2c'. */ interface IOFT { // Custom error messages error InvalidLocalDecimals(); error SlippageExceeded(uint256 amountLD, uint256 minAmountLD); // Events event OFTSent( bytes32 indexed guid, // GUID of the OFT message. uint32 dstEid, // Destination Endpoint ID. address indexed fromAddress, // Address of the sender on the src chain. uint256 amountSentLD, // Amount of tokens sent in local decimals. uint256 amountReceivedLD // Amount of tokens received in local decimals. ); event OFTReceived( bytes32 indexed guid, // GUID of the OFT message. uint32 srcEid, // Source Endpoint ID. address indexed toAddress, // Address of the recipient on the dst chain. uint256 amountReceivedLD // Amount of tokens received in local decimals. ); /** * @notice Retrieves interfaceID and the version of the OFT. * @return interfaceId The interface ID. * @return version The version. * * @dev interfaceId: This specific interface ID is '0x02e49c2c'. * @dev version: Indicates a cross-chain compatible msg encoding with other OFTs. * @dev If a new feature is added to the OFT cross-chain msg encoding, the version will be incremented. * ie. localOFT version(x,1) CAN send messages to remoteOFT version(x,1) */ function oftVersion() external view returns (bytes4 interfaceId, uint64 version); /** * @notice Retrieves the address of the token associated with the OFT. * @return token The address of the ERC20 token implementation. */ function token() external view returns (address); /** * @notice Indicates whether the OFT contract requires approval of the 'token()' to send. * @return requiresApproval Needs approval of the underlying token implementation. * * @dev Allows things like wallet implementers to determine integration requirements, * without understanding the underlying token implementation. */ function approvalRequired() external view returns (bool); /** * @notice Retrieves the shared decimals of the OFT. * @return sharedDecimals The shared decimals of the OFT. */ function sharedDecimals() external view returns (uint8); /** * @notice Provides a quote for OFT-related operations. * @param _sendParam The parameters for the send operation. * @return limit The OFT limit information. * @return oftFeeDetails The details of OFT fees. * @return receipt The OFT receipt information. */ function quoteOFT( SendParam calldata _sendParam ) external view returns (OFTLimit memory, OFTFeeDetail[] memory oftFeeDetails, OFTReceipt memory); /** * @notice Provides a quote for the send() operation. * @param _sendParam The parameters for the send() operation. * @param _payInLzToken Flag indicating whether the caller is paying in the LZ token. * @return fee The calculated LayerZero messaging fee from the send() operation. * * @dev MessagingFee: LayerZero msg fee * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. */ function quoteSend(SendParam calldata _sendParam, bool _payInLzToken) external view returns (MessagingFee memory); /** * @notice Executes the send() operation. * @param _sendParam The parameters for the send operation. * @param _fee The fee information supplied by the caller. * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. * @param _refundAddress The address to receive any excess funds from fees etc. on the src. * @return receipt The LayerZero messaging receipt from the send() operation. * @return oftReceipt The OFT receipt information. * * @dev MessagingReceipt: LayerZero msg receipt * - guid: The unique identifier for the sent message. * - nonce: The nonce of the sent message. * - fee: The LayerZero fee incurred for the message. */ function send( SendParam calldata _sendParam, MessagingFee calldata _fee, address _refundAddress ) external payable returns (MessagingReceipt memory, OFTReceipt memory); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; import { IMessageLibManager } from "./IMessageLibManager.sol"; import { IMessagingComposer } from "./IMessagingComposer.sol"; import { IMessagingChannel } from "./IMessagingChannel.sol"; import { IMessagingContext } from "./IMessagingContext.sol"; struct MessagingParams { uint32 dstEid; bytes32 receiver; bytes message; bytes options; bool payInLzToken; } struct MessagingReceipt { bytes32 guid; uint64 nonce; MessagingFee fee; } struct MessagingFee { uint256 nativeFee; uint256 lzTokenFee; } struct Origin { uint32 srcEid; bytes32 sender; uint64 nonce; } interface ILayerZeroEndpointV2 is IMessageLibManager, IMessagingComposer, IMessagingChannel, IMessagingContext { event PacketSent(bytes encodedPayload, bytes options, address sendLibrary); event PacketVerified(Origin origin, address receiver, bytes32 payloadHash); event PacketDelivered(Origin origin, address receiver); event LzReceiveAlert( address indexed receiver, address indexed executor, Origin origin, bytes32 guid, uint256 gas, uint256 value, bytes message, bytes extraData, bytes reason ); event LzTokenSet(address token); event DelegateSet(address sender, address delegate); function quote(MessagingParams calldata _params, address _sender) external view returns (MessagingFee memory); function send( MessagingParams calldata _params, address _refundAddress ) external payable returns (MessagingReceipt memory); function verify(Origin calldata _origin, address _receiver, bytes32 _payloadHash) external; function verifiable(Origin calldata _origin, address _receiver) external view returns (bool); function initializable(Origin calldata _origin, address _receiver) external view returns (bool); function lzReceive( Origin calldata _origin, address _receiver, bytes32 _guid, bytes calldata _message, bytes calldata _extraData ) external payable; // oapp can burn messages partially by calling this function with its own business logic if messages are verified in order function clear(address _oapp, Origin calldata _origin, bytes32 _guid, bytes calldata _message) external; function setLzToken(address _lzToken) external; function lzToken() external view returns (address); function nativeToken() external view returns (address); function setDelegate(address _delegate) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; import { Origin } from "./ILayerZeroEndpointV2.sol"; interface ILayerZeroReceiver { function allowInitializePath(Origin calldata _origin) external view returns (bool); function nextNonce(uint32 _eid, bytes32 _sender) external view returns (uint64); function lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) external payable; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; struct SetConfigParam { uint32 eid; uint32 configType; bytes config; } interface IMessageLibManager { struct Timeout { address lib; uint256 expiry; } event LibraryRegistered(address newLib); event DefaultSendLibrarySet(uint32 eid, address newLib); event DefaultReceiveLibrarySet(uint32 eid, address newLib); event DefaultReceiveLibraryTimeoutSet(uint32 eid, address oldLib, uint256 expiry); event SendLibrarySet(address sender, uint32 eid, address newLib); event ReceiveLibrarySet(address receiver, uint32 eid, address newLib); event ReceiveLibraryTimeoutSet(address receiver, uint32 eid, address oldLib, uint256 timeout); function registerLibrary(address _lib) external; function isRegisteredLibrary(address _lib) external view returns (bool); function getRegisteredLibraries() external view returns (address[] memory); function setDefaultSendLibrary(uint32 _eid, address _newLib) external; function defaultSendLibrary(uint32 _eid) external view returns (address); function setDefaultReceiveLibrary(uint32 _eid, address _newLib, uint256 _gracePeriod) external; function defaultReceiveLibrary(uint32 _eid) external view returns (address); function setDefaultReceiveLibraryTimeout(uint32 _eid, address _lib, uint256 _expiry) external; function defaultReceiveLibraryTimeout(uint32 _eid) external view returns (address lib, uint256 expiry); function isSupportedEid(uint32 _eid) external view returns (bool); function isValidReceiveLibrary(address _receiver, uint32 _eid, address _lib) external view returns (bool); /// ------------------- OApp interfaces ------------------- function setSendLibrary(address _oapp, uint32 _eid, address _newLib) external; function getSendLibrary(address _sender, uint32 _eid) external view returns (address lib); function isDefaultSendLibrary(address _sender, uint32 _eid) external view returns (bool); function setReceiveLibrary(address _oapp, uint32 _eid, address _newLib, uint256 _gracePeriod) external; function getReceiveLibrary(address _receiver, uint32 _eid) external view returns (address lib, bool isDefault); function setReceiveLibraryTimeout(address _oapp, uint32 _eid, address _lib, uint256 _expiry) external; function receiveLibraryTimeout(address _receiver, uint32 _eid) external view returns (address lib, uint256 expiry); function setConfig(address _oapp, address _lib, SetConfigParam[] calldata _params) external; function getConfig( address _oapp, address _lib, uint32 _eid, uint32 _configType ) external view returns (bytes memory config); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; interface IMessagingChannel { event InboundNonceSkipped(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce); event PacketNilified(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash); event PacketBurnt(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash); function eid() external view returns (uint32); // this is an emergency function if a message cannot be verified for some reasons // required to provide _nextNonce to avoid race condition function skip(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce) external; function nilify(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external; function burn(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external; function nextGuid(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (bytes32); function inboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64); function outboundNonce(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (uint64); function inboundPayloadHash( address _receiver, uint32 _srcEid, bytes32 _sender, uint64 _nonce ) external view returns (bytes32); function lazyInboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; interface IMessagingComposer { event ComposeSent(address from, address to, bytes32 guid, uint16 index, bytes message); event ComposeDelivered(address from, address to, bytes32 guid, uint16 index); event LzComposeAlert( address indexed from, address indexed to, address indexed executor, bytes32 guid, uint16 index, uint256 gas, uint256 value, bytes message, bytes extraData, bytes reason ); function composeQueue( address _from, address _to, bytes32 _guid, uint16 _index ) external view returns (bytes32 messageHash); function sendCompose(address _to, bytes32 _guid, uint16 _index, bytes calldata _message) external; function lzCompose( address _from, address _to, bytes32 _guid, uint16 _index, bytes calldata _message, bytes calldata _extraData ) external payable; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; interface IMessagingContext { function isSendingMessage() external view returns (bool); function getSendContext() external view returns (uint32 dstEid, address sender); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/Context.sol"; /** * @dev 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. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * 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. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; import {IERC20Permit} from "../extensions/IERC20Permit.sol"; import {Address} from "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev An operation with an ERC20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data); if (returndata.length != 0 && !abi.decode(returndata, (bool))) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol) pragma solidity ^0.8.20; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error AddressInsufficientBalance(address account); /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedInnerCall(); /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert AddressInsufficientBalance(address(this)); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert FailedInnerCall(); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {FailedInnerCall} error. * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an * unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {FailedInnerCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}. */ function _revert(bytes memory returndata) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert FailedInnerCall(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.20; /** * @dev These functions deal with verification of Merkle Tree proofs. * * The tree and the proofs can be generated using our * https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. * You will find a quickstart guide in the readme. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the Merkle tree could be reinterpreted as a leaf value. * OpenZeppelin's JavaScript library generates Merkle trees that are safe * against this attack out of the box. */ library MerkleProof { /** *@dev The multiproof provided is not valid. */ error MerkleProofInvalidMultiproof(); /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} */ function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the Merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. if (leavesLen + proofLen != totalHashes + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { if (proofPos != proofLen) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof}. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the Merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. if (leavesLen + proofLen != totalHashes + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { if (proofPos != proofLen) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Sorts the pair (a, b) and hashes the result. */ function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } /** * @dev Implementation of keccak256(abi.encode(a, b)) that doesn't allocate or expand memory. */ function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.22; import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import { MerkleProof } from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { IOFT } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oft/interfaces/IOFT.sol"; import { IClaim, IDonate, Currency, Donation } from "./IClaim.sol"; /** * @title ClaimCore */ abstract contract ClaimCore is IClaim, Ownable { bytes32 public merkleRoot; IDonate public immutable donateContract; uint256 public immutable numeratorUsdc; uint256 public immutable numeratorUsdt; uint256 public immutable numeratorNative; uint256 public constant DENOMINATOR = 10 ** 18; address public donateAndClaim; modifier onlyDonateAndClaim() { if (msg.sender != donateAndClaim) revert OnlyDonateAndClaim(); _; } constructor( bytes32 _merkleRoot, address _donateContract, address _stargateUsdc, address _stargateUsdt, address _stargateNative, uint256 _nativePrice, address _owner ) Ownable(_owner) { merkleRoot = _merkleRoot; donateContract = IDonate(_donateContract); if (_stargateUsdc != address(0)) { numeratorUsdc = 10 ** (IERC20Metadata(IOFT(_stargateUsdc).token()).decimals() - 1); // -1 for 10% } if (_stargateUsdt != address(0)) { numeratorUsdt = 10 ** (IERC20Metadata(IOFT(_stargateUsdt).token()).decimals() - 1); // -1 for 10% } // native is always denominated in 18 decimals if (_stargateNative != address(0)) { // Validate this is an actual native pool, eg. NOT WETH if (IOFT(_stargateNative).token() != address(0)) { revert InvalidNativeStargate(); } if (_nativePrice == 0) revert InvalidNativePrice(); numeratorNative = (10 ** (18 - 1)) / _nativePrice; // -1 for 10% } } function setDonateAndClaim(address _donateAndClaim) external onlyOwner { if (donateAndClaim != address(0)) revert DonateAndClaimAlreadySet(); donateAndClaim = _donateAndClaim; emit DonateAndClaimSet(_donateAndClaim); } /** * @notice Quote the donation amount * @param _zroAmount amount of zro to calculate required donation against * @return donation amount in native and stable coin. */ function requiredDonation(uint256 _zroAmount) public view returns (Donation memory) { uint256 usdc = (_zroAmount * numeratorUsdc) / DENOMINATOR; uint256 usdt = (_zroAmount * numeratorUsdt) / DENOMINATOR; uint256 native = (_zroAmount * numeratorNative) / DENOMINATOR; return Donation(usdc, usdt, native); } function assertDonation(Currency _currency, address _user, uint256 _zroAmount) public view { // retrieve the expected and actual donation amounts Donation memory expectedDonation = requiredDonation(_zroAmount); Donation memory actualDonation = donateContract.getDonation(_user); // numerator must be set, otherwise indicates theres an unsupported currency attempting to assert // this is a threshold, users can submit more than "required" if (_currency == Currency.USDC && numeratorUsdc > 0) { if (expectedDonation.usdc > actualDonation.usdc) { revert InsufficientDonation(_currency, expectedDonation.usdc, actualDonation.usdc); } } else if (_currency == Currency.USDT && numeratorUsdt > 0) { if (expectedDonation.usdt > actualDonation.usdt) { revert InsufficientDonation(_currency, expectedDonation.usdt, actualDonation.usdt); } } else if (_currency == Currency.Native && numeratorNative > 0) { if (expectedDonation.native > actualDonation.native) { revert InsufficientDonation(_currency, expectedDonation.native, actualDonation.native); } } else { revert IDonate.UnsupportedCurrency(_currency); } } /** * @notice Set the merkle root for the claim * @param _merkleRoot New merkle root */ function setMerkleRoot(bytes32 _merkleRoot) external onlyOwner { // Can be set to zero address to effectively pause merkleRoot = _merkleRoot; emit MerkleRootSet(_merkleRoot); } /** * @notice Leaf encode the user and amount * @param _account User address * @param _zroAmount Amount of ZRO * @return Leaf hash */ function _leafEncode(address _account, uint256 _zroAmount) internal pure returns (bytes32) { return keccak256(abi.encodePacked(keccak256(abi.encodePacked(_account, _zroAmount)))); } /** * @notice Verify the proof using the merkle root * @param _user User address * @param _zroAmount Amount of ZRO * @param _proof Merkle proof * @return True if proof is valid */ function _verifyProof( address _user, uint256 _zroAmount, bytes32[] calldata _proof ) internal view virtual returns (bool) { bytes32 leaf = _leafEncode(_user, _zroAmount); return MerkleProof.verify(_proof, merkleRoot, leaf); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.22; import { OAppOptionsType3 } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oapp/libs/OAppOptionsType3.sol"; import { OAppSender } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oapp/OAppSender.sol"; import { OAppCore } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oapp/OAppCore.sol"; import { RateLimiter } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oapp/utils/RateLimiter.sol"; // solhint-disable-next-line max-line-length import { MessagingFee, MessagingReceipt, MessagingParams } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; import { ClaimCore, Currency } from "./ClaimCore.sol"; /** * @title ZROClaimRemote */ contract ClaimRemote is ClaimCore, OAppSender, OAppOptionsType3, RateLimiter { uint8 internal constant MSG_TYPE_CLAIM = 1; uint32 public immutable remoteEid; constructor( uint32 _remoteEid, address _endpoint, bytes32 _merkleRoot, address _donateContract, address _stargateUsdc, address _stargateUsdt, address _stargateNative, uint256 _nativePrice, address _owner ) ClaimCore(_merkleRoot, _donateContract, _stargateUsdc, _stargateUsdt, _stargateNative, _nativePrice, _owner) OAppCore(_endpoint, _owner) { remoteEid = _remoteEid; } function setRateLimits(RateLimitConfig[] memory _rateLimitConfigs) external onlyOwner { _setRateLimits(_rateLimitConfigs); } /** * @notice Quote the fee for MSG_TYPE_CLAIM to claim tokens from a remote ZROClaimHub contract * @param _to The address to send the tokens to on this chain * @param _zroAmount The amount of tokens to claim * @param _extraOptions Additional options for the message * @return fee The MessagingFee for MSG_TYPE_CLAIM */ function quoteClaim( address _to, uint256 _zroAmount, bytes calldata _extraOptions ) external view virtual returns (MessagingFee memory fee) { bytes memory payload = abi.encode(msg.sender, _zroAmount, _to); bytes memory options = combineOptions(remoteEid, MSG_TYPE_CLAIM, _extraOptions); return _quote(remoteEid, payload, options, false); } /** * @notice Claim tokens from a remote ZROClaimHub contract. Pay for donation on source chain and send a LZ message * to the ZROClaimHub contract on the destination chain. Once the message is received, the ZRO tokens will be sent * back to this chain to the provided 'to' address * @param _currency The currency of the donation to be paid * @param _zroAmount The amount of tokens to claim * @param _proof The Merkle proof for the redemption * @param _to The address to send the tokens to on this chain * @param _extraOptions Additional options for the message * @return receipt The MessagingReceipt for the message */ function claim( Currency _currency, uint256 _zroAmount, bytes32[] calldata _proof, address _to, bytes calldata _extraOptions // need enough to send 'msg.value' back to this chain via, quoteClaimCallback() ) external payable returns (MessagingReceipt memory receipt) { return _claim(msg.sender, _currency, _zroAmount, _proof, _to, _extraOptions); } function claim( address _user, Currency _currency, uint256 _zroAmount, bytes32[] calldata _proof, address _to, bytes calldata _extraOptions // need enough to send 'msg.value' back to this chain via, quoteClaimCallback() ) external payable onlyDonateAndClaim returns (MessagingReceipt memory receipt) { return _claim(_user, _currency, _zroAmount, _proof, _to, _extraOptions); } function _claim( address _user, Currency _currency, uint256 _zroAmount, bytes32[] calldata _proof, address _to, bytes calldata _extraOptions // need enough to send 'msg.value' back to this chain via, quoteClaimCallback() ) internal returns (MessagingReceipt memory receipt) { if (_to == address(0)) revert InvalidToAddress(); // step 1: assert claimer has donated sufficient amount assertDonation(_currency, _user, _zroAmount); // step 2: validate the proof is correct if (!_verifyProof(_user, _zroAmount, _proof)) revert InvalidProof(); // step 3: rate limiting the transactions _checkAndUpdateRateLimit(remoteEid, 1 /** amount */); // step 4: generate the message and options for the crosschain call bytes memory payload = abi.encode(_user, _zroAmount, _to); bytes memory options = combineOptions(remoteEid, MSG_TYPE_CLAIM, _extraOptions); // step 5: send the message cross chain // solhint-disable-next-line check-send-result receipt = endpoint.send{ value: msg.value }( MessagingParams(remoteEid, _getPeerOrRevert(remoteEid), payload, options, false), payable(_user) ); emit ZRORequested(_user, _zroAmount, _to); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.22; import { MessagingReceipt } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; // solhint-disable-next-line no-unused-import import { IDonate, Currency, Donation } from "../donate/IDonate.sol"; interface IClaim { // Custom Errors error AlreadyClaimed(address user); error InsufficientDonation(Currency currency, uint256 expectedAmount, uint256 actualAmount); error InvalidProof(); error InvalidNativeStargate(); error InvalidNativePrice(); error OnlyDonateAndClaim(); error DonateAndClaimAlreadySet(); error WithdrawFailed(); error MsgValueNotSupported(); error InvalidToAddress(); // Events event MerkleRootSet(bytes32 merkleRoot); event ZRORequested(address requester, uint256 zroAmount, address to); event DonateAndClaimSet(address donateAndClaim); event ZroWithdrawn(address to, uint256 amount); event NativeWithdrawn(address to, uint256 amount); // Functions function claim( Currency currency, uint256 zroAmount, bytes32[] calldata proof, address to, bytes calldata extraBytes ) external payable returns (MessagingReceipt memory receipt); function claim( address user, Currency currency, uint256 zroAmount, bytes32[] calldata proof, address to, bytes calldata extraBytes ) external payable returns (MessagingReceipt memory receipt); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.22; enum Currency { USDC, USDT, Native } struct Donation { uint256 usdc; uint256 usdt; uint256 native; } interface IDonate { // Custom Errors error InsufficientMsgValue(); error InsufficientBalance(); error UnsupportedCurrency(Currency currency); error WithdrawDonationFailed(); error InvalidNativeStargate(); error InvalidDonationReceiver(); error UnexpectedMsgValue(); // Events event Donated(Currency currency, address from, address beneficiary, uint256 amount); event DonationWithdrawn(Currency currency, address to, uint256 amount); // Functions function getDonation(address user) external view returns (Donation memory donation); function withdrawDonation(Currency currency, uint256 minAmount) external payable; function donate(Currency currency, uint256 amount, address beneficiary) external payable; }
{ "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "metadata": { "useLiteralContent": true } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_zroToken","type":"address"},{"internalType":"address","name":"_endpoint","type":"address"},{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"},{"internalType":"address","name":"_donateContract","type":"address"},{"internalType":"address","name":"_stargateUsdc","type":"address"},{"internalType":"address","name":"_stargateUsdt","type":"address"},{"internalType":"address","name":"_stargateNative","type":"address"},{"internalType":"uint256","name":"_nativePrice","type":"uint256"},{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"AlreadyClaimed","type":"error"},{"inputs":[],"name":"DonateAndClaimAlreadySet","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[{"internalType":"enum Currency","name":"currency","type":"uint8"},{"internalType":"uint256","name":"expectedAmount","type":"uint256"},{"internalType":"uint256","name":"actualAmount","type":"uint256"}],"name":"InsufficientDonation","type":"error"},{"inputs":[],"name":"InvalidDelegate","type":"error"},{"inputs":[],"name":"InvalidEndpointCall","type":"error"},{"inputs":[],"name":"InvalidNativePrice","type":"error"},{"inputs":[],"name":"InvalidNativeStargate","type":"error"},{"inputs":[],"name":"InvalidProof","type":"error"},{"inputs":[],"name":"InvalidToAddress","type":"error"},{"inputs":[],"name":"MsgValueNotSupported","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"NoPeer","type":"error"},{"inputs":[],"name":"OnlyDonateAndClaim","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"OnlyEndpoint","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"}],"name":"OnlyPeer","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[{"internalType":"enum Currency","name":"currency","type":"uint8"}],"name":"UnsupportedCurrency","type":"error"},{"inputs":[],"name":"WithdrawFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"claimer","type":"address"},{"indexed":false,"internalType":"uint256","name":"expectedAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"actualAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"claimer","type":"address"},{"indexed":false,"internalType":"uint256","name":"expectedAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"actualAmount","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"dstEid","type":"uint32"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"ClaimRemote","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"donateAndClaim","type":"address"}],"name":"DonateAndClaimSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"name":"MerkleRootSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NativeWithdrawn","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":false,"internalType":"uint32","name":"eid","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"peer","type":"bytes32"}],"name":"PeerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"requester","type":"address"},{"indexed":false,"internalType":"uint256","name":"zroAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"ZRORequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ZroWithdrawn","type":"event"},{"inputs":[],"name":"DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"origin","type":"tuple"}],"name":"allowInitializePath","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum Currency","name":"_currency","type":"uint8"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_zroAmount","type":"uint256"}],"name":"assertDonation","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"enum Currency","name":"_currency","type":"uint8"},{"internalType":"uint256","name":"_zroAmount","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"claim","outputs":[{"components":[{"internalType":"bytes32","name":"guid","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"},{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"fee","type":"tuple"}],"internalType":"struct MessagingReceipt","name":"receipt","type":"tuple"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"enum Currency","name":"_currency","type":"uint8"},{"internalType":"uint256","name":"_zroAmount","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"claim","outputs":[{"components":[{"internalType":"bytes32","name":"guid","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"},{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"fee","type":"tuple"}],"internalType":"struct MessagingReceipt","name":"receipt","type":"tuple"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"donateAndClaim","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"donateContract","outputs":[{"internalType":"contract IDonate","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endpoint","outputs":[{"internalType":"contract ILayerZeroEndpointV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"","type":"tuple"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"address","name":"_sender","type":"address"}],"name":"isComposeMsgSender","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"_origin","type":"tuple"},{"internalType":"bytes32","name":"_guid","type":"bytes32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"address","name":"_executor","type":"address"},{"internalType":"bytes","name":"_extraData","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"nextNonce","outputs":[{"internalType":"uint64","name":"nonce","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numeratorNative","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numeratorUsdc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numeratorUsdt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oAppVersion","outputs":[{"internalType":"uint64","name":"senderVersion","type":"uint64"},{"internalType":"uint64","name":"receiverVersion","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"peers","outputs":[{"internalType":"bytes32","name":"peer","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_dstEid","type":"uint32"},{"internalType":"uint256","name":"_zroAmount","type":"uint256"}],"name":"quoteClaimCallback","outputs":[{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"msgFee","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_zroAmount","type":"uint256"}],"name":"requiredDonation","outputs":[{"components":[{"internalType":"uint256","name":"usdc","type":"uint256"},{"internalType":"uint256","name":"usdt","type":"uint256"},{"internalType":"uint256","name":"native","type":"uint256"}],"internalType":"struct Donation","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_delegate","type":"address"}],"name":"setDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_donateAndClaim","type":"address"}],"name":"setDonateAndClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"bytes32","name":"_peer","type":"bytes32"}],"name":"setPeer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawNative","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawZro","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"zroClaimed","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"zroToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6101406040523480156200001257600080fd5b50604051620027003803806200270083398101604081905262000035916200047e565b878188888888888886806001600160a01b0381166200006e57604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b620000798162000411565b5060018790556001600160a01b038087166080528516156200017d576001856001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000d6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000fc919062000527565b6001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016091906200054c565b6200016c919062000587565b6200017990600a620006a6565b60a0525b6001600160a01b0384161562000275576001846001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001ce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001f4919062000527565b6001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000232573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200025891906200054c565b62000264919062000587565b6200027190600a620006a6565b60c0525b6001600160a01b03831615620003575760006001600160a01b0316836001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002cf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f5919062000527565b6001600160a01b0316146200031d57604051630692f76560e01b815260040160405180910390fd5b816000036200033f576040516347da897160e01b815260040160405180910390fd5b620003538267016345785d8a0000620006b7565b60e0525b5050506001600160a01b0380871661010052851693506200038f9250505057604051632d618d8160e21b815260040160405180910390fd5b6101005160405163ca5eb5e160e01b81526001600160a01b0383811660048301529091169063ca5eb5e190602401600060405180830381600087803b158015620003d857600080fd5b505af1158015620003ed573d6000803e3d6000fd5b5050506001600160a01b03909b166101205250620006da9950505050505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b03811681146200047957600080fd5b919050565b60008060008060008060008060006101208a8c0312156200049e57600080fd5b620004a98a62000461565b9850620004b960208b0162000461565b975060408a01519650620004d060608b0162000461565b9550620004e060808b0162000461565b9450620004f060a08b0162000461565b93506200050060c08b0162000461565b925060e08a01519150620005186101008b0162000461565b90509295985092959850929598565b6000602082840312156200053a57600080fd5b620005458262000461565b9392505050565b6000602082840312156200055f57600080fd5b815160ff811681146200054557600080fd5b634e487b7160e01b600052601160045260246000fd5b60ff8281168282160390811115620005a357620005a362000571565b92915050565b600181815b80851115620005ea578160001904821115620005ce57620005ce62000571565b80851615620005dc57918102915b93841c9390800290620005ae565b509250929050565b6000826200060357506001620005a3565b816200061257506000620005a3565b81600181146200062b5760028114620006365762000656565b6001915050620005a3565b60ff8411156200064a576200064a62000571565b50506001821b620005a3565b5060208310610133831016604e8410600b84101617156200067b575081810a620005a3565b620006878383620005a9565b80600019048211156200069e576200069e62000571565b029392505050565b60006200054560ff841683620005f2565b600082620006d557634e487b7160e01b600052601260045260246000fd5b500490565b60805160a05160c05160e0516101005161012051611f7b62000785600039600081816102e30152818161092101528181610d070152818161101301526112a7015260008181610363015281816107580152610c9a01526000818161021101528181610bf40152610e2b01526000818161061e01528181610b770152610dea01526000818161053b01528181610b010152610da901526000818161032f0152610a740152611f7b6000f3fe6080604052600436106101d15760003560e01c80637d25a05e116100f7578063bb0b6a5311610095578063d776b41811610064578063d776b4181461060c578063f2fde38b14610640578063f942963714610660578063ff7bd03d1461067357600080fd5b8063bb0b6a531461055d578063ca5eb5e11461058a578063cfaf711d146105aa578063d6d754db146105ca57600080fd5b80638da5cb5b116100d15780638da5cb5b146104cf5780638dab3f81146104ed578063918f86741461050d57806399ba4f591461052957600080fd5b80637d25a05e1461043457806382413eac146104705780638b2eddf9146104af57600080fd5b8063452a3a701161016f57806373760a891161013e57806373760a891461039a57806379567417146103c75780637a692982146103e75780637cb647591461041457600080fd5b8063452a3a70146102d1578063569f9b771461031d5780635e280f1114610351578063715018a61461038557600080fd5b806317442b70116101ab57806317442b701461025957806318d79d131461027b5780632eb4a7ab1461029b5780633400288b146102b157600080fd5b806307b18bde146101dd5780630904cc50146101ff57806313137d651461024657600080fd5b366101d857005b600080fd5b3480156101e957600080fd5b506101fd6101f8366004611701565b610693565b005b34801561020b57600080fd5b506102337f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b6101fd61025436600461178e565b610756565b34801561026557600080fd5b506040805160008152600260208201520161023d565b34801561028757600080fd5b506101fd61029636600461182e565b610816565b3480156102a757600080fd5b5061023360015481565b3480156102bd57600080fd5b506101fd6102cc366004611864565b61089d565b3480156102dd57600080fd5b506103057f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161023d565b34801561032957600080fd5b506103057f000000000000000000000000000000000000000000000000000000000000000081565b34801561035d57600080fd5b506103057f000000000000000000000000000000000000000000000000000000000000000081565b34801561039157600080fd5b506101fd6108b3565b3480156103a657600080fd5b506103ba6103b5366004611864565b6108c7565b60405161023d9190611880565b3480156103d357600080fd5b50600254610305906001600160a01b031681565b3480156103f357600080fd5b5061023361040236600461182e565b60046020526000908152604090205481565b34801561042057600080fd5b506101fd61042f366004611897565b6109b9565b34801561044057600080fd5b5061045761044f366004611864565b600092915050565b60405167ffffffffffffffff909116815260200161023d565b34801561047c57600080fd5b5061049f61048b3660046118b0565b6001600160a01b0381163014949350505050565b604051901515815260200161023d565b6104c26104bd36600461196b565b6109f6565b60405161023d9190611a1c565b3480156104db57600080fd5b506000546001600160a01b0316610305565b3480156104f957600080fd5b506101fd610508366004611a5f565b610a44565b34801561051957600080fd5b50610233670de0b6b3a764000081565b34801561053557600080fd5b506102337f000000000000000000000000000000000000000000000000000000000000000081565b34801561056957600080fd5b50610233610578366004611a9e565b60036020526000908152604090205481565b34801561059657600080fd5b506101fd6105a536600461182e565b610c73565b3480156105b657600080fd5b506101fd6105c5366004611701565b610cf2565b3480156105d657600080fd5b506105ea6105e5366004611897565b610d75565b604080518251815260208084015190820152918101519082015260600161023d565b34801561061857600080fd5b506102337f000000000000000000000000000000000000000000000000000000000000000081565b34801561064c57600080fd5b506101fd61065b36600461182e565b610e7d565b6104c261066e366004611ab9565b610ebb565b34801561067f57600080fd5b5061049f61068e366004611b38565b610edd565b61069b610f13565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146106e8576040519150601f19603f3d011682016040523d82523d6000602084013e6106ed565b606091505b505090508061070f57604051631d42c86760e21b815260040160405180910390fd5b604080516001600160a01b0385168152602081018490527fc303ca808382409472acbbf899c316cf439f409f6584aae22df86dfa3c9ed504910160405180910390a1505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633146107a6576040516391ac5e4f60e01b81523360048201526024015b60405180910390fd5b602087018035906107c0906107bb908a611a9e565b610f40565b146107fe576107d26020880188611a9e565b60405163309afaf360e21b815263ffffffff90911660048201526020880135602482015260440161079d565b61080d87878787878787610f7c565b50505050505050565b61081e610f13565b6002546001600160a01b03161561084857604051630abf614160e41b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f40dd9837620e8955c26f089308a386b585e7476d1b96cc080f88022a28406545906020015b60405180910390a150565b6108a5610f13565b6108af8282611140565b5050565b6108bb610f13565b6108c5600061118e565b565b6040805180820182526000808252602080830182905283518281526101008101855263ffffffff871691810191825292938301338152602001858152602001600081526020018381526020018381526020018381525090507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633b6f743b8260006040518363ffffffff1660e01b815260040161096e929190611c1a565b6040805180830381865afa15801561098a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ae9190611cd2565b925050505b92915050565b6109c1610f13565b60018190556040518181527f42cbc405e4dbf1b691e85b9a34b08ecfcf7a9ad9078bf4d645ccfa1fac11c10b90602001610892565b6109fe6116a4565b6002546001600160a01b03163314610a295760405163118e623160e31b815260040160405180910390fd5b610a378989898989896111de565b9998505050505050505050565b6000610a4f82610d75565b6040516320850e9960e11b81526001600160a01b0385811660048301529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063410a1d3290602401606060405180830381865afa158015610abb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610adf9190611cee565b90506000856002811115610af557610af5611d2a565b148015610b22575060007f0000000000000000000000000000000000000000000000000000000000000000115b15610b5757805182511115610b5257815181516040516306cb6f9f60e41b815261079d9288929091600401611d62565b610c6c565b6001856002811115610b6b57610b6b611d2a565b148015610b98575060007f0000000000000000000000000000000000000000000000000000000000000000115b15610bd457806020015182602001511115610b525784826020015182602001516040516306cb6f9f60e41b815260040161079d93929190611d62565b6002856002811115610be857610be8611d2a565b148015610c15575060007f0000000000000000000000000000000000000000000000000000000000000000115b15610c5157806040015182604001511115610b525784826040015182604001516040516306cb6f9f60e41b815260040161079d93929190611d62565b8460405163de0a0bd160e01b815260040161079d9190611d81565b5050505050565b610c7b610f13565b60405163ca5eb5e160e01b81526001600160a01b0382811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063ca5eb5e190602401600060405180830381600087803b158015610cde57600080fd5b505af1158015610c6c573d6000803e3d6000fd5b610cfa610f13565b610d2e6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016838361132a565b604080516001600160a01b0384168152602081018390527f49d9a10b3c2c133f5db344656ec717d4cf37213d7fda8774565a36442a836c4691015b60405180910390a15050565b610d9960405180606001604052806000815260200160008152602001600081525090565b6000670de0b6b3a7640000610dce7f000000000000000000000000000000000000000000000000000000000000000085611da5565b610dd89190611dbc565b90506000670de0b6b3a7640000610e0f7f000000000000000000000000000000000000000000000000000000000000000086611da5565b610e199190611dbc565b90506000670de0b6b3a7640000610e507f000000000000000000000000000000000000000000000000000000000000000087611da5565b610e5a9190611dbc565b604080516060810182529485526020850193909352918301919091525092915050565b610e85610f13565b6001600160a01b038116610eaf57604051631e4fbdf760e01b81526000600482015260240161079d565b610eb88161118e565b50565b610ec36116a4565b610ed13389898989896111de565b98975050505050505050565b6000602082018035906003908390610ef59086611a9e565b63ffffffff1681526020810191909152604001600020541492915050565b6000546001600160a01b031633146108c55760405163118cdaa760e01b815233600482015260240161079d565b63ffffffff8116600090815260036020526040812054806109b35760405163f6ff4fb760e01b815263ffffffff8416600482015260240161079d565b60008080610f8c87890189611dde565b9250925092506000610f9e8484611381565b905080156110bf5760408051600080825260208201909252905060006040518060e001604052808e6000016020810190610fd89190611a9e565b63ffffffff1681526020016001600160a01b0386168152602001848152602001600081526020018381526020018381526020018381525090507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c7c7f5b3478360405180604001604052804781526020016000815250306040518563ffffffff1660e01b815260040161107793929190611e20565b60c06040518083038185885af1158015611095573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906110ba9190611e65565b505050505b7f82e45245d12a20ddee81f5c5b25c8407b35b1f59ee3fce43c791e342b145b4e58484838e60000160208101906110f69190611a9e565b604080516001600160a01b039586168152602081019490945283019190915263ffffffff166060820152908416608082015260a00160405180910390a15050505050505050505050565b63ffffffff8216600081815260036020908152604091829020849055815192835282018390527f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b9101610d69565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6111e66116a4565b6001600160a01b03821661120d57604051638aa3a72f60e01b815260040160405180910390fd5b341561122c5760405163ba52ae7760e01b815260040160405180910390fd5b611237868887610a44565b611243878686866113d8565b611260576040516309bde33960e01b815260040160405180910390fd5b600061126c8887611381565b90508060000361129a57604051632058b6db60e01b81526001600160a01b038916600482015260240161079d565b6112ce6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016848361132a565b604080516001600160a01b038a81168252602082018990528183018490528516606082015290517fb6fe5ce185a3773d47e919f57c7edfd102c91cb7833b2be405c4de89d9980fd79181900360800190a1509695505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261137c908490611491565b505050565b6001600160a01b0382166000908152600460205260408120548083116113ab5760009150506109b3565b6001600160a01b03841660009081526004602052604090208390556113d08184611ede565b949350505050565b60008061144486866040516bffffffffffffffffffffffff19606084901b1660208201526034810182905260009060540160408051601f198184030181528282528051602091820120908301520160405160208183030381529060405280519060200120905092915050565b90506114878484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060015491508490506114f4565b9695505050505050565b60006114a66001600160a01b0384168361150c565b905080516000141580156114cb5750808060200190518101906114c99190611ef1565b155b1561137c57604051635274afe760e01b81526001600160a01b038416600482015260240161079d565b600082611501858461151a565b1490505b9392505050565b60606115058383600061155d565b600081815b84518110156115555761154b8286838151811061153e5761153e611f13565b60200260200101516115f0565b915060010161151f565b509392505050565b6060814710156115825760405163cd78605960e01b815230600482015260240161079d565b600080856001600160a01b0316848660405161159e9190611f29565b60006040518083038185875af1925050503d80600081146115db576040519150601f19603f3d011682016040523d82523d6000602084013e6115e0565b606091505b509150915061148786838361161f565b600081831061160c576000828152602084905260409020611505565b6000838152602083905260409020611505565b6060826116345761162f8261167b565b611505565b815115801561164b57506001600160a01b0384163b155b1561167457604051639996b31560e01b81526001600160a01b038516600482015260240161079d565b5080611505565b80511561168b5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b604051806060016040528060008019168152602001600067ffffffffffffffff1681526020016116e7604051806040016040528060008152602001600081525090565b905290565b6001600160a01b0381168114610eb857600080fd5b6000806040838503121561171457600080fd5b823561171f816116ec565b946020939093013593505050565b60006060828403121561173f57600080fd5b50919050565b60008083601f84011261175757600080fd5b50813567ffffffffffffffff81111561176f57600080fd5b60208301915083602082850101111561178757600080fd5b9250929050565b600080600080600080600060e0888a0312156117a957600080fd5b6117b3898961172d565b965060608801359550608088013567ffffffffffffffff808211156117d757600080fd5b6117e38b838c01611745565b909750955060a08a013591506117f8826116ec565b90935060c0890135908082111561180e57600080fd5b5061181b8a828b01611745565b989b979a50959850939692959293505050565b60006020828403121561184057600080fd5b8135611505816116ec565b803563ffffffff8116811461185f57600080fd5b919050565b6000806040838503121561187757600080fd5b61171f8361184b565b8151815260208083015190820152604081016109b3565b6000602082840312156118a957600080fd5b5035919050565b60008060008060a085870312156118c657600080fd5b6118d0868661172d565b9350606085013567ffffffffffffffff8111156118ec57600080fd5b6118f887828801611745565b909450925050608085013561190c816116ec565b939692955090935050565b80356003811061185f57600080fd5b60008083601f84011261193857600080fd5b50813567ffffffffffffffff81111561195057600080fd5b6020830191508360208260051b850101111561178757600080fd5b60008060008060008060008060c0898b03121561198757600080fd5b8835611992816116ec565b97506119a060208a01611917565b965060408901359550606089013567ffffffffffffffff808211156119c457600080fd5b6119d08c838d01611926565b909750955060808b013591506119e5826116ec565b90935060a08a013590808211156119fb57600080fd5b50611a088b828c01611745565b999c989b5096995094979396929594505050565b60006080820190508251825267ffffffffffffffff60208401511660208301526040830151611a58604084018280518252602090810151910152565b5092915050565b600080600060608486031215611a7457600080fd5b611a7d84611917565b92506020840135611a8d816116ec565b929592945050506040919091013590565b600060208284031215611ab057600080fd5b6115058261184b565b600080600080600080600060a0888a031215611ad457600080fd5b611add88611917565b965060208801359550604088013567ffffffffffffffff80821115611b0157600080fd5b611b0d8b838c01611926565b909750955060608a01359150611b22826116ec565b9093506080890135908082111561180e57600080fd5b600060608284031215611b4a57600080fd5b611505838361172d565b60005b83811015611b6f578181015183820152602001611b57565b50506000910152565b60008151808452611b90816020860160208601611b54565b601f01601f19169290920160200192915050565b63ffffffff81511682526020810151602083015260408101516040830152606081015160608301526000608082015160e06080850152611be760e0850182611b78565b905060a083015184820360a0860152611c008282611b78565b91505060c083015184820360c08601526109ae8282611b78565b604081526000611c2d6040830185611ba4565b905082151560208301529392505050565b6040516060810167ffffffffffffffff81118282101715611c6f57634e487b7160e01b600052604160045260246000fd5b60405290565b600060408284031215611c8757600080fd5b6040516040810181811067ffffffffffffffff82111715611cb857634e487b7160e01b600052604160045260246000fd5b604052825181526020928301519281019290925250919050565b600060408284031215611ce457600080fd5b6115058383611c75565b600060608284031215611d0057600080fd5b611d08611c3e565b8251815260208301516020820152604083015160408201528091505092915050565b634e487b7160e01b600052602160045260246000fd5b60038110611d5e57634e487b7160e01b600052602160045260246000fd5b9052565b60608101611d708286611d40565b602082019390935260400152919050565b602081016109b38284611d40565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176109b3576109b3611d8f565b600082611dd957634e487b7160e01b600052601260045260246000fd5b500490565b600080600060608486031215611df357600080fd5b8335611dfe816116ec565b9250602084013591506040840135611e15816116ec565b809150509250925092565b608081526000611e336080830186611ba4565b9050611e4c602083018580518252602090810151910152565b6001600160a01b03929092166060919091015292915050565b60008082840360c0811215611e7957600080fd5b6080811215611e8757600080fd5b50611e90611c3e565b83518152602084015167ffffffffffffffff81168114611eaf57600080fd5b6020820152611ec18560408601611c75565b60408201529150611ed58460808501611c75565b90509250929050565b818103818111156109b3576109b3611d8f565b600060208284031215611f0357600080fd5b8151801515811461150557600080fd5b634e487b7160e01b600052603260045260246000fd5b60008251611f3b818460208701611b54565b919091019291505056fea2646970667358221220111a8bc2b94295c52e53d09674f2a5839b285015ab2fec14debbaa47832d4d3a64736f6c634300081600330000000000000000000000006985884c4392d348587b19cb9eaaf157f13271cd0000000000000000000000001a44076050125825900e736c501f859c50fe728c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a86da1141eb193ea9da56c70c286b64def66b245000000000000000000000000e8cdf27acd73a434d661c84887215f7598e7d0d3000000000000000000000000ce8cca271ebc0533920c83d39f417ed6a0abb7d0000000000000000000000000a45b5130f36cdca45667738e2a258ab09f4a5f7f0000000000000000000000000000000000000000000000000000000000000e100000000000000000000000001e6e44b259912b6021e84086a47d1843494c146c
Deployed Bytecode
0x6080604052600436106101d15760003560e01c80637d25a05e116100f7578063bb0b6a5311610095578063d776b41811610064578063d776b4181461060c578063f2fde38b14610640578063f942963714610660578063ff7bd03d1461067357600080fd5b8063bb0b6a531461055d578063ca5eb5e11461058a578063cfaf711d146105aa578063d6d754db146105ca57600080fd5b80638da5cb5b116100d15780638da5cb5b146104cf5780638dab3f81146104ed578063918f86741461050d57806399ba4f591461052957600080fd5b80637d25a05e1461043457806382413eac146104705780638b2eddf9146104af57600080fd5b8063452a3a701161016f57806373760a891161013e57806373760a891461039a57806379567417146103c75780637a692982146103e75780637cb647591461041457600080fd5b8063452a3a70146102d1578063569f9b771461031d5780635e280f1114610351578063715018a61461038557600080fd5b806317442b70116101ab57806317442b701461025957806318d79d131461027b5780632eb4a7ab1461029b5780633400288b146102b157600080fd5b806307b18bde146101dd5780630904cc50146101ff57806313137d651461024657600080fd5b366101d857005b600080fd5b3480156101e957600080fd5b506101fd6101f8366004611701565b610693565b005b34801561020b57600080fd5b506102337f000000000000000000000000000000000000000000000000000019438493bc7181565b6040519081526020015b60405180910390f35b6101fd61025436600461178e565b610756565b34801561026557600080fd5b506040805160008152600260208201520161023d565b34801561028757600080fd5b506101fd61029636600461182e565b610816565b3480156102a757600080fd5b5061023360015481565b3480156102bd57600080fd5b506101fd6102cc366004611864565b61089d565b3480156102dd57600080fd5b506103057f0000000000000000000000006985884c4392d348587b19cb9eaaf157f13271cd81565b6040516001600160a01b03909116815260200161023d565b34801561032957600080fd5b506103057f000000000000000000000000a86da1141eb193ea9da56c70c286b64def66b24581565b34801561035d57600080fd5b506103057f0000000000000000000000001a44076050125825900e736c501f859c50fe728c81565b34801561039157600080fd5b506101fd6108b3565b3480156103a657600080fd5b506103ba6103b5366004611864565b6108c7565b60405161023d9190611880565b3480156103d357600080fd5b50600254610305906001600160a01b031681565b3480156103f357600080fd5b5061023361040236600461182e565b60046020526000908152604090205481565b34801561042057600080fd5b506101fd61042f366004611897565b6109b9565b34801561044057600080fd5b5061045761044f366004611864565b600092915050565b60405167ffffffffffffffff909116815260200161023d565b34801561047c57600080fd5b5061049f61048b3660046118b0565b6001600160a01b0381163014949350505050565b604051901515815260200161023d565b6104c26104bd36600461196b565b6109f6565b60405161023d9190611a1c565b3480156104db57600080fd5b506000546001600160a01b0316610305565b3480156104f957600080fd5b506101fd610508366004611a5f565b610a44565b34801561051957600080fd5b50610233670de0b6b3a764000081565b34801561053557600080fd5b506102337f00000000000000000000000000000000000000000000000000000000000186a081565b34801561056957600080fd5b50610233610578366004611a9e565b60036020526000908152604090205481565b34801561059657600080fd5b506101fd6105a536600461182e565b610c73565b3480156105b657600080fd5b506101fd6105c5366004611701565b610cf2565b3480156105d657600080fd5b506105ea6105e5366004611897565b610d75565b604080518251815260208084015190820152918101519082015260600161023d565b34801561061857600080fd5b506102337f00000000000000000000000000000000000000000000000000000000000186a081565b34801561064c57600080fd5b506101fd61065b36600461182e565b610e7d565b6104c261066e366004611ab9565b610ebb565b34801561067f57600080fd5b5061049f61068e366004611b38565b610edd565b61069b610f13565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146106e8576040519150601f19603f3d011682016040523d82523d6000602084013e6106ed565b606091505b505090508061070f57604051631d42c86760e21b815260040160405180910390fd5b604080516001600160a01b0385168152602081018490527fc303ca808382409472acbbf899c316cf439f409f6584aae22df86dfa3c9ed504910160405180910390a1505050565b7f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b031633146107a6576040516391ac5e4f60e01b81523360048201526024015b60405180910390fd5b602087018035906107c0906107bb908a611a9e565b610f40565b146107fe576107d26020880188611a9e565b60405163309afaf360e21b815263ffffffff90911660048201526020880135602482015260440161079d565b61080d87878787878787610f7c565b50505050505050565b61081e610f13565b6002546001600160a01b03161561084857604051630abf614160e41b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f40dd9837620e8955c26f089308a386b585e7476d1b96cc080f88022a28406545906020015b60405180910390a150565b6108a5610f13565b6108af8282611140565b5050565b6108bb610f13565b6108c5600061118e565b565b6040805180820182526000808252602080830182905283518281526101008101855263ffffffff871691810191825292938301338152602001858152602001600081526020018381526020018381526020018381525090507f0000000000000000000000006985884c4392d348587b19cb9eaaf157f13271cd6001600160a01b0316633b6f743b8260006040518363ffffffff1660e01b815260040161096e929190611c1a565b6040805180830381865afa15801561098a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ae9190611cd2565b925050505b92915050565b6109c1610f13565b60018190556040518181527f42cbc405e4dbf1b691e85b9a34b08ecfcf7a9ad9078bf4d645ccfa1fac11c10b90602001610892565b6109fe6116a4565b6002546001600160a01b03163314610a295760405163118e623160e31b815260040160405180910390fd5b610a378989898989896111de565b9998505050505050505050565b6000610a4f82610d75565b6040516320850e9960e11b81526001600160a01b0385811660048301529192506000917f000000000000000000000000a86da1141eb193ea9da56c70c286b64def66b245169063410a1d3290602401606060405180830381865afa158015610abb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610adf9190611cee565b90506000856002811115610af557610af5611d2a565b148015610b22575060007f00000000000000000000000000000000000000000000000000000000000186a0115b15610b5757805182511115610b5257815181516040516306cb6f9f60e41b815261079d9288929091600401611d62565b610c6c565b6001856002811115610b6b57610b6b611d2a565b148015610b98575060007f00000000000000000000000000000000000000000000000000000000000186a0115b15610bd457806020015182602001511115610b525784826020015182602001516040516306cb6f9f60e41b815260040161079d93929190611d62565b6002856002811115610be857610be8611d2a565b148015610c15575060007f000000000000000000000000000000000000000000000000000019438493bc71115b15610c5157806040015182604001511115610b525784826040015182604001516040516306cb6f9f60e41b815260040161079d93929190611d62565b8460405163de0a0bd160e01b815260040161079d9190611d81565b5050505050565b610c7b610f13565b60405163ca5eb5e160e01b81526001600160a01b0382811660048301527f0000000000000000000000001a44076050125825900e736c501f859c50fe728c169063ca5eb5e190602401600060405180830381600087803b158015610cde57600080fd5b505af1158015610c6c573d6000803e3d6000fd5b610cfa610f13565b610d2e6001600160a01b037f0000000000000000000000006985884c4392d348587b19cb9eaaf157f13271cd16838361132a565b604080516001600160a01b0384168152602081018390527f49d9a10b3c2c133f5db344656ec717d4cf37213d7fda8774565a36442a836c4691015b60405180910390a15050565b610d9960405180606001604052806000815260200160008152602001600081525090565b6000670de0b6b3a7640000610dce7f00000000000000000000000000000000000000000000000000000000000186a085611da5565b610dd89190611dbc565b90506000670de0b6b3a7640000610e0f7f00000000000000000000000000000000000000000000000000000000000186a086611da5565b610e199190611dbc565b90506000670de0b6b3a7640000610e507f000000000000000000000000000000000000000000000000000019438493bc7187611da5565b610e5a9190611dbc565b604080516060810182529485526020850193909352918301919091525092915050565b610e85610f13565b6001600160a01b038116610eaf57604051631e4fbdf760e01b81526000600482015260240161079d565b610eb88161118e565b50565b610ec36116a4565b610ed13389898989896111de565b98975050505050505050565b6000602082018035906003908390610ef59086611a9e565b63ffffffff1681526020810191909152604001600020541492915050565b6000546001600160a01b031633146108c55760405163118cdaa760e01b815233600482015260240161079d565b63ffffffff8116600090815260036020526040812054806109b35760405163f6ff4fb760e01b815263ffffffff8416600482015260240161079d565b60008080610f8c87890189611dde565b9250925092506000610f9e8484611381565b905080156110bf5760408051600080825260208201909252905060006040518060e001604052808e6000016020810190610fd89190611a9e565b63ffffffff1681526020016001600160a01b0386168152602001848152602001600081526020018381526020018381526020018381525090507f0000000000000000000000006985884c4392d348587b19cb9eaaf157f13271cd6001600160a01b031663c7c7f5b3478360405180604001604052804781526020016000815250306040518563ffffffff1660e01b815260040161107793929190611e20565b60c06040518083038185885af1158015611095573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906110ba9190611e65565b505050505b7f82e45245d12a20ddee81f5c5b25c8407b35b1f59ee3fce43c791e342b145b4e58484838e60000160208101906110f69190611a9e565b604080516001600160a01b039586168152602081019490945283019190915263ffffffff166060820152908416608082015260a00160405180910390a15050505050505050505050565b63ffffffff8216600081815260036020908152604091829020849055815192835282018390527f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b9101610d69565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6111e66116a4565b6001600160a01b03821661120d57604051638aa3a72f60e01b815260040160405180910390fd5b341561122c5760405163ba52ae7760e01b815260040160405180910390fd5b611237868887610a44565b611243878686866113d8565b611260576040516309bde33960e01b815260040160405180910390fd5b600061126c8887611381565b90508060000361129a57604051632058b6db60e01b81526001600160a01b038916600482015260240161079d565b6112ce6001600160a01b037f0000000000000000000000006985884c4392d348587b19cb9eaaf157f13271cd16848361132a565b604080516001600160a01b038a81168252602082018990528183018490528516606082015290517fb6fe5ce185a3773d47e919f57c7edfd102c91cb7833b2be405c4de89d9980fd79181900360800190a1509695505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261137c908490611491565b505050565b6001600160a01b0382166000908152600460205260408120548083116113ab5760009150506109b3565b6001600160a01b03841660009081526004602052604090208390556113d08184611ede565b949350505050565b60008061144486866040516bffffffffffffffffffffffff19606084901b1660208201526034810182905260009060540160408051601f198184030181528282528051602091820120908301520160405160208183030381529060405280519060200120905092915050565b90506114878484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060015491508490506114f4565b9695505050505050565b60006114a66001600160a01b0384168361150c565b905080516000141580156114cb5750808060200190518101906114c99190611ef1565b155b1561137c57604051635274afe760e01b81526001600160a01b038416600482015260240161079d565b600082611501858461151a565b1490505b9392505050565b60606115058383600061155d565b600081815b84518110156115555761154b8286838151811061153e5761153e611f13565b60200260200101516115f0565b915060010161151f565b509392505050565b6060814710156115825760405163cd78605960e01b815230600482015260240161079d565b600080856001600160a01b0316848660405161159e9190611f29565b60006040518083038185875af1925050503d80600081146115db576040519150601f19603f3d011682016040523d82523d6000602084013e6115e0565b606091505b509150915061148786838361161f565b600081831061160c576000828152602084905260409020611505565b6000838152602083905260409020611505565b6060826116345761162f8261167b565b611505565b815115801561164b57506001600160a01b0384163b155b1561167457604051639996b31560e01b81526001600160a01b038516600482015260240161079d565b5080611505565b80511561168b5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b604051806060016040528060008019168152602001600067ffffffffffffffff1681526020016116e7604051806040016040528060008152602001600081525090565b905290565b6001600160a01b0381168114610eb857600080fd5b6000806040838503121561171457600080fd5b823561171f816116ec565b946020939093013593505050565b60006060828403121561173f57600080fd5b50919050565b60008083601f84011261175757600080fd5b50813567ffffffffffffffff81111561176f57600080fd5b60208301915083602082850101111561178757600080fd5b9250929050565b600080600080600080600060e0888a0312156117a957600080fd5b6117b3898961172d565b965060608801359550608088013567ffffffffffffffff808211156117d757600080fd5b6117e38b838c01611745565b909750955060a08a013591506117f8826116ec565b90935060c0890135908082111561180e57600080fd5b5061181b8a828b01611745565b989b979a50959850939692959293505050565b60006020828403121561184057600080fd5b8135611505816116ec565b803563ffffffff8116811461185f57600080fd5b919050565b6000806040838503121561187757600080fd5b61171f8361184b565b8151815260208083015190820152604081016109b3565b6000602082840312156118a957600080fd5b5035919050565b60008060008060a085870312156118c657600080fd5b6118d0868661172d565b9350606085013567ffffffffffffffff8111156118ec57600080fd5b6118f887828801611745565b909450925050608085013561190c816116ec565b939692955090935050565b80356003811061185f57600080fd5b60008083601f84011261193857600080fd5b50813567ffffffffffffffff81111561195057600080fd5b6020830191508360208260051b850101111561178757600080fd5b60008060008060008060008060c0898b03121561198757600080fd5b8835611992816116ec565b97506119a060208a01611917565b965060408901359550606089013567ffffffffffffffff808211156119c457600080fd5b6119d08c838d01611926565b909750955060808b013591506119e5826116ec565b90935060a08a013590808211156119fb57600080fd5b50611a088b828c01611745565b999c989b5096995094979396929594505050565b60006080820190508251825267ffffffffffffffff60208401511660208301526040830151611a58604084018280518252602090810151910152565b5092915050565b600080600060608486031215611a7457600080fd5b611a7d84611917565b92506020840135611a8d816116ec565b929592945050506040919091013590565b600060208284031215611ab057600080fd5b6115058261184b565b600080600080600080600060a0888a031215611ad457600080fd5b611add88611917565b965060208801359550604088013567ffffffffffffffff80821115611b0157600080fd5b611b0d8b838c01611926565b909750955060608a01359150611b22826116ec565b9093506080890135908082111561180e57600080fd5b600060608284031215611b4a57600080fd5b611505838361172d565b60005b83811015611b6f578181015183820152602001611b57565b50506000910152565b60008151808452611b90816020860160208601611b54565b601f01601f19169290920160200192915050565b63ffffffff81511682526020810151602083015260408101516040830152606081015160608301526000608082015160e06080850152611be760e0850182611b78565b905060a083015184820360a0860152611c008282611b78565b91505060c083015184820360c08601526109ae8282611b78565b604081526000611c2d6040830185611ba4565b905082151560208301529392505050565b6040516060810167ffffffffffffffff81118282101715611c6f57634e487b7160e01b600052604160045260246000fd5b60405290565b600060408284031215611c8757600080fd5b6040516040810181811067ffffffffffffffff82111715611cb857634e487b7160e01b600052604160045260246000fd5b604052825181526020928301519281019290925250919050565b600060408284031215611ce457600080fd5b6115058383611c75565b600060608284031215611d0057600080fd5b611d08611c3e565b8251815260208301516020820152604083015160408201528091505092915050565b634e487b7160e01b600052602160045260246000fd5b60038110611d5e57634e487b7160e01b600052602160045260246000fd5b9052565b60608101611d708286611d40565b602082019390935260400152919050565b602081016109b38284611d40565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176109b3576109b3611d8f565b600082611dd957634e487b7160e01b600052601260045260246000fd5b500490565b600080600060608486031215611df357600080fd5b8335611dfe816116ec565b9250602084013591506040840135611e15816116ec565b809150509250925092565b608081526000611e336080830186611ba4565b9050611e4c602083018580518252602090810151910152565b6001600160a01b03929092166060919091015292915050565b60008082840360c0811215611e7957600080fd5b6080811215611e8757600080fd5b50611e90611c3e565b83518152602084015167ffffffffffffffff81168114611eaf57600080fd5b6020820152611ec18560408601611c75565b60408201529150611ed58460808501611c75565b90509250929050565b818103818111156109b3576109b3611d8f565b600060208284031215611f0357600080fd5b8151801515811461150557600080fd5b634e487b7160e01b600052603260045260246000fd5b60008251611f3b818460208701611b54565b919091019291505056fea2646970667358221220111a8bc2b94295c52e53d09674f2a5839b285015ab2fec14debbaa47832d4d3a64736f6c63430008160033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006985884c4392d348587b19cb9eaaf157f13271cd0000000000000000000000001a44076050125825900e736c501f859c50fe728c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a86da1141eb193ea9da56c70c286b64def66b245000000000000000000000000e8cdf27acd73a434d661c84887215f7598e7d0d3000000000000000000000000ce8cca271ebc0533920c83d39f417ed6a0abb7d0000000000000000000000000a45b5130f36cdca45667738e2a258ab09f4a5f7f0000000000000000000000000000000000000000000000000000000000000e100000000000000000000000001e6e44b259912b6021e84086a47d1843494c146c
-----Decoded View---------------
Arg [0] : _zroToken (address): 0x6985884C4392D348587B19cb9eAAf157F13271cd
Arg [1] : _endpoint (address): 0x1a44076050125825900e736c501f859c50fE728c
Arg [2] : _merkleRoot (bytes32): 0x0000000000000000000000000000000000000000000000000000000000000000
Arg [3] : _donateContract (address): 0xa86Da1141eB193Ea9DA56c70c286b64dEf66b245
Arg [4] : _stargateUsdc (address): 0xe8CDF27AcD73a434D661C84887215F7598e7d0d3
Arg [5] : _stargateUsdt (address): 0xcE8CcA271Ebc0533920C83d39F417ED6A0abB7D0
Arg [6] : _stargateNative (address): 0xA45B5130f36CDcA45667738e2a258AB09f4A5f7F
Arg [7] : _nativePrice (uint256): 3600
Arg [8] : _owner (address): 0x1e6e44B259912B6021E84086A47D1843494c146c
-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 0000000000000000000000006985884c4392d348587b19cb9eaaf157f13271cd
Arg [1] : 0000000000000000000000001a44076050125825900e736c501f859c50fe728c
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [3] : 000000000000000000000000a86da1141eb193ea9da56c70c286b64def66b245
Arg [4] : 000000000000000000000000e8cdf27acd73a434d661c84887215f7598e7d0d3
Arg [5] : 000000000000000000000000ce8cca271ebc0533920c83d39f417ed6a0abb7d0
Arg [6] : 000000000000000000000000a45b5130f36cdca45667738e2a258ab09f4a5f7f
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000e10
Arg [8] : 0000000000000000000000001e6e44b259912b6021e84086a47d1843494c146c
Deployed Bytecode Sourcemap
704:7161:24:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2008:233;;;;;;;;;;-1:-1:-1;2008:233:24;;;;;:::i;:::-;;:::i;:::-;;725:40:23;;;;;;;;;;;;;;;;;;616:25:28;;;604:2;589:18;725:40:23;;;;;;;;4368:708:1;;;;;;:::i;:::-;;:::i;1193:143::-;;;;;;;;;;-1:-1:-1;1193:143:1;;;1245:20;2423:34:28;;678:1:1;2488:2:28;2473:18;;2466:43;2359:18;1193:143:1;2216:299:28;2103:246:23;;;;;;;;;;-1:-1:-1;2103:246:23;;;;;:::i;:::-;;:::i;559:25::-;;;;;;;;;;;;;;;;1724:108:0;;;;;;;;;;-1:-1:-1;1724:108:0;;;;;:::i;:::-;;:::i;790:33:24:-;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3543:32:28;;;3525:51;;3513:2;3498:18;790:33:24;3379:203:28;591:39:23;;;;;;;;;;;;;;;446:46:0;;;;;;;;;;;;;;;2293:101:15;;;;;;;;;;;;;:::i;6988:705:24:-;;;;;;;;;;-1:-1:-1;6988:705:24;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;825:29:23:-;;;;;;;;;;-1:-1:-1;825:29:23;;;;-1:-1:-1;;;;;825:29:23;;;830:57:24;;;;;;;;;;-1:-1:-1;830:57:24;;;;;:::i;:::-;;;;;;;;;;;;;;4325:204:23;;;;;;;;;;-1:-1:-1;4325:204:23;;;;;:::i;:::-;;:::i;3507:128:1:-;;;;;;;;;;-1:-1:-1;3507:128:1;;;;;:::i;:::-;3596:12;3507:128;;;;;;;;5088:18:28;5076:31;;;5058:50;;5046:2;5031:18;3507:128:1;4914:200:28;2013:216:1;;;;;;;;;;-1:-1:-1;2013:216:1;;;;;:::i;:::-;-1:-1:-1;;;;;2198:24:1;;2217:4;2198:24;2013:216;;;;;;;;;;5959:14:28;;5952:22;5934:41;;5922:2;5907:18;2013:216:1;5794:187:28;3075:411:24;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1638:85:15:-;;;;;;;;;;-1:-1:-1;1684:7:15;1710:6;-1:-1:-1;;;;;1710:6:15;1638:85;;2895:1317:23;;;;;;;;;;-1:-1:-1;2895:1317:23;;;;;:::i;:::-;;:::i;772:46::-;;;;;;;;;;;;810:8;772:46;;637:38;;;;;;;;;;;;;;;569:48:0;;;;;;;;;;-1:-1:-1;569:48:0;;;;;:::i;:::-;;;;;;;;;;;;;;3252:105;;;;;;;;;;-1:-1:-1;3252:105:0;;;;;:::i;:::-;;:::i;1759:171:24:-;;;;;;;;;;-1:-1:-1;1759:171:24;;;;;:::i;:::-;;:::i;2548:341:23:-;;;;;;;;;;-1:-1:-1;2548:341:23;;;;;:::i;:::-;;:::i;:::-;;;;9179:13:28;;9161:32;;9249:4;9237:17;;;9231:24;9209:20;;;9202:54;9300:17;;;9294:24;9272:20;;;9265:54;9149:2;9134:18;2548:341:23;8963:362:28;681:38:23;;;;;;;;;;;;;;;2543:215:15;;;;;;;;;;-1:-1:-1;2543:215:15;;;;;:::i;:::-;;:::i;2618:374:24:-;;;;;;:::i;:::-;;:::i;2771:149:1:-;;;;;;;;;;-1:-1:-1;2771:149:1;;;;;:::i;:::-;;:::i;2008:233:24:-;1531:13:15;:11;:13::i;:::-;2092:9:24::1;2115:3;-1:-1:-1::0;;;;;2107:17:24::1;2133:7;2107:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2091:55;;;2161:4;2156:34;;2174:16;;-1:-1:-1::0;;;2174:16:24::1;;;;;;;;;;;2156:34;2205:29;::::0;;-1:-1:-1;;;;;11021:32:28;;11003:51;;11085:2;11070:18;;11063:34;;;2205:29:24::1;::::0;10976:18:28;2205:29:24::1;;;;;;;2081:160;2008:233:::0;;:::o;4368:708:1:-;4681:8;-1:-1:-1;;;;;4673:31:1;4694:10;4673:31;4669:68;;4713:24;;-1:-1:-1;;;4713:24:1;;4726:10;4713:24;;;3525:51:28;3498:18;;4713:24:1;;;;;;;;4669:68;4873:14;;;;;;4837:32;;4854:14;;4873:7;4854:14;:::i;:::-;4837:16;:32::i;:::-;:50;4833:103;;4905:14;;;;:7;:14;:::i;:::-;4896:40;;-1:-1:-1;;;4896:40:1;;11310:10:28;11298:23;;;4896:40:1;;;11280:42:28;4921:14:1;;;;11338:18:28;;;11331:34;11253:18;;4896:40:1;11108:263:28;4833:103:1;5010:59;5021:7;5030:5;5037:8;;5047:9;5058:10;;5010;:59::i;:::-;4368:708;;;;;;;:::o;2103:246:23:-;1531:13:15;:11;:13::i;:::-;2188:14:23::1;::::0;-1:-1:-1;;;;;2188:14:23::1;:28:::0;2184:67:::1;;2225:26;;-1:-1:-1::0;;;2225:26:23::1;;;;;;;;;;;2184:67;2261:14;:32:::0;;-1:-1:-1;;;;;;2261:32:23::1;-1:-1:-1::0;;;;;2261:32:23;::::1;::::0;;::::1;::::0;;;2308:34:::1;::::0;3525:51:28;;;2308:34:23::1;::::0;3513:2:28;3498:18;2308:34:23::1;;;;;;;;2103:246:::0;:::o;1724:108:0:-;1531:13:15;:11;:13::i;:::-;1804:21:0::1;1813:4;1819:5;1804:8;:21::i;:::-;1724:108:::0;;:::o;2293:101:15:-;1531:13;:11;:13::i;:::-;2357:30:::1;2384:1;2357:18;:30::i;:::-;2293:101::o:0;6988:705:24:-;-1:-1:-1;;;;;;;;;;;;;;;;;;;7255:12:24;;;;;7307:319;;;;;;;;7255:12;;;7307:319;;;-1:-1:-1;;7307:319:24;;7381:10;7307:319;;;;7416:10;7307:319;;;;7453:1;7307:319;;;;7537:10;7307:319;;;;7573:10;7307:319;;;;7605:10;7307:319;;;7277:349;;7648:8;-1:-1:-1;;;;;7643:24:24;;7668:10;7680:5;7643:43;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7636:50;;;;6988:705;;;;;:::o;4325:204:23:-;1531:13:15;:11;:13::i;:::-;4457:10:23::1;:24:::0;;;4496:26:::1;::::0;616:25:28;;;4496:26:23::1;::::0;604:2:28;589:18;4496:26:23::1;470:177:28::0;3075:411:24;3380:31;;:::i;:::-;919:14:23;;-1:-1:-1;;;;;919:14:23;905:10;:28;901:61;;942:20;;-1:-1:-1;;;942:20:23;;;;;;;;;;;901:61;3430:49:24::1;3437:5;3444:9;3455:10;3467:6;;3475:3;3430:6;:49::i;:::-;3423:56:::0;3075:411;-1:-1:-1;;;;;;;;;3075:411:24:o;2895:1317:23:-;3057:32;3092:28;3109:10;3092:16;:28::i;:::-;3163:33;;-1:-1:-1;;;3163:33:23;;-1:-1:-1;;;;;3543:32:28;;;3163:33:23;;;3525:51:28;3057:63:23;;-1:-1:-1;3130:30:23;;3163:14;:26;;;;3498:18:28;;3163:33:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3130:66;-1:-1:-1;3400:13:23;3387:9;:26;;;;;;;;:::i;:::-;;:47;;;;;3433:1;3417:13;:17;3387:47;3383:823;;;3478:19;;3454:21;;:43;3450:164;;;3556:21;;3579:19;;3524:75;;-1:-1:-1;;;3524:75:23;;;;3545:9;;3556:21;;3524:75;;;:::i;3450:164::-;3383:823;;;3647:13;3634:9;:26;;;;;;;;:::i;:::-;;:47;;;;;3680:1;3664:13;:17;3634:47;3630:576;;;3725:14;:19;;;3701:16;:21;;;:43;3697:164;;;3792:9;3803:16;:21;;;3826:14;:19;;;3771:75;;-1:-1:-1;;;3771:75:23;;;;;;;;;;:::i;3630:576::-;3894:15;3881:9;:28;;;;;;;;:::i;:::-;;:51;;;;;3931:1;3913:15;:19;3881:51;3877:329;;;3978:14;:21;;;3952:16;:23;;;:47;3948:172;;;4047:9;4058:16;:23;;;4083:14;:21;;;4026:79;;-1:-1:-1;;;4026:79:23;;;;;;;;;;:::i;3877:329::-;4185:9;4157:38;;-1:-1:-1;;;4157:38:23;;;;;;;;:::i;3877:329::-;2986:1226;;2895:1317;;;:::o;3252:105:0:-;1531:13:15;:11;:13::i;:::-;3319:31:0::1;::::0;-1:-1:-1;;;3319:31:0;;-1:-1:-1;;;;;3543:32:28;;;3319:31:0::1;::::0;::::1;3525:51:28::0;3319:8:0::1;:20;::::0;::::1;::::0;3498:18:28;;3319:31:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;1759:171:24::0;1531:13:15;:11;:13::i;:::-;1839:43:24::1;-1:-1:-1::0;;;;;1846:8:24::1;1839:29;1869:3:::0;1874:7;1839:29:::1;:43::i;:::-;1897:26;::::0;;-1:-1:-1;;;;;11021:32:28;;11003:51;;11085:2;11070:18;;11063:34;;;1897:26:24::1;::::0;10976:18:28;1897:26:24::1;;;;;;;;1759:171:::0;;:::o;2548:341:23:-;2615:15;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;2615:15:23;2642:12;810:8;2658:26;2671:13;2658:10;:26;:::i;:::-;2657:42;;;;:::i;:::-;2642:57;-1:-1:-1;2709:12:23;810:8;2725:26;2738:13;2725:10;:26;:::i;:::-;2724:42;;;;:::i;:::-;2709:57;-1:-1:-1;2776:14:23;810:8;2794:28;2807:15;2794:10;:28;:::i;:::-;2793:44;;;;:::i;:::-;2854:28;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2854:28:23;2548:341;-1:-1:-1;;2548:341:23:o;2543:215:15:-;1531:13;:11;:13::i;:::-;-1:-1:-1;;;;;2627:22:15;::::1;2623:91;;2672:31;::::0;-1:-1:-1;;;2672:31:15;;2700:1:::1;2672:31;::::0;::::1;3525:51:28::0;3498:18;;2672:31:15::1;3379:203:28::0;2623:91:15::1;2723:28;2742:8;2723:18;:28::i;:::-;2543:215:::0;:::o;2618:374:24:-;2881:31;;:::i;:::-;2931:54;2938:10;2950:9;2961:10;2973:6;;2981:3;2931:6;:54::i;:::-;2924:61;2618:374;-1:-1:-1;;;;;;;;2618:374:24:o;2771:149:1:-;2853:4;2900:13;;;;;;2876:5;;2853:4;;2882:13;;2900:6;2882:13;:::i;:::-;2876:20;;;;;;;;;;;;;-1:-1:-1;2876:20:1;;:37;;2771:149;-1:-1:-1;;2771:149:1:o;1796:162:15:-;1684:7;1710:6;-1:-1:-1;;;;;1710:6:15;735:10:21;1855:23:15;1851:101;;1901:40;;-1:-1:-1;;;1901:40:15;;735:10:21;1901:40:15;;;3525:51:28;3498:18;;1901:40:15;3379:203:28;2718:196:0;2822:11;;;2788:7;2822:11;;;:5;:11;;;;;;;2843:43;;2874:12;;-1:-1:-1;;;2874:12:0;;16385:10:28;16373:23;;2874:12:0;;;16355:42:28;16328:18;;2874:12:0;16211:192:28;4462:1788:24;4680:12;;;4727:49;;;;4738:8;4727:49;:::i;:::-;4679:97;;;;;;4838:24;4865:34;4883:4;4889:9;4865:17;:34::i;:::-;4838:61;-1:-1:-1;5007:21:24;;5003:1036;;5070:12;;;5044:23;5070:12;;;;;;;;;5044:38;;5096:27;5126:356;;;;;;;;5162:7;:14;;;;;;;;;;:::i;:::-;5126:356;;;;;;-1:-1:-1;;;;;7797:23:24;;5126:356;;;;5246:16;5126:356;;;;5293:1;5126:356;;;;5381:10;5126:356;;;;5421:10;5126:356;;;;5457:10;5126:356;;;5096:386;;5853:8;-1:-1:-1;;;;;5848:19:24;;5876:21;5917:10;5945:38;;;;;;;;5958:21;5945:38;;;;5981:1;5945:38;;;6009:4;5848:180;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;5030:1009;;5003:1036;6177:66;6189:4;6195:9;6206:16;6224:7;:14;;;;;;;;;;:::i;:::-;6177:66;;;-1:-1:-1;;;;;18486:15:28;;;18468:34;;18533:2;18518:18;;18511:34;;;;18561:18;;18554:34;;;;18636:10;18624:23;18619:2;18604:18;;18597:51;18685:15;;;18679:3;18664:19;;18657:44;18417:3;18402:19;6177:66:24;;;;;;;4669:1581;;;;4462:1788;;;;;;;:::o;2286:134:0:-;2359:11;;;;;;;:5;:11;;;;;;;;;:19;;;2393:20;;11280:42:28;;;11338:18;;11331:34;;;2393:20:0;;11253:18:28;2393:20:0;11108:263:28;2912:187:15;2985:16;3004:6;;-1:-1:-1;;;;;3020:17:15;;;-1:-1:-1;;;;;;3020:17:15;;;;;;3052:40;;3004:6;;;;;;;3052:40;;2985:16;3052:40;2975:124;2912:187;:::o;3492:964:24:-;3667:31;;:::i;:::-;-1:-1:-1;;;;;3714:17:24;;3710:48;;3740:18;;-1:-1:-1;;;3740:18:24;;;;;;;;;;;3710:48;3826:9;:14;3822:49;;3849:22;;-1:-1:-1;;;3849:22:24;;;;;;;;;;;3822:49;3943:44;3958:9;3969:5;3976:10;3943:14;:44::i;:::-;4039:39;4052:5;4059:10;4071:6;;4039:12;:39::i;:::-;4034:67;;4087:14;;-1:-1:-1;;;4087:14:24;;;;;;;;;;;4034:67;4152:24;4179:36;4197:5;4204:10;4179:17;:36::i;:::-;4152:63;;4229:16;4249:1;4229:21;4225:55;;4259:21;;-1:-1:-1;;;4259:21:24;;-1:-1:-1;;;;;3543:32:28;;4259:21:24;;;3525:51:28;3498:18;;4259:21:24;3379:203:28;4225:55:24;4334:52;-1:-1:-1;;;;;4341:8:24;4334:29;4364:3;4369:16;4334:29;:52::i;:::-;4402:47;;;-1:-1:-1;;;;;18999:15:28;;;18981:34;;19046:2;19031:18;;19024:34;;;19074:18;;;19067:34;;;19137:15;;19132:2;19117:18;;19110:43;4402:47:24;;;;;;;18930:3:28;4402:47:24;;;3700:756;3492:964;;;;;;;;:::o;1303:160:19:-;1412:43;;;-1:-1:-1;;;;;11021:32:28;;1412:43:19;;;11003:51:28;11070:18;;;;11063:34;;;1412:43:19;;;;;;;;;;10976:18:28;;;;1412:43:19;;;;;;;;-1:-1:-1;;;;;1412:43:19;-1:-1:-1;;;1412:43:19;;;1385:71;;1405:5;;1385:19;:71::i;:::-;1303:160;;;:::o;6256:491:24:-;-1:-1:-1;;;;;6436:17:24;;6336:7;6436:17;;;:10;:17;;;;;;6616:28;;;6612:42;;6653:1;6646:8;;;;;6612:42;-1:-1:-1;;;;;6665:17:24;;;;;;:10;:17;;;;;:30;;;6713:27;6726:14;6685:10;6713:27;:::i;:::-;6706:34;6256:491;-1:-1:-1;;;;6256:491:24:o;5111:274:23:-;5256:4;5272:12;5287:30;5299:5;5306:10;4843:38;;-1:-1:-1;;19756:2:28;19752:15;;;19748:53;4843:38:23;;;19736:66:28;19818:12;;;19811:28;;;4780:7:23;;19855:12:28;;4843:38:23;;;-1:-1:-1;;4843:38:23;;;;;;;;;4833:49;;4843:38;4833:49;;;;4816:67;;;20007:19:28;20042:12;4816:67:23;;;;;;;;;;;;4806:78;;;;;;4799:85;;4698:193;;;;;5287:30;5272:45;;5334:44;5353:6;;5334:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5361:10:23;;;-1:-1:-1;5373:4:23;;-1:-1:-1;5334:18:23;:44::i;:::-;5327:51;5111:274;-1:-1:-1;;;;;;5111:274:23:o;4059:629:19:-;4478:23;4504:33;-1:-1:-1;;;;;4504:27:19;;4532:4;4504:27;:33::i;:::-;4478:59;;4551:10;:17;4572:1;4551:22;;:57;;;;;4589:10;4578:30;;;;;;;;;;;;:::i;:::-;4577:31;4551:57;4547:135;;;4631:40;;-1:-1:-1;;;4631:40:19;;-1:-1:-1;;;;;3543:32:28;;4631:40:19;;;3525:51:28;3498:18;;4631:40:19;3379:203:28;1265:154:22;1356:4;1408;1379:25;1392:5;1399:4;1379:12;:25::i;:::-;:33;1372:40;;1265:154;;;;;;:::o;2705:151:20:-;2780:12;2811:38;2833:6;2841:4;2847:1;2811:21;:38::i;1967:290:22:-;2050:7;2092:4;2050:7;2106:116;2130:5;:12;2126:1;:16;2106:116;;;2178:33;2188:12;2202:5;2208:1;2202:8;;;;;;;;:::i;:::-;;;;;;;2178:9;:33::i;:::-;2163:48;-1:-1:-1;2144:3:22;;2106:116;;;-1:-1:-1;2238:12:22;1967:290;-1:-1:-1;;;1967:290:22:o;3180:392:20:-;3279:12;3331:5;3307:21;:29;3303:108;;;3359:41;;-1:-1:-1;;;3359:41:20;;3394:4;3359:41;;;3525:51:28;3498:18;;3359:41:20;3379:203:28;3303:108:20;3421:12;3435:23;3462:6;-1:-1:-1;;;;;3462:11:20;3481:5;3488:4;3462:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3420:73;;;;3510:55;3537:6;3545:7;3554:10;3510:26;:55::i;9229:147:22:-;9292:7;9322:1;9318;:5;:51;;9564:13;9655:15;;;9690:4;9683:15;;;9736:4;9720:21;;9318:51;;;9564:13;9655:15;;;9690:4;9683:15;;;9736:4;9720:21;;9326:20;9496:261;4625:582:20;4769:12;4798:7;4793:408;;4821:19;4829:10;4821:7;:19::i;:::-;4793:408;;;5045:17;;:22;:49;;;;-1:-1:-1;;;;;;5071:18:20;;;:23;5045:49;5041:119;;;5121:24;;-1:-1:-1;;;5121:24:20;;-1:-1:-1;;;;;3543:32:28;;5121:24:20;;;3525:51:28;3498:18;;5121:24:20;3379:203:28;5041:119:20;-1:-1:-1;5180:10:20;5173:17;;5743:516;5874:17;;:21;5870:383;;6102:10;6096:17;6158:15;6145:10;6141:2;6137:19;6130:44;5870:383;6225:17;;-1:-1:-1;;;6225:17:20;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:131:28:-;-1:-1:-1;;;;;89:31:28;;79:42;;69:70;;135:1;132;125:12;150:315;218:6;226;279:2;267:9;258:7;254:23;250:32;247:52;;;295:1;292;285:12;247:52;334:9;321:23;353:31;378:5;353:31;:::i;:::-;403:5;455:2;440:18;;;;427:32;;-1:-1:-1;;;150:315:28:o;652:154::-;711:5;756:2;747:6;742:3;738:16;734:25;731:45;;;772:1;769;762:12;731:45;-1:-1:-1;794:6:28;652:154;-1:-1:-1;652:154:28:o;811:347::-;862:8;872:6;926:3;919:4;911:6;907:17;903:27;893:55;;944:1;941;934:12;893:55;-1:-1:-1;967:20:28;;1010:18;999:30;;996:50;;;1042:1;1039;1032:12;996:50;1079:4;1071:6;1067:17;1055:29;;1131:3;1124:4;1115:6;1107;1103:19;1099:30;1096:39;1093:59;;;1148:1;1145;1138:12;1093:59;811:347;;;;;:::o;1163:1048::-;1306:6;1314;1322;1330;1338;1346;1354;1407:3;1395:9;1386:7;1382:23;1378:33;1375:53;;;1424:1;1421;1414:12;1375:53;1447;1492:7;1481:9;1447:53;:::i;:::-;1437:63;;1547:2;1536:9;1532:18;1519:32;1509:42;;1602:3;1591:9;1587:19;1574:33;1626:18;1667:2;1659:6;1656:14;1653:34;;;1683:1;1680;1673:12;1653:34;1722:58;1772:7;1763:6;1752:9;1748:22;1722:58;:::i;:::-;1799:8;;-1:-1:-1;1696:84:28;-1:-1:-1;1884:3:28;1869:19;;1856:33;;-1:-1:-1;1898:31:28;1856:33;1898:31;:::i;:::-;1948:5;;-1:-1:-1;2006:3:28;1991:19;;1978:33;;2023:16;;;2020:36;;;2052:1;2049;2042:12;2020:36;;2091:60;2143:7;2132:8;2121:9;2117:24;2091:60;:::i;:::-;1163:1048;;;;-1:-1:-1;1163:1048:28;;-1:-1:-1;1163:1048:28;;;;2065:86;;-1:-1:-1;;;1163:1048:28:o;2520:247::-;2579:6;2632:2;2620:9;2611:7;2607:23;2603:32;2600:52;;;2648:1;2645;2638:12;2600:52;2687:9;2674:23;2706:31;2731:5;2706:31;:::i;2954:163::-;3021:20;;3081:10;3070:22;;3060:33;;3050:61;;3107:1;3104;3097:12;3050:61;2954:163;;;:::o;3122:252::-;3189:6;3197;3250:2;3238:9;3229:7;3225:23;3221:32;3218:52;;;3266:1;3263;3256:12;3218:52;3289:28;3307:9;3289:28;:::i;4463:261::-;4383:12;;4371:25;;4445:4;4434:16;;;4428:23;4412:14;;;4405:47;4657:2;4642:18;;4669:49;4305:153;4729:180;4788:6;4841:2;4829:9;4820:7;4816:23;4812:32;4809:52;;;4857:1;4854;4847:12;4809:52;-1:-1:-1;4880:23:28;;4729:180;-1:-1:-1;4729:180:28:o;5119:670::-;5233:6;5241;5249;5257;5310:3;5298:9;5289:7;5285:23;5281:33;5278:53;;;5327:1;5324;5317:12;5278:53;5350;5395:7;5384:9;5350:53;:::i;:::-;5340:63;;5454:2;5443:9;5439:18;5426:32;5481:18;5473:6;5470:30;5467:50;;;5513:1;5510;5503:12;5467:50;5552:58;5602:7;5593:6;5582:9;5578:22;5552:58;:::i;:::-;5629:8;;-1:-1:-1;5526:84:28;-1:-1:-1;;5714:3:28;5699:19;;5686:33;5728:31;5686:33;5728:31;:::i;:::-;5119:670;;;;-1:-1:-1;5119:670:28;;-1:-1:-1;;5119:670:28:o;5986:149::-;6060:20;;6109:1;6099:12;;6089:40;;6125:1;6122;6115:12;6140:367;6203:8;6213:6;6267:3;6260:4;6252:6;6248:17;6244:27;6234:55;;6285:1;6282;6275:12;6234:55;-1:-1:-1;6308:20:28;;6351:18;6340:30;;6337:50;;;6383:1;6380;6373:12;6337:50;6420:4;6412:6;6408:17;6396:29;;6480:3;6473:4;6463:6;6460:1;6456:14;6448:6;6444:27;6440:38;6437:47;6434:67;;;6497:1;6494;6487:12;6512:1185;6667:6;6675;6683;6691;6699;6707;6715;6723;6776:3;6764:9;6755:7;6751:23;6747:33;6744:53;;;6793:1;6790;6783:12;6744:53;6832:9;6819:23;6851:31;6876:5;6851:31;:::i;:::-;6901:5;-1:-1:-1;6925:44:28;6965:2;6950:18;;6925:44;:::i;:::-;6915:54;;7016:2;7005:9;7001:18;6988:32;6978:42;;7071:2;7060:9;7056:18;7043:32;7094:18;7135:2;7127:6;7124:14;7121:34;;;7151:1;7148;7141:12;7121:34;7190:70;7252:7;7243:6;7232:9;7228:22;7190:70;:::i;:::-;7279:8;;-1:-1:-1;7164:96:28;-1:-1:-1;7366:3:28;7351:19;;7338:33;;-1:-1:-1;7380:33:28;7338;7380;:::i;:::-;7432:7;;-1:-1:-1;7492:3:28;7477:19;;7464:33;;7509:16;;;7506:36;;;7538:1;7535;7528:12;7506:36;;7577:60;7629:7;7618:8;7607:9;7603:24;7577:60;:::i;:::-;6512:1185;;;;-1:-1:-1;6512:1185:28;;-1:-1:-1;6512:1185:28;;;;;;7656:8;-1:-1:-1;;;6512:1185:28:o;7702:469::-;7862:4;7904:3;7893:9;7889:19;7881:27;;7941:6;7935:13;7924:9;7917:32;8017:18;8009:4;8001:6;7997:17;7991:24;7987:49;7980:4;7969:9;7965:20;7958:79;8084:4;8076:6;8072:17;8066:24;8099:66;8159:4;8148:9;8144:20;8130:12;4383;;4371:25;;4445:4;4434:16;;;4428:23;4412:14;;4405:47;4305:153;8099:66;;7702:469;;;;:::o;8176:408::-;8266:6;8274;8282;8335:2;8323:9;8314:7;8310:23;8306:32;8303:52;;;8351:1;8348;8341:12;8303:52;8374:35;8399:9;8374:35;:::i;:::-;8364:45;;8459:2;8448:9;8444:18;8431:32;8472:31;8497:5;8472:31;:::i;:::-;8176:408;;8522:5;;-1:-1:-1;;;8574:2:28;8559:18;;;;8546:32;;8176:408::o;8589:184::-;8647:6;8700:2;8688:9;8679:7;8675:23;8671:32;8668:52;;;8716:1;8713;8706:12;8668:52;8739:28;8757:9;8739:28;:::i;9330:1043::-;9476:6;9484;9492;9500;9508;9516;9524;9577:3;9565:9;9556:7;9552:23;9548:33;9545:53;;;9594:1;9591;9584:12;9545:53;9617:35;9642:9;9617:35;:::i;:::-;9607:45;;9699:2;9688:9;9684:18;9671:32;9661:42;;9754:2;9743:9;9739:18;9726:32;9777:18;9818:2;9810:6;9807:14;9804:34;;;9834:1;9831;9824:12;9804:34;9873:70;9935:7;9926:6;9915:9;9911:22;9873:70;:::i;:::-;9962:8;;-1:-1:-1;9847:96:28;-1:-1:-1;10047:2:28;10032:18;;10019:32;;-1:-1:-1;10060:31:28;10019:32;10060:31;:::i;:::-;10110:5;;-1:-1:-1;10168:3:28;10153:19;;10140:33;;10185:16;;;10182:36;;;10214:1;10211;10204:12;10378:236;10463:6;10516:2;10504:9;10495:7;10491:23;10487:32;10484:52;;;10532:1;10529;10522:12;10484:52;10555:53;10600:7;10589:9;10555:53;:::i;11508:250::-;11593:1;11603:113;11617:6;11614:1;11611:13;11603:113;;;11693:11;;;11687:18;11674:11;;;11667:39;11639:2;11632:10;11603:113;;;-1:-1:-1;;11750:1:28;11732:16;;11725:27;11508:250::o;11763:270::-;11804:3;11842:5;11836:12;11869:6;11864:3;11857:19;11885:76;11954:6;11947:4;11942:3;11938:14;11931:4;11924:5;11920:16;11885:76;:::i;:::-;12015:2;11994:15;-1:-1:-1;;11990:29:28;11981:39;;;;12022:4;11977:50;;11763:270;-1:-1:-1;;11763:270:28:o;12038:763::-;12138:10;12130:5;12124:12;12120:29;12115:3;12108:42;12199:4;12192:5;12188:16;12182:23;12175:4;12170:3;12166:14;12159:47;12255:4;12248:5;12244:16;12238:23;12231:4;12226:3;12222:14;12215:47;12311:4;12304:5;12300:16;12294:23;12287:4;12282:3;12278:14;12271:47;12090:3;12364:4;12357:5;12353:16;12347:23;12402:4;12395;12390:3;12386:14;12379:28;12428:46;12468:4;12463:3;12459:14;12445:12;12428:46;:::i;:::-;12416:58;;12522:4;12515:5;12511:16;12505:23;12570:3;12564:4;12560:14;12553:4;12548:3;12544:14;12537:38;12598;12631:4;12615:14;12598:38;:::i;:::-;12584:52;;;12684:4;12677:5;12673:16;12667:23;12734:3;12726:6;12722:16;12715:4;12710:3;12706:14;12699:40;12755;12788:6;12772:14;12755:40;:::i;12806:345::-;13011:2;13000:9;12993:21;12974:4;13031:55;13082:2;13071:9;13067:18;13059:6;13031:55;:::i;:::-;13023:63;;13136:6;13129:14;13122:22;13117:2;13106:9;13102:18;13095:50;12806:345;;;;;:::o;13156:343::-;13223:2;13217:9;13265:2;13253:15;;13298:18;13283:34;;13319:22;;;13280:62;13277:185;;;13384:10;13379:3;13375:20;13372:1;13365:31;13419:4;13416:1;13409:15;13447:4;13444:1;13437:15;13277:185;13478:2;13471:22;13156:343;:::o;13504:575::-;13574:5;13622:4;13610:9;13605:3;13601:19;13597:30;13594:50;;;13640:1;13637;13630:12;13594:50;13673:4;13667:11;13717:4;13709:6;13705:17;13788:6;13776:10;13773:22;13752:18;13740:10;13737:34;13734:62;13731:185;;;13838:10;13833:3;13829:20;13826:1;13819:31;13873:4;13870:1;13863:15;13901:4;13898:1;13891:15;13731:185;13932:4;13925:24;13997:16;;13982:32;;14068:2;14053:18;;;14047:25;14030:15;;;14023:50;;;;-1:-1:-1;13967:6:28;13504:575;-1:-1:-1;13504:575:28:o;14084:259::-;14184:6;14237:2;14225:9;14216:7;14212:23;14208:32;14205:52;;;14253:1;14250;14243:12;14205:52;14276:61;14329:7;14318:9;14276:61;:::i;14348:394::-;14444:6;14497:2;14485:9;14476:7;14472:23;14468:32;14465:52;;;14513:1;14510;14503:12;14465:52;14539:17;;:::i;:::-;14585:9;14579:16;14572:5;14565:31;14649:2;14638:9;14634:18;14628:25;14623:2;14616:5;14612:14;14605:49;14707:2;14696:9;14692:18;14686:25;14681:2;14674:5;14670:14;14663:49;14731:5;14721:15;;;14348:394;;;;:::o;14747:127::-;14808:10;14803:3;14799:20;14796:1;14789:31;14839:4;14836:1;14829:15;14863:4;14860:1;14853:15;14879:236;14959:1;14952:5;14949:12;14939:143;;15004:10;14999:3;14995:20;14992:1;14985:31;15039:4;15036:1;15029:15;15067:4;15064:1;15057:15;14939:143;15091:18;;14879:236::o;15120:348::-;15321:2;15306:18;;15333:43;15310:9;15358:6;15333:43;:::i;:::-;15407:2;15392:18;;15385:34;;;;15450:2;15435:18;15428:34;15120:348;;-1:-1:-1;15120:348:28:o;15473:206::-;15618:2;15603:18;;15630:43;15607:9;15655:6;15630:43;:::i;15684:127::-;15745:10;15740:3;15736:20;15733:1;15726:31;15776:4;15773:1;15766:15;15800:4;15797:1;15790:15;15816:168;15889:9;;;15920;;15937:15;;;15931:22;;15917:37;15907:71;;15958:18;;:::i;15989:217::-;16029:1;16055;16045:132;;16099:10;16094:3;16090:20;16087:1;16080:31;16134:4;16131:1;16124:15;16162:4;16159:1;16152:15;16045:132;-1:-1:-1;16191:9:28;;15989:217::o;16408:472::-;16501:6;16509;16517;16570:2;16558:9;16549:7;16545:23;16541:32;16538:52;;;16586:1;16583;16576:12;16538:52;16625:9;16612:23;16644:31;16669:5;16644:31;:::i;:::-;16694:5;-1:-1:-1;16746:2:28;16731:18;;16718:32;;-1:-1:-1;16802:2:28;16787:18;;16774:32;16815:33;16774:32;16815:33;:::i;:::-;16867:7;16857:17;;;16408:472;;;;;:::o;16885:518::-;17184:3;17173:9;17166:22;17147:4;17205:56;17256:3;17245:9;17241:19;17233:6;17205:56;:::i;:::-;17197:64;;17270:58;17324:2;17313:9;17309:18;17301:6;4383:12;;4371:25;;4445:4;4434:16;;;4428:23;4412:14;;4405:47;4305:153;17270:58;-1:-1:-1;;;;;17364:32:28;;;;17359:2;17344:18;;;;17337:60;16885:518;;-1:-1:-1;;16885:518:28:o;17408:760::-;17549:6;17557;17601:9;17592:7;17588:23;17631:3;17627:2;17623:12;17620:32;;;17648:1;17645;17638:12;17620:32;17672:4;17668:2;17664:13;17661:33;;;17690:1;17687;17680:12;17661:33;;17716:17;;:::i;:::-;17762:9;17756:16;17749:5;17742:31;17818:2;17807:9;17803:18;17797:25;17866:18;17857:7;17853:32;17844:7;17841:45;17831:73;;17900:1;17897;17890:12;17831:73;17931:2;17920:14;;17913:31;17976:70;18038:7;18033:2;18018:18;;17976:70;:::i;:::-;17971:2;17960:14;;17953:94;17964:5;-1:-1:-1;18090:72:28;18154:7;18147:4;18132:20;;18090:72;:::i;:::-;18080:82;;17408:760;;;;;:::o;19164:128::-;19231:9;;;19252:11;;;19249:37;;;19266:18;;:::i;19297:277::-;19364:6;19417:2;19405:9;19396:7;19392:23;19388:32;19385:52;;;19433:1;19430;19423:12;19385:52;19465:9;19459:16;19518:5;19511:13;19504:21;19497:5;19494:32;19484:60;;19540:1;19537;19530:12;20065:127;20126:10;20121:3;20117:20;20114:1;20107:31;20157:4;20154:1;20147:15;20181:4;20178:1;20171:15;20197:287;20326:3;20364:6;20358:13;20380:66;20439:6;20434:3;20427:4;20419:6;20415:17;20380:66;:::i;:::-;20462:16;;;;;20197:287;-1:-1:-1;;20197:287:28:o
Swarm Source
ipfs://111a8bc2b94295c52e53d09674f2a5839b285015ab2fec14debbaa47832d4d3a
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
BASE | 100.00% | $1,805.7 | 1 | $1,805.7 |
Loading...
Loading
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.