Overview
ETH Balance
0 ETH
Eth Value
$0.00Token Holdings
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 70 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Send | 20509836 | 9 days ago | IN | 0.00063777 ETH | 0.00023855 | ||||
Send | 20509806 | 9 days ago | IN | 0.00063777 ETH | 0.00023445 | ||||
Send | 20365002 | 30 days ago | IN | 0.00069745 ETH | 0.00152946 | ||||
Send | 20088126 | 68 days ago | IN | 0.00215223 ETH | 0.00182064 | ||||
Send | 20079939 | 69 days ago | IN | 0.00215223 ETH | 0.00361637 | ||||
Send | 20054865 | 73 days ago | IN | 0.00215223 ETH | 0.00200497 | ||||
Send | 20043611 | 74 days ago | IN | 0.00215223 ETH | 0.00146306 | ||||
Send | 20031394 | 76 days ago | IN | 0.00107847 ETH | 0.00342038 | ||||
Send | 20028749 | 77 days ago | IN | 0.00327722 ETH | 0.00547054 | ||||
Send | 20002102 | 80 days ago | IN | 0.00102844 ETH | 0.00098777 | ||||
Send | 19998844 | 81 days ago | IN | 0.00104156 ETH | 0.00182582 | ||||
Send | 19997099 | 81 days ago | IN | 0.00104156 ETH | 0.00186382 | ||||
Send | 19997060 | 81 days ago | IN | 0.00104156 ETH | 0.00203269 | ||||
Send | 19997024 | 81 days ago | IN | 0.00104156 ETH | 0.00170557 | ||||
Send | 19995886 | 81 days ago | IN | 0.00104156 ETH | 0.00106451 | ||||
Send | 19989591 | 82 days ago | IN | 0.00142653 ETH | 0.00200408 | ||||
Send | 19976233 | 84 days ago | IN | 0.00142653 ETH | 0.00529226 | ||||
Send | 19973796 | 84 days ago | IN | 0.00106654 ETH | 0.00423606 | ||||
Send | 19973198 | 84 days ago | IN | 0.00106654 ETH | 0.00210309 | ||||
Send | 19947444 | 88 days ago | IN | 0.00106654 ETH | 0.0012559 | ||||
Send | 19947374 | 88 days ago | IN | 0.00106654 ETH | 0.00135102 | ||||
Send | 19947105 | 88 days ago | IN | 0.00106654 ETH | 0.00125337 | ||||
Send | 19939930 | 89 days ago | IN | 0.00102546 ETH | 0.00148965 | ||||
Send | 19939805 | 89 days ago | IN | 0.00102546 ETH | 0.00159841 | ||||
Send | 19939169 | 89 days ago | IN | 0.00102546 ETH | 0.00148307 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
20509836 | 9 days ago | 0.00063777 ETH | ||||
20509806 | 9 days ago | 0.00063777 ETH | ||||
20365002 | 30 days ago | 0.00069745 ETH | ||||
20088126 | 68 days ago | 0.00215223 ETH | ||||
20079939 | 69 days ago | 0.00215223 ETH | ||||
20054865 | 73 days ago | 0.00215223 ETH | ||||
20043611 | 74 days ago | 0.00215223 ETH | ||||
20031394 | 76 days ago | 0.00107847 ETH | ||||
20028749 | 77 days ago | 0.00327722 ETH | ||||
20002102 | 80 days ago | 0.00102844 ETH | ||||
19998844 | 81 days ago | 0.00104156 ETH | ||||
19997099 | 81 days ago | 0.00104156 ETH | ||||
19997060 | 81 days ago | 0.00104156 ETH | ||||
19997024 | 81 days ago | 0.00104156 ETH | ||||
19995886 | 81 days ago | 0.00104156 ETH | ||||
19989591 | 82 days ago | 0.00142653 ETH | ||||
19976233 | 84 days ago | 0.00142653 ETH | ||||
19973796 | 84 days ago | 0.00106654 ETH | ||||
19973198 | 84 days ago | 0.00106654 ETH | ||||
19947444 | 88 days ago | 0.00106654 ETH | ||||
19947374 | 88 days ago | 0.00106654 ETH | ||||
19947105 | 88 days ago | 0.00106654 ETH | ||||
19939930 | 89 days ago | 0.00102546 ETH | ||||
19939805 | 89 days ago | 0.00102546 ETH | ||||
19939169 | 89 days ago | 0.00102546 ETH |
Loading...
Loading
Contract Name:
WooTokenOFTAdapter
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 {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {OFTAdapter} from "@layerzerolabs/lz-evm-oapp-v2/contracts/oft/OFTAdapter.sol"; /// @dev contract used for Origin chain where the token is already deployed contract WooTokenOFTAdapter is OFTAdapter { constructor(address _token, address _lzEndpoint, address _delegate) OFTAdapter(_token, _lzEndpoint, _delegate) Ownable(_delegate) {} }
// 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; /** * @title IOAppMsgInspector * @dev Interface for the OApp Message Inspector, allowing examination of message and options contents. */ interface IOAppMsgInspector { // Custom error message for inspection failure error InspectionFailed(bytes message, bytes options); /** * @notice Allows the inspector to examine LayerZero message contents and optionally throw a revert if invalid. * @param _message The message payload to be inspected. * @param _options Additional options or parameters for inspection. * @return valid A boolean indicating whether the inspection passed (true) or failed (false). * * @dev Optionally done as a revert, OR use the boolean provided to handle the failure. */ function inspect(bytes calldata _message, bytes calldata _options) external view returns (bool valid); }
// 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; // @dev Import the 'MessagingFee' and 'MessagingReceipt' so it's exposed to OApp implementers // solhint-disable-next-line no-unused-import import { OAppSender, MessagingFee, MessagingReceipt } from "./OAppSender.sol"; // @dev Import the 'Origin' so it's exposed to OApp implementers // solhint-disable-next-line no-unused-import import { OAppReceiver, Origin } from "./OAppReceiver.sol"; import { OAppCore } from "./OAppCore.sol"; /** * @title OApp * @dev Abstract contract serving as the base for OApp implementation, combining OAppSender and OAppReceiver functionality. */ abstract contract OApp is OAppSender, OAppReceiver { /** * @dev Constructor to initialize the OApp with the provided endpoint and owner. * @param _endpoint The address of the LOCAL LayerZero endpoint. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. */ constructor(address _endpoint, address _delegate) OAppCore(_endpoint, _delegate) {} /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol implementation. * @return receiverVersion The version of the OAppReceiver.sol implementation. */ function oAppVersion() public pure virtual override(OAppSender, OAppReceiver) returns (uint64 senderVersion, uint64 receiverVersion) { return (SENDER_VERSION, RECEIVER_VERSION); } }
// 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.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.20; library OFTComposeMsgCodec { // Offset constants for decoding composed messages uint8 private constant NONCE_OFFSET = 8; uint8 private constant SRC_EID_OFFSET = 12; uint8 private constant AMOUNT_LD_OFFSET = 44; uint8 private constant COMPOSE_FROM_OFFSET = 76; /** * @dev Encodes a OFT composed message. * @param _nonce The nonce value. * @param _srcEid The source endpoint ID. * @param _amountLD The amount in local decimals. * @param _composeMsg The composed message. * @return _msg The encoded Composed message. */ function encode( uint64 _nonce, uint32 _srcEid, uint256 _amountLD, bytes memory _composeMsg // 0x[composeFrom][composeMsg] ) internal pure returns (bytes memory _msg) { _msg = abi.encodePacked(_nonce, _srcEid, _amountLD, _composeMsg); } /** * @dev Retrieves the nonce from the composed message. * @param _msg The message. * @return The nonce value. */ function nonce(bytes calldata _msg) internal pure returns (uint64) { return uint64(bytes8(_msg[:NONCE_OFFSET])); } /** * @dev Retrieves the source endpoint ID from the composed message. * @param _msg The message. * @return The source endpoint ID. */ function srcEid(bytes calldata _msg) internal pure returns (uint32) { return uint32(bytes4(_msg[NONCE_OFFSET:SRC_EID_OFFSET])); } /** * @dev Retrieves the amount in local decimals from the composed message. * @param _msg The message. * @return The amount in local decimals. */ function amountLD(bytes calldata _msg) internal pure returns (uint256) { return uint256(bytes32(_msg[SRC_EID_OFFSET:AMOUNT_LD_OFFSET])); } /** * @dev Retrieves the composeFrom value from the composed message. * @param _msg The message. * @return The composeFrom value. */ function composeFrom(bytes calldata _msg) internal pure returns (bytes32) { return bytes32(_msg[AMOUNT_LD_OFFSET:COMPOSE_FROM_OFFSET]); } /** * @dev Retrieves the composed message. * @param _msg The message. * @return The composed message. */ function composeMsg(bytes calldata _msg) internal pure returns (bytes memory) { return _msg[COMPOSE_FROM_OFFSET:]; } /** * @dev Converts an address to bytes32. * @param _addr The address to convert. * @return The bytes32 representation of the address. */ function addressToBytes32(address _addr) internal pure returns (bytes32) { return bytes32(uint256(uint160(_addr))); } /** * @dev Converts bytes32 to an address. * @param _b The bytes32 value to convert. * @return The address representation of bytes32. */ function bytes32ToAddress(bytes32 _b) internal pure returns (address) { return address(uint160(uint256(_b))); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; library OFTMsgCodec { // Offset constants for encoding and decoding OFT messages uint8 private constant SEND_TO_OFFSET = 32; uint8 private constant SEND_AMOUNT_SD_OFFSET = 40; /** * @dev Encodes an OFT LayerZero message. * @param _sendTo The recipient address. * @param _amountShared The amount in shared decimals. * @param _composeMsg The composed message. * @return _msg The encoded message. * @return hasCompose A boolean indicating whether the message has a composed payload. */ function encode( bytes32 _sendTo, uint64 _amountShared, bytes memory _composeMsg ) internal view returns (bytes memory _msg, bool hasCompose) { hasCompose = _composeMsg.length > 0; // @dev Remote chains will want to know the composed function caller ie. msg.sender on the src. _msg = hasCompose ? abi.encodePacked(_sendTo, _amountShared, addressToBytes32(msg.sender), _composeMsg) : abi.encodePacked(_sendTo, _amountShared); } /** * @dev Checks if the OFT message is composed. * @param _msg The OFT message. * @return A boolean indicating whether the message is composed. */ function isComposed(bytes calldata _msg) internal pure returns (bool) { return _msg.length > SEND_AMOUNT_SD_OFFSET; } /** * @dev Retrieves the recipient address from the OFT message. * @param _msg The OFT message. * @return The recipient address. */ function sendTo(bytes calldata _msg) internal pure returns (bytes32) { return bytes32(_msg[:SEND_TO_OFFSET]); } /** * @dev Retrieves the amount in shared decimals from the OFT message. * @param _msg The OFT message. * @return The amount in shared decimals. */ function amountSD(bytes calldata _msg) internal pure returns (uint64) { return uint64(bytes8(_msg[SEND_TO_OFFSET:SEND_AMOUNT_SD_OFFSET])); } /** * @dev Retrieves the composed message from the OFT message. * @param _msg The OFT message. * @return The composed message. */ function composeMsg(bytes calldata _msg) internal pure returns (bytes memory) { return _msg[SEND_AMOUNT_SD_OFFSET:]; } /** * @dev Converts an address to bytes32. * @param _addr The address to convert. * @return The bytes32 representation of the address. */ function addressToBytes32(address _addr) internal pure returns (bytes32) { return bytes32(uint256(uint160(_addr))); } /** * @dev Converts bytes32 to an address. * @param _b The bytes32 value to convert. * @return The address representation of bytes32. */ function bytes32ToAddress(bytes32 _b) internal pure returns (address) { return address(uint160(uint256(_b))); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { IOFT, OFTCore } from "./OFTCore.sol"; /** * @title OFT Contract * @dev OFT is an ERC-20 token that extends the functionality of the OFTCore contract. */ abstract contract OFT is OFTCore, ERC20 { /** * @dev Constructor for the OFT contract. * @param _name The name of the OFT. * @param _symbol The symbol of the OFT. * @param _lzEndpoint The LayerZero endpoint address. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. */ constructor( string memory _name, string memory _symbol, address _lzEndpoint, address _delegate ) ERC20(_name, _symbol) OFTCore(decimals(), _lzEndpoint, _delegate) {} /** * @dev Retrieves the address of the underlying ERC20 implementation. * @return The address of the OFT token. * * @dev In the case of OFT, address(this) and erc20 are the same contract. */ function token() public view returns (address) { return address(this); } /** * @notice Indicates whether the OFT contract requires approval of the 'token()' to send. * @return requiresApproval Needs approval of the underlying token implementation. * * @dev In the case of OFT where the contract IS the token, approval is NOT required. */ function approvalRequired() external pure virtual returns (bool) { return false; } /** * @dev Burns tokens from the sender's specified balance. * @param _from The address to debit the tokens from. * @param _amountLD The amount of tokens to send in local decimals. * @param _minAmountLD The minimum amount to send in local decimals. * @param _dstEid The destination chain ID. * @return amountSentLD The amount sent in local decimals. * @return amountReceivedLD The amount received in local decimals on the remote. */ function _debit( address _from, uint256 _amountLD, uint256 _minAmountLD, uint32 _dstEid ) internal virtual override returns (uint256 amountSentLD, uint256 amountReceivedLD) { (amountSentLD, amountReceivedLD) = _debitView(_amountLD, _minAmountLD, _dstEid); // @dev In NON-default OFT, amountSentLD could be 100, with a 10% fee, the amountReceivedLD amount is 90, // therefore amountSentLD CAN differ from amountReceivedLD. // @dev Default OFT burns on src. _burn(_from, amountSentLD); } /** * @dev Credits tokens to the specified address. * @param _to The address to credit the tokens to. * @param _amountLD The amount of tokens to credit in local decimals. * @dev _srcEid The source chain ID. * @return amountReceivedLD The amount of tokens ACTUALLY received in local decimals. */ function _credit( address _to, uint256 _amountLD, uint32 /*_srcEid*/ ) internal virtual override returns (uint256 amountReceivedLD) { // @dev Default OFT mints on dst. _mint(_to, _amountLD); // @dev In the case of NON-default OFT, the _amountLD MIGHT not be == amountReceivedLD. return _amountLD; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { IERC20Metadata, IERC20 } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { IOFT, OFTCore } from "./OFTCore.sol"; /** * @title OFTAdapter Contract * @dev OFTAdapter is a contract that adapts an ERC-20 token to the OFT functionality. * * @dev For existing ERC20 tokens, this can be used to convert the token to crosschain compatibility. * @dev WARNING: ONLY 1 of these should exist for a given global mesh, * unless you make a NON-default implementation of OFT and needs to be done very carefully. * @dev WARNING: The default OFTAdapter implementation assumes LOSSLESS transfers, ie. 1 token in, 1 token out. * IF the 'innerToken' applies something like a transfer fee, the default will NOT work... * a pre/post balance check will need to be done to calculate the amountSentLD/amountReceivedLD. */ abstract contract OFTAdapter is OFTCore { using SafeERC20 for IERC20; IERC20 internal immutable innerToken; /** * @dev Constructor for the OFTAdapter contract. * @param _token The address of the ERC-20 token to be adapted. * @param _lzEndpoint The LayerZero endpoint address. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. */ constructor( address _token, address _lzEndpoint, address _delegate ) OFTCore(IERC20Metadata(_token).decimals(), _lzEndpoint, _delegate) { innerToken = IERC20(_token); } /** * @dev Retrieves the address of the underlying ERC20 implementation. * @return The address of the adapted ERC-20 token. * * @dev In the case of OFTAdapter, address(this) and erc20 are NOT the same contract. */ function token() public view returns (address) { return address(innerToken); } /** * @notice Indicates whether the OFT contract requires approval of the 'token()' to send. * @return requiresApproval Needs approval of the underlying token implementation. * * @dev In the case of default OFTAdapter, approval is required. * @dev In non-default OFTAdapter contracts with something like mint and burn privileges, it would NOT need approval. */ function approvalRequired() external pure virtual returns (bool) { return true; } /** * @dev Burns tokens from the sender's specified balance, ie. pull method. * @param _from The address to debit from. * @param _amountLD The amount of tokens to send in local decimals. * @param _minAmountLD The minimum amount to send in local decimals. * @param _dstEid The destination chain ID. * @return amountSentLD The amount sent in local decimals. * @return amountReceivedLD The amount received in local decimals on the remote. * * @dev msg.sender will need to approve this _amountLD of tokens to be locked inside of the contract. * @dev WARNING: The default OFTAdapter implementation assumes LOSSLESS transfers, ie. 1 token in, 1 token out. * IF the 'innerToken' applies something like a transfer fee, the default will NOT work... * a pre/post balance check will need to be done to calculate the amountReceivedLD. */ function _debit( address _from, uint256 _amountLD, uint256 _minAmountLD, uint32 _dstEid ) internal virtual override returns (uint256 amountSentLD, uint256 amountReceivedLD) { (amountSentLD, amountReceivedLD) = _debitView(_amountLD, _minAmountLD, _dstEid); // @dev Lock tokens by moving them into this contract from the caller. innerToken.safeTransferFrom(_from, address(this), amountSentLD); } /** * @dev Credits tokens to the specified address. * @param _to The address to credit the tokens to. * @param _amountLD The amount of tokens to credit in local decimals. * @dev _srcEid The source chain ID. * @return amountReceivedLD The amount of tokens ACTUALLY received in local decimals. * * @dev WARNING: The default OFTAdapter implementation assumes LOSSLESS transfers, ie. 1 token in, 1 token out. * IF the 'innerToken' applies something like a transfer fee, the default will NOT work... * a pre/post balance check will need to be done to calculate the amountReceivedLD. */ function _credit( address _to, uint256 _amountLD, uint32 /*_srcEid*/ ) internal virtual override returns (uint256 amountReceivedLD) { // @dev Unlock the tokens and transfer to the recipient. innerToken.safeTransfer(_to, _amountLD); // @dev In the case of NON-default OFTAdapter, the amountLD MIGHT not be == amountReceivedLD. return _amountLD; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { OApp, Origin } from "../oapp/OApp.sol"; import { OAppOptionsType3 } from "../oapp/libs/OAppOptionsType3.sol"; import { IOAppMsgInspector } from "../oapp/interfaces/IOAppMsgInspector.sol"; import { OAppPreCrimeSimulator } from "../precrime/OAppPreCrimeSimulator.sol"; import { IOFT, SendParam, OFTLimit, OFTReceipt, OFTFeeDetail, MessagingReceipt, MessagingFee } from "./interfaces/IOFT.sol"; import { OFTMsgCodec } from "./libs/OFTMsgCodec.sol"; import { OFTComposeMsgCodec } from "./libs/OFTComposeMsgCodec.sol"; /** * @title OFTCore * @dev Abstract contract for the OftChain (OFT) token. */ abstract contract OFTCore is IOFT, OApp, OAppPreCrimeSimulator, OAppOptionsType3 { using OFTMsgCodec for bytes; using OFTMsgCodec for bytes32; // @notice Provides a conversion rate when swapping between denominations of SD and LD // - shareDecimals == SD == shared Decimals // - localDecimals == LD == local decimals // @dev Considers that tokens have different decimal amounts on various chains. // @dev eg. // For a token // - locally with 4 decimals --> 1.2345 => uint(12345) // - remotely with 2 decimals --> 1.23 => uint(123) // - The conversion rate would be 10 ** (4 - 2) = 100 // @dev If you want to send 1.2345 -> (uint 12345), you CANNOT represent that value on the remote, // you can only display 1.23 -> uint(123). // @dev To preserve the dust that would otherwise be lost on that conversion, // we need to unify a denomination that can be represented on ALL chains inside of the OFT mesh uint256 public immutable decimalConversionRate; // @notice Msg types that are used to identify the various OFT operations. // @dev This can be extended in child contracts for non-default oft operations // @dev These values are used in things like combineOptions() in OAppOptionsType3.sol. uint16 public constant SEND = 1; uint16 public constant SEND_AND_CALL = 2; // Address of an optional contract to inspect both 'message' and 'options' address public msgInspector; event MsgInspectorSet(address inspector); /** * @dev Constructor. * @param _localDecimals The decimals of the token on the local chain (this chain). * @param _endpoint The address of the LayerZero endpoint. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. */ constructor(uint8 _localDecimals, address _endpoint, address _delegate) OApp(_endpoint, _delegate) { if (_localDecimals < sharedDecimals()) revert InvalidLocalDecimals(); decimalConversionRate = 10 ** (_localDecimals - sharedDecimals()); } /** * @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 pure virtual returns (bytes4 interfaceId, uint64 version) { return (type(IOFT).interfaceId, 1); } /** * @dev Retrieves the shared decimals of the OFT. * @return The shared decimals of the OFT. * * @dev Sets an implicit cap on the amount of tokens, over uint64.max() will need some sort of outbound cap / totalSupply cap * Lowest common decimal denominator between chains. * Defaults to 6 decimal places to provide up to 18,446,744,073,709.551615 units (max uint64). * For tokens exceeding this totalSupply(), they will need to override the sharedDecimals function with something smaller. * ie. 4 sharedDecimals would be 1,844,674,407,370,955.1615 */ function sharedDecimals() public view virtual returns (uint8) { return 6; } /** * @dev Sets the message inspector address for the OFT. * @param _msgInspector The address of the message inspector. * * @dev This is an optional contract that can be used to inspect both 'message' and 'options'. * @dev Set it to address(0) to disable it, or set it to a contract address to enable it. */ function setMsgInspector(address _msgInspector) public virtual onlyOwner { msgInspector = _msgInspector; emit MsgInspectorSet(_msgInspector); } /** * @notice Provides a quote for OFT-related operations. * @param _sendParam The parameters for the send operation. * @return oftLimit The OFT limit information. * @return oftFeeDetails The details of OFT fees. * @return oftReceipt The OFT receipt information. */ function quoteOFT( SendParam calldata _sendParam ) external view virtual returns (OFTLimit memory oftLimit, OFTFeeDetail[] memory oftFeeDetails, OFTReceipt memory oftReceipt) { uint256 minAmountLD = 0; // Unused in the default implementation. uint256 maxAmountLD = type(uint64).max; // Unused in the default implementation. oftLimit = OFTLimit(minAmountLD, maxAmountLD); // Unused in the default implementation; reserved for future complex fee details. oftFeeDetails = new OFTFeeDetail[](0); // @dev This is the same as the send() operation, but without the actual send. // - amountSentLD is the amount in local decimals that would be sent from the sender. // - amountReceivedLD is the amount in local decimals that will be credited to the recipient on the remote OFT instance. // @dev The amountSentLD MIGHT not equal the amount the user actually receives. HOWEVER, the default does. (uint256 amountSentLD, uint256 amountReceivedLD) = _debitView( _sendParam.amountLD, _sendParam.minAmountLD, _sendParam.dstEid ); oftReceipt = OFTReceipt(amountSentLD, amountReceivedLD); } /** * @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 msgFee 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 virtual returns (MessagingFee memory msgFee) { // @dev mock the amount to receive, this is the same operation used in the send(). // The quote is as similar as possible to the actual send() operation. (, uint256 amountReceivedLD) = _debitView(_sendParam.amountLD, _sendParam.minAmountLD, _sendParam.dstEid); // @dev Builds the options and OFT message to quote in the endpoint. (bytes memory message, bytes memory options) = _buildMsgAndOptions(_sendParam, amountReceivedLD); // @dev Calculates the LayerZero fee for the send() operation. return _quote(_sendParam.dstEid, message, options, _payInLzToken); } /** * @dev Executes the send operation. * @param _sendParam The parameters for the send operation. * @param _fee The calculated fee for the send() operation. * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. * @param _refundAddress The address to receive any excess funds. * @return msgReceipt The receipt for 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 virtual returns (MessagingReceipt memory msgReceipt, OFTReceipt memory oftReceipt) { // @dev Applies the token transfers regarding this send() operation. // - amountSentLD is the amount in local decimals that was ACTUALLY sent/debited from the sender. // - amountReceivedLD is the amount in local decimals that will be received/credited to the recipient on the remote OFT instance. (uint256 amountSentLD, uint256 amountReceivedLD) = _debit( msg.sender, _sendParam.amountLD, _sendParam.minAmountLD, _sendParam.dstEid ); // @dev Builds the options and OFT message to quote in the endpoint. (bytes memory message, bytes memory options) = _buildMsgAndOptions(_sendParam, amountReceivedLD); // @dev Sends the message to the LayerZero endpoint and returns the LayerZero msg receipt. msgReceipt = _lzSend(_sendParam.dstEid, message, options, _fee, _refundAddress); // @dev Formulate the OFT receipt. oftReceipt = OFTReceipt(amountSentLD, amountReceivedLD); emit OFTSent(msgReceipt.guid, _sendParam.dstEid, msg.sender, amountSentLD, amountReceivedLD); } /** * @dev Internal function to build the message and options. * @param _sendParam The parameters for the send() operation. * @param _amountLD The amount in local decimals. * @return message The encoded message. * @return options The encoded options. */ function _buildMsgAndOptions( SendParam calldata _sendParam, uint256 _amountLD ) internal view virtual returns (bytes memory message, bytes memory options) { bool hasCompose; // @dev This generated message has the msg.sender encoded into the payload so the remote knows who the caller is. (message, hasCompose) = OFTMsgCodec.encode( _sendParam.to, _toSD(_amountLD), // @dev Must be include a non empty bytes if you want to compose, EVEN if you dont need it on the remote. // EVEN if you dont require an arbitrary payload to be sent... eg. '0x01' _sendParam.composeMsg ); // @dev Change the msg type depending if its composed or not. uint16 msgType = hasCompose ? SEND_AND_CALL : SEND; // @dev Combine the callers _extraOptions with the enforced options via the OAppOptionsType3. options = combineOptions(_sendParam.dstEid, msgType, _sendParam.extraOptions); // @dev Optionally inspect the message and options depending if the OApp owner has set a msg inspector. // @dev If it fails inspection, needs to revert in the implementation. ie. does not rely on return boolean if (msgInspector != address(0)) IOAppMsgInspector(msgInspector).inspect(message, options); } /** * @dev Internal function to handle the receive on the LayerZero endpoint. * @param _origin The origin information. * - srcEid: The source chain endpoint ID. * - sender: The sender address from the src chain. * - nonce: The nonce of the LayerZero message. * @param _guid The unique identifier for the received LayerZero message. * @param _message The encoded message. * @dev _executor The address of the executor. * @dev _extraData Additional data. */ function _lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address /*_executor*/, // @dev unused in the default implementation. bytes calldata /*_extraData*/ // @dev unused in the default implementation. ) internal virtual override { // @dev The src sending chain doesnt know the address length on this chain (potentially non-evm) // Thus everything is bytes32() encoded in flight. address toAddress = _message.sendTo().bytes32ToAddress(); // @dev Credit the amountLD to the recipient and return the ACTUAL amount the recipient received in local decimals uint256 amountReceivedLD = _credit(toAddress, _toLD(_message.amountSD()), _origin.srcEid); if (_message.isComposed()) { // @dev Proprietary composeMsg format for the OFT. bytes memory composeMsg = OFTComposeMsgCodec.encode( _origin.nonce, _origin.srcEid, amountReceivedLD, _message.composeMsg() ); // @dev Stores the lzCompose payload that will be executed in a separate tx. // Standardizes functionality for executing arbitrary contract invocation on some non-evm chains. // @dev The off-chain executor will listen and process the msg based on the src-chain-callers compose options passed. // @dev The index is used when a OApp needs to compose multiple msgs on lzReceive. // For default OFT implementation there is only 1 compose msg per lzReceive, thus its always 0. endpoint.sendCompose(toAddress, _guid, 0 /* the index of the composed message*/, composeMsg); } emit OFTReceived(_guid, _origin.srcEid, toAddress, amountReceivedLD); } /** * @dev Internal function to handle the OAppPreCrimeSimulator simulated receive. * @param _origin The origin information. * - srcEid: The source chain endpoint ID. * - sender: The sender address from the src chain. * - nonce: The nonce of the LayerZero message. * @param _guid The unique identifier for the received LayerZero message. * @param _message The LayerZero message. * @param _executor The address of the off-chain executor. * @param _extraData Arbitrary data passed by the msg executor. * * @dev Enables the preCrime simulator to mock sending lzReceive() messages, * routes the msg down from the OAppPreCrimeSimulator, and back up to the OAppReceiver. */ function _lzReceiveSimulate( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) internal virtual override { _lzReceive(_origin, _guid, _message, _executor, _extraData); } /** * @dev Check if the peer is considered 'trusted' by the OApp. * @param _eid The endpoint ID to check. * @param _peer The peer to check. * @return Whether the peer passed is considered 'trusted' by the OApp. * * @dev Enables OAppPreCrimeSimulator to check whether a potential Inbound Packet is from a trusted source. */ function isPeer(uint32 _eid, bytes32 _peer) public view virtual override returns (bool) { return peers[_eid] == _peer; } /** * @dev Internal function to remove dust from the given local decimal amount. * @param _amountLD The amount in local decimals. * @return amountLD The amount after removing dust. * * @dev Prevents the loss of dust when moving amounts between chains with different decimals. * @dev eg. uint(123) with a conversion rate of 100 becomes uint(100). */ function _removeDust(uint256 _amountLD) internal view virtual returns (uint256 amountLD) { return (_amountLD / decimalConversionRate) * decimalConversionRate; } /** * @dev Internal function to convert an amount from shared decimals into local decimals. * @param _amountSD The amount in shared decimals. * @return amountLD The amount in local decimals. */ function _toLD(uint64 _amountSD) internal view virtual returns (uint256 amountLD) { return _amountSD * decimalConversionRate; } /** * @dev Internal function to convert an amount from local decimals into shared decimals. * @param _amountLD The amount in local decimals. * @return amountSD The amount in shared decimals. */ function _toSD(uint256 _amountLD) internal view virtual returns (uint64 amountSD) { return uint64(_amountLD / decimalConversionRate); } /** * @dev Internal function to mock the amount mutation from a OFT debit() operation. * @param _amountLD The amount to send in local decimals. * @param _minAmountLD The minimum amount to send in local decimals. * @dev _dstEid The destination endpoint ID. * @return amountSentLD The amount sent, in local decimals. * @return amountReceivedLD The amount to be received on the remote chain, in local decimals. * * @dev This is where things like fees would be calculated and deducted from the amount to be received on the remote. */ function _debitView( uint256 _amountLD, uint256 _minAmountLD, uint32 /*_dstEid*/ ) internal view virtual returns (uint256 amountSentLD, uint256 amountReceivedLD) { // @dev Remove the dust so nothing is lost on the conversion between chains with different decimals for the token. amountSentLD = _removeDust(_amountLD); // @dev The amount to send is the same as amount received in the default implementation. amountReceivedLD = amountSentLD; // @dev Check for slippage. if (amountReceivedLD < _minAmountLD) { revert SlippageExceeded(amountReceivedLD, _minAmountLD); } } /** * @dev Internal function to perform a debit operation. * @param _from The address to debit. * @param _amountLD The amount to send in local decimals. * @param _minAmountLD The minimum amount to send in local decimals. * @param _dstEid The destination endpoint ID. * @return amountSentLD The amount sent in local decimals. * @return amountReceivedLD The amount received in local decimals on the remote. * * @dev Defined here but are intended to be overriden depending on the OFT implementation. * @dev Depending on OFT implementation the _amountLD could differ from the amountReceivedLD. */ function _debit( address _from, uint256 _amountLD, uint256 _minAmountLD, uint32 _dstEid ) internal virtual returns (uint256 amountSentLD, uint256 amountReceivedLD); /** * @dev Internal function to perform a credit operation. * @param _to The address to credit. * @param _amountLD The amount to credit in local decimals. * @param _srcEid The source endpoint ID. * @return amountReceivedLD The amount ACTUALLY received in local decimals. * * @dev Defined here but are intended to be overriden depending on the OFT implementation. * @dev Depending on OFT implementation the _amountLD could differ from the amountReceivedLD. */ function _credit( address _to, uint256 _amountLD, uint32 _srcEid ) internal virtual returns (uint256 amountReceivedLD); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; // @dev Import the Origin so it's exposed to OAppPreCrimeSimulator implementers. // solhint-disable-next-line no-unused-import import { InboundPacket, Origin } from "../libs/Packet.sol"; /** * @title IOAppPreCrimeSimulator Interface * @dev Interface for the preCrime simulation functionality in an OApp. */ interface IOAppPreCrimeSimulator { // @dev simulation result used in PreCrime implementation error SimulationResult(bytes result); error OnlySelf(); /** * @dev Emitted when the preCrime contract address is set. * @param preCrimeAddress The address of the preCrime contract. */ event PreCrimeSet(address preCrimeAddress); /** * @dev Retrieves the address of the preCrime contract implementation. * @return The address of the preCrime contract. */ function preCrime() external view returns (address); /** * @dev Retrieves the address of the OApp contract. * @return The address of the OApp contract. */ function oApp() external view returns (address); /** * @dev Sets the preCrime contract address. * @param _preCrime The address of the preCrime contract. */ function setPreCrime(address _preCrime) external; /** * @dev Mocks receiving a packet, then reverts with a series of data to infer the state/result. * @param _packets An array of LayerZero InboundPacket objects representing received packets. */ function lzReceiveAndRevert(InboundPacket[] calldata _packets) external payable; /** * @dev checks if the specified peer is considered 'trusted' by the OApp. * @param _eid The endpoint Id to check. * @param _peer The peer to check. * @return Whether the peer passed is considered 'trusted' by the OApp. */ function isPeer(uint32 _eid, bytes32 _peer) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; struct PreCrimePeer { uint32 eid; bytes32 preCrime; bytes32 oApp; } // TODO not done yet interface IPreCrime { error OnlyOffChain(); // for simulate() error PacketOversize(uint256 max, uint256 actual); error PacketUnsorted(); error SimulationFailed(bytes reason); // for preCrime() error SimulationResultNotFound(uint32 eid); error InvalidSimulationResult(uint32 eid, bytes reason); error CrimeFound(bytes crime); function getConfig(bytes[] calldata _packets, uint256[] calldata _packetMsgValues) external returns (bytes memory); function simulate( bytes[] calldata _packets, uint256[] calldata _packetMsgValues ) external payable returns (bytes memory); function buildSimulationResult() external view returns (bytes memory); function preCrime( bytes[] calldata _packets, uint256[] calldata _packetMsgValues, bytes[] calldata _simulations ) external; function version() external view returns (uint64 major, uint8 minor); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { Origin } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol"; import { PacketV1Codec } from "@layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/libs/PacketV1Codec.sol"; /** * @title InboundPacket * @dev Structure representing an inbound packet received by the contract. */ struct InboundPacket { Origin origin; // Origin information of the packet. uint32 dstEid; // Destination endpointId of the packet. address receiver; // Receiver address for the packet. bytes32 guid; // Unique identifier of the packet. uint256 value; // msg.value of the packet. address executor; // Executor address for the packet. bytes message; // Message payload of the packet. bytes extraData; // Additional arbitrary data for the packet. } /** * @title PacketDecoder * @dev Library for decoding LayerZero packets. */ library PacketDecoder { using PacketV1Codec for bytes; /** * @dev Decode an inbound packet from the given packet data. * @param _packet The packet data to decode. * @return packet An InboundPacket struct representing the decoded packet. */ function decode(bytes calldata _packet) internal pure returns (InboundPacket memory packet) { packet.origin = Origin(_packet.srcEid(), _packet.sender(), _packet.nonce()); packet.dstEid = _packet.dstEid(); packet.receiver = _packet.receiverB20(); packet.guid = _packet.guid(); packet.message = _packet.message(); } /** * @dev Decode multiple inbound packets from the given packet data and associated message values. * @param _packets An array of packet data to decode. * @param _packetMsgValues An array of associated message values for each packet. * @return packets An array of InboundPacket structs representing the decoded packets. */ function decode( bytes[] calldata _packets, uint256[] memory _packetMsgValues ) internal pure returns (InboundPacket[] memory packets) { packets = new InboundPacket[](_packets.length); for (uint256 i = 0; i < _packets.length; i++) { bytes calldata packet = _packets[i]; packets[i] = PacketDecoder.decode(packet); // @dev Allows the verifier to specify the msg.value that gets passed in lzReceive. packets[i].value = _packetMsgValues[i]; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { IPreCrime } from "./interfaces/IPreCrime.sol"; import { IOAppPreCrimeSimulator, InboundPacket, Origin } from "./interfaces/IOAppPreCrimeSimulator.sol"; /** * @title OAppPreCrimeSimulator * @dev Abstract contract serving as the base for preCrime simulation functionality in an OApp. */ abstract contract OAppPreCrimeSimulator is IOAppPreCrimeSimulator, Ownable { // The address of the preCrime implementation. address public preCrime; /** * @dev Retrieves the address of the OApp contract. * @return The address of the OApp contract. * * @dev The simulator contract is the base contract for the OApp by default. * @dev If the simulator is a separate contract, override this function. */ function oApp() external view virtual returns (address) { return address(this); } /** * @dev Sets the preCrime contract address. * @param _preCrime The address of the preCrime contract. */ function setPreCrime(address _preCrime) public virtual onlyOwner { preCrime = _preCrime; emit PreCrimeSet(_preCrime); } /** * @dev Interface for pre-crime simulations. Always reverts at the end with the simulation results. * @param _packets An array of InboundPacket objects representing received packets to be delivered. * * @dev WARNING: MUST revert at the end with the simulation results. * @dev Gives the preCrime implementation the ability to mock sending packets to the lzReceive function, * WITHOUT actually executing them. */ function lzReceiveAndRevert(InboundPacket[] calldata _packets) public payable virtual { for (uint256 i = 0; i < _packets.length; i++) { InboundPacket calldata packet = _packets[i]; // Ignore packets that are not from trusted peers. if (!isPeer(packet.origin.srcEid, packet.origin.sender)) continue; // @dev Because a verifier is calling this function, it doesnt have access to executor params: // - address _executor // - bytes calldata _extraData // preCrime will NOT work for OApps that rely on these two parameters inside of their _lzReceive(). // They are instead stubbed to default values, address(0) and bytes("") // @dev Calling this.lzReceiveSimulate removes ability for assembly return 0 callstack exit, // which would cause the revert to be ignored. this.lzReceiveSimulate{ value: packet.value }( packet.origin, packet.guid, packet.message, packet.executor, packet.extraData ); } // @dev Revert with the simulation results. msg.sender must implement IPreCrime.buildSimulationResult(). revert SimulationResult(IPreCrime(msg.sender).buildSimulationResult()); } /** * @dev Is effectively an internal function because msg.sender must be address(this). * Allows resetting the call stack for 'internal' calls. * @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 of the packet. * @param _message The message payload of the packet. * @param _executor The executor address for the packet. * @param _extraData Additional data for the packet. */ function lzReceiveSimulate( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) external payable virtual { // @dev Ensure ONLY can be called 'internally'. if (msg.sender != address(this)) revert OnlySelf(); _lzReceiveSimulate(_origin, _guid, _message, _executor, _extraData); } /** * @dev Internal function to handle the OAppPreCrimeSimulator simulated receive. * @param _origin The origin information. * - srcEid: The source chain endpoint ID. * - sender: The sender address from the src chain. * - nonce: The nonce of the LayerZero message. * @param _guid The GUID of the LayerZero message. * @param _message The LayerZero message. * @param _executor The address of the off-chain executor. * @param _extraData Arbitrary data passed by the msg executor. * * @dev Enables the preCrime simulator to mock sending lzReceive() messages, * routes the msg down from the OAppPreCrimeSimulator, and back up to the OAppReceiver. */ function _lzReceiveSimulate( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) internal virtual; /** * @dev checks if the specified peer is considered 'trusted' by the OApp. * @param _eid The endpoint Id to check. * @param _peer The peer to check. * @return Whether the peer passed is considered 'trusted' by the OApp. */ function isPeer(uint32 _eid, bytes32 _peer) public view virtual returns (bool); }
// 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; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import { SetConfigParam } from "./IMessageLibManager.sol"; enum MessageLibType { Send, Receive, SendAndReceive } interface IMessageLib is IERC165 { function setConfig(address _oapp, SetConfigParam[] calldata _config) external; function getConfig(uint32 _eid, address _oapp, uint32 _configType) external view returns (bytes memory config); function isSupportedEid(uint32 _eid) external view returns (bool); // message libs of same major version are compatible function version() external view returns (uint64 major, uint8 minor, uint8 endpointVersion); function messageLibType() external view returns (MessageLibType); }
// 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 pragma solidity >=0.8.0; import { MessagingFee } from "./ILayerZeroEndpointV2.sol"; import { IMessageLib } from "./IMessageLib.sol"; struct Packet { uint64 nonce; uint32 srcEid; address sender; uint32 dstEid; bytes32 receiver; bytes32 guid; bytes message; } interface ISendLib is IMessageLib { function send( Packet calldata _packet, bytes calldata _options, bool _payInLzToken ) external returns (MessagingFee memory, bytes memory encodedPacket); function quote( Packet calldata _packet, bytes calldata _options, bool _payInLzToken ) external view returns (MessagingFee memory); function setTreasury(address _treasury) external; function withdrawFee(address _to, uint256 _amount) external; function withdrawLzTokenFee(address _lzToken, address _to, uint256 _amount) external; }
// SPDX-License-Identifier: LZBL-1.2 pragma solidity ^0.8.20; library AddressCast { error AddressCast_InvalidSizeForAddress(); error AddressCast_InvalidAddress(); function toBytes32(bytes calldata _addressBytes) internal pure returns (bytes32 result) { if (_addressBytes.length > 32) revert AddressCast_InvalidAddress(); result = bytes32(_addressBytes); unchecked { uint256 offset = 32 - _addressBytes.length; result = result >> (offset * 8); } } function toBytes32(address _address) internal pure returns (bytes32 result) { result = bytes32(uint256(uint160(_address))); } function toBytes(bytes32 _addressBytes32, uint256 _size) internal pure returns (bytes memory result) { if (_size == 0 || _size > 32) revert AddressCast_InvalidSizeForAddress(); result = new bytes(_size); unchecked { uint256 offset = 256 - _size * 8; assembly { mstore(add(result, 32), shl(offset, _addressBytes32)) } } } function toAddress(bytes32 _addressBytes32) internal pure returns (address result) { result = address(uint160(uint256(_addressBytes32))); } function toAddress(bytes calldata _addressBytes) internal pure returns (address result) { if (_addressBytes.length != 20) revert AddressCast_InvalidAddress(); result = address(bytes20(_addressBytes)); } }
// SPDX-License-Identifier: LZBL-1.2 pragma solidity ^0.8.20; import { Packet } from "../../interfaces/ISendLib.sol"; import { AddressCast } from "../../libs/AddressCast.sol"; library PacketV1Codec { using AddressCast for address; using AddressCast for bytes32; uint8 internal constant PACKET_VERSION = 1; // header (version + nonce + path) // version uint256 private constant PACKET_VERSION_OFFSET = 0; // nonce uint256 private constant NONCE_OFFSET = 1; // path uint256 private constant SRC_EID_OFFSET = 9; uint256 private constant SENDER_OFFSET = 13; uint256 private constant DST_EID_OFFSET = 45; uint256 private constant RECEIVER_OFFSET = 49; // payload (guid + message) uint256 private constant GUID_OFFSET = 81; // keccak256(nonce + path) uint256 private constant MESSAGE_OFFSET = 113; function encode(Packet memory _packet) internal pure returns (bytes memory encodedPacket) { encodedPacket = abi.encodePacked( PACKET_VERSION, _packet.nonce, _packet.srcEid, _packet.sender.toBytes32(), _packet.dstEid, _packet.receiver, _packet.guid, _packet.message ); } function encodePacketHeader(Packet memory _packet) internal pure returns (bytes memory) { return abi.encodePacked( PACKET_VERSION, _packet.nonce, _packet.srcEid, _packet.sender.toBytes32(), _packet.dstEid, _packet.receiver ); } function encodePayload(Packet memory _packet) internal pure returns (bytes memory) { return abi.encodePacked(_packet.guid, _packet.message); } function header(bytes calldata _packet) internal pure returns (bytes calldata) { return _packet[0:GUID_OFFSET]; } function version(bytes calldata _packet) internal pure returns (uint8) { return uint8(bytes1(_packet[PACKET_VERSION_OFFSET:NONCE_OFFSET])); } function nonce(bytes calldata _packet) internal pure returns (uint64) { return uint64(bytes8(_packet[NONCE_OFFSET:SRC_EID_OFFSET])); } function srcEid(bytes calldata _packet) internal pure returns (uint32) { return uint32(bytes4(_packet[SRC_EID_OFFSET:SENDER_OFFSET])); } function sender(bytes calldata _packet) internal pure returns (bytes32) { return bytes32(_packet[SENDER_OFFSET:DST_EID_OFFSET]); } function senderAddressB20(bytes calldata _packet) internal pure returns (address) { return sender(_packet).toAddress(); } function dstEid(bytes calldata _packet) internal pure returns (uint32) { return uint32(bytes4(_packet[DST_EID_OFFSET:RECEIVER_OFFSET])); } function receiver(bytes calldata _packet) internal pure returns (bytes32) { return bytes32(_packet[RECEIVER_OFFSET:GUID_OFFSET]); } function receiverB20(bytes calldata _packet) internal pure returns (address) { return receiver(_packet).toAddress(); } function guid(bytes calldata _packet) internal pure returns (bytes32) { return bytes32(_packet[GUID_OFFSET:MESSAGE_OFFSET]); } function message(bytes calldata _packet) internal pure returns (bytes calldata) { return bytes(_packet[MESSAGE_OFFSET:]); } function payload(bytes calldata _packet) internal pure returns (bytes calldata) { return bytes(_packet[GUID_OFFSET:]); } function payloadHash(bytes calldata _packet) internal pure returns (bytes32) { return keccak256(payload(_packet)); } }
// 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) (interfaces/draft-IERC6093.sol) pragma solidity ^0.8.20; /** * @dev Standard ERC20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "./IERC20.sol"; import {IERC20Metadata} from "./extensions/IERC20Metadata.sol"; import {Context} from "../../utils/Context.sol"; import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. */ abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors { mapping(address account => uint256) private _balances; mapping(address account => mapping(address spender => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the default value returned by this function, unless * it's overridden. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `value`. */ function transfer(address to, uint256 value) public virtual returns (bool) { address owner = _msgSender(); _transfer(owner, to, value); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 value) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, value); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `value`. * - the caller must have allowance for ``from``'s tokens of at least * `value`. */ function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, value); _transfer(from, to, value); return true; } /** * @dev Moves a `value` amount of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _transfer(address from, address to, uint256 value) internal { if (from == address(0)) { revert ERC20InvalidSender(address(0)); } if (to == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(from, to, value); } /** * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from` * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding * this function. * * Emits a {Transfer} event. */ function _update(address from, address to, uint256 value) internal virtual { if (from == address(0)) { // Overflow check required: The rest of the code assumes that totalSupply never overflows _totalSupply += value; } else { uint256 fromBalance = _balances[from]; if (fromBalance < value) { revert ERC20InsufficientBalance(from, fromBalance, value); } unchecked { // Overflow not possible: value <= fromBalance <= totalSupply. _balances[from] = fromBalance - value; } } if (to == address(0)) { unchecked { // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply. _totalSupply -= value; } } else { unchecked { // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256. _balances[to] += value; } } emit Transfer(from, to, value); } /** * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0). * Relies on the `_update` mechanism * * Emits a {Transfer} event with `from` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _mint(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(address(0), account, value); } /** * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply. * Relies on the `_update` mechanism. * * Emits a {Transfer} event with `to` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead */ function _burn(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidSender(address(0)); } _update(account, address(0), value); } /** * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. * * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. */ function _approve(address owner, address spender, uint256 value) internal { _approve(owner, spender, value, true); } /** * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event. * * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any * `Approval` event during `transferFrom` operations. * * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to * true using the following override: * ``` * function _approve(address owner, address spender, uint256 value, bool) internal virtual override { * super._approve(owner, spender, value, true); * } * ``` * * Requirements are the same as {_approve}. */ function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual { if (owner == address(0)) { revert ERC20InvalidApprover(address(0)); } if (spender == address(0)) { revert ERC20InvalidSpender(address(0)); } _allowances[owner][spender] = value; if (emitEvent) { emit Approval(owner, spender, value); } } /** * @dev Updates `owner` s allowance for `spender` based on spent `value`. * * Does not update the allowance value in case of infinite allowance. * Revert if not enough allowance is available. * * Does not emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 value) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { if (currentAllowance < value) { revert ERC20InsufficientAllowance(spender, currentAllowance, value); } unchecked { _approve(owner, spender, currentAllowance - value, false); } } } }
// 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/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.22; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {OFT} from "@layerzerolabs/lz-evm-oapp-v2/contracts/oft/OFT.sol"; /// @dev contract used for Destination chains contract WooTokenOFT is OFT { constructor(string memory _name, string memory _symbol, address _lzEndpoint, address _delegate) OFT(_name, _symbol, _lzEndpoint, _delegate) Ownable(_delegate) {} }
{ "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
[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_lzEndpoint","type":"address"},{"internalType":"address","name":"_delegate","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":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"InvalidDelegate","type":"error"},{"inputs":[],"name":"InvalidEndpointCall","type":"error"},{"inputs":[],"name":"InvalidLocalDecimals","type":"error"},{"inputs":[{"internalType":"bytes","name":"options","type":"bytes"}],"name":"InvalidOptions","type":"error"},{"inputs":[],"name":"LzTokenUnavailable","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"NoPeer","type":"error"},{"inputs":[{"internalType":"uint256","name":"msgValue","type":"uint256"}],"name":"NotEnoughNative","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":[],"name":"OnlySelf","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":"bytes","name":"result","type":"bytes"}],"name":"SimulationResult","type":"error"},{"inputs":[{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"uint256","name":"minAmountLD","type":"uint256"}],"name":"SlippageExceeded","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint16","name":"msgType","type":"uint16"},{"internalType":"bytes","name":"options","type":"bytes"}],"indexed":false,"internalType":"struct EnforcedOptionParam[]","name":"_enforcedOptions","type":"tuple[]"}],"name":"EnforcedOptionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"inspector","type":"address"}],"name":"MsgInspectorSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"guid","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"srcEid","type":"uint32"},{"indexed":true,"internalType":"address","name":"toAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountReceivedLD","type":"uint256"}],"name":"OFTReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"guid","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"dstEid","type":"uint32"},{"indexed":true,"internalType":"address","name":"fromAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountSentLD","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountReceivedLD","type":"uint256"}],"name":"OFTSent","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":"preCrimeAddress","type":"address"}],"name":"PreCrimeSet","type":"event"},{"inputs":[],"name":"SEND","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SEND_AND_CALL","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"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":[],"name":"approvalRequired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"uint16","name":"_msgType","type":"uint16"},{"internalType":"bytes","name":"_extraOptions","type":"bytes"}],"name":"combineOptions","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimalConversionRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endpoint","outputs":[{"internalType":"contract ILayerZeroEndpointV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint16","name":"msgType","type":"uint16"}],"name":"enforcedOptions","outputs":[{"internalType":"bytes","name":"enforcedOption","type":"bytes"}],"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":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"bytes32","name":"_peer","type":"bytes32"}],"name":"isPeer","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":[{"components":[{"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":"uint32","name":"dstEid","type":"uint32"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes32","name":"guid","type":"bytes32"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"address","name":"executor","type":"address"},{"internalType":"bytes","name":"message","type":"bytes"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct InboundPacket[]","name":"_packets","type":"tuple[]"}],"name":"lzReceiveAndRevert","outputs":[],"stateMutability":"payable","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":"lzReceiveSimulate","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"msgInspector","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"oApp","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oAppVersion","outputs":[{"internalType":"uint64","name":"senderVersion","type":"uint64"},{"internalType":"uint64","name":"receiverVersion","type":"uint64"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"oftVersion","outputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"},{"internalType":"uint64","name":"version","type":"uint64"}],"stateMutability":"pure","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":[],"name":"preCrime","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"bytes32","name":"to","type":"bytes32"},{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"uint256","name":"minAmountLD","type":"uint256"},{"internalType":"bytes","name":"extraOptions","type":"bytes"},{"internalType":"bytes","name":"composeMsg","type":"bytes"},{"internalType":"bytes","name":"oftCmd","type":"bytes"}],"internalType":"struct SendParam","name":"_sendParam","type":"tuple"}],"name":"quoteOFT","outputs":[{"components":[{"internalType":"uint256","name":"minAmountLD","type":"uint256"},{"internalType":"uint256","name":"maxAmountLD","type":"uint256"}],"internalType":"struct OFTLimit","name":"oftLimit","type":"tuple"},{"components":[{"internalType":"int256","name":"feeAmountLD","type":"int256"},{"internalType":"string","name":"description","type":"string"}],"internalType":"struct OFTFeeDetail[]","name":"oftFeeDetails","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"amountSentLD","type":"uint256"},{"internalType":"uint256","name":"amountReceivedLD","type":"uint256"}],"internalType":"struct OFTReceipt","name":"oftReceipt","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"bytes32","name":"to","type":"bytes32"},{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"uint256","name":"minAmountLD","type":"uint256"},{"internalType":"bytes","name":"extraOptions","type":"bytes"},{"internalType":"bytes","name":"composeMsg","type":"bytes"},{"internalType":"bytes","name":"oftCmd","type":"bytes"}],"internalType":"struct SendParam","name":"_sendParam","type":"tuple"},{"internalType":"bool","name":"_payInLzToken","type":"bool"}],"name":"quoteSend","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":[{"components":[{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"bytes32","name":"to","type":"bytes32"},{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"uint256","name":"minAmountLD","type":"uint256"},{"internalType":"bytes","name":"extraOptions","type":"bytes"},{"internalType":"bytes","name":"composeMsg","type":"bytes"},{"internalType":"bytes","name":"oftCmd","type":"bytes"}],"internalType":"struct SendParam","name":"_sendParam","type":"tuple"},{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"_fee","type":"tuple"},{"internalType":"address","name":"_refundAddress","type":"address"}],"name":"send","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":"msgReceipt","type":"tuple"},{"components":[{"internalType":"uint256","name":"amountSentLD","type":"uint256"},{"internalType":"uint256","name":"amountReceivedLD","type":"uint256"}],"internalType":"struct OFTReceipt","name":"oftReceipt","type":"tuple"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_delegate","type":"address"}],"name":"setDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint16","name":"msgType","type":"uint16"},{"internalType":"bytes","name":"options","type":"bytes"}],"internalType":"struct EnforcedOptionParam[]","name":"_enforcedOptions","type":"tuple[]"}],"name":"setEnforcedOptions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_msgInspector","type":"address"}],"name":"setMsgInspector","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":"_preCrime","type":"address"}],"name":"setPreCrime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sharedDecimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60e06040523480156200001157600080fd5b5060405162002fb938038062002fb9833981016040819052620000349162000254565b828282826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000076573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009c91906200029e565b8282818181818a6001600160a01b038116620000d257604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b620000dd81620001e2565b506001600160a01b0380831660805281166200010c57604051632d618d8160e21b815260040160405180910390fd5b60805160405163ca5eb5e160e01b81526001600160a01b0383811660048301529091169063ca5eb5e190602401600060405180830381600087803b1580156200015457600080fd5b505af115801562000169573d6000803e3d6000fd5b5050505050505050620001816200023260201b60201c565b60ff168360ff161015620001a8576040516301e9714b60e41b815260040160405180910390fd5b620001b5600684620002e0565b620001c290600a620003ff565b60a0525050506001600160a01b0390921660c05250620004109350505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600690565b80516001600160a01b03811681146200024f57600080fd5b919050565b6000806000606084860312156200026a57600080fd5b620002758462000237565b9250620002856020850162000237565b9150620002956040850162000237565b90509250925092565b600060208284031215620002b157600080fd5b815160ff81168114620002c357600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b60ff8281168282160390811115620002fc57620002fc620002ca565b92915050565b600181815b8085111562000343578160001904821115620003275762000327620002ca565b808516156200033557918102915b93841c939080029062000307565b509250929050565b6000826200035c57506001620002fc565b816200036b57506000620002fc565b81600181146200038457600281146200038f57620003af565b6001915050620002fc565b60ff841115620003a357620003a3620002ca565b50506001821b620002fc565b5060208310610133831016604e8410600b8410161715620003d4575081810a620002fc565b620003e0838362000302565b8060001904821115620003f757620003f7620002ca565b029392505050565b6000620002c360ff8416836200034b565b60805160a05160c051612b256200049460003960008181610669015281816115bf01526117b80152600081816104e2015281816116ff0152818161177b015261186b0152600081816103e40152818161078001528181610e56015281816110c30152818161135101528181611623015281816119a30152611a5c0152612b256000f3fe6080604052600436106101ee5760003560e01c806382413eac1161010d578063bc70b354116100a0578063d045a0dc1161006f578063d045a0dc14610607578063d42438851461061a578063f2fde38b1461063a578063fc0c546a1461065a578063ff7bd03d1461068d57600080fd5b8063bc70b35414610593578063bd815db0146105b3578063c7c7f5b3146105c6578063ca5eb5e1146105e757600080fd5b80639f68b964116100dc5780639f68b96414610512578063b731ea0a14610526578063b98bd07014610546578063bb0b6a531461056657600080fd5b806382413eac14610476578063857749b0146104965780638da5cb5b146104b2578063963efcaa146104d057600080fd5b80633b6f743b116101855780635e280f11116101545780635e280f11146103d25780636fc1b31e14610406578063715018a6146104265780637d25a05e1461043b57600080fd5b80633b6f743b1461031e57806352ae28791461034b5780635535d4611461035e5780635a0dfe4d1461038b57600080fd5b8063156a0d0f116101c1578063156a0d0f146102a057806317442b70146102c75780631f5e1334146102e95780633400288b146102fe57600080fd5b80630d35b415146101f3578063111ecdad1461022b57806313137d6514610263578063134d4f2514610278575b600080fd5b3480156101ff57600080fd5b5061021361020e366004611c80565b6106ad565b60405161022293929190611d04565b60405180910390f35b34801561023757600080fd5b5060045461024b906001600160a01b031681565b6040516001600160a01b039091168152602001610222565b610276610271366004611e0c565b61077e565b005b34801561028457600080fd5b5061028d600281565b60405161ffff9091168152602001610222565b3480156102ac57600080fd5b506040805162b9270b60e21b81526001602082015201610222565b3480156102d357600080fd5b5060408051600181526002602082015201610222565b3480156102f557600080fd5b5061028d600181565b34801561030a57600080fd5b50610276610319366004611ec4565b61083e565b34801561032a57600080fd5b5061033e610339366004611efc565b610854565b6040516102229190611f4d565b34801561035757600080fd5b503061024b565b34801561036a57600080fd5b5061037e610379366004611f76565b6108bd565b6040516102229190611fa9565b34801561039757600080fd5b506103c26103a6366004611ec4565b63ffffffff919091166000908152600160205260409020541490565b6040519015158152602001610222565b3480156103de57600080fd5b5061024b7f000000000000000000000000000000000000000000000000000000000000000081565b34801561041257600080fd5b50610276610421366004611fbc565b610962565b34801561043257600080fd5b506102766109bf565b34801561044757600080fd5b5061045e610456366004611ec4565b600092915050565b6040516001600160401b039091168152602001610222565b34801561048257600080fd5b506103c2610491366004611fd9565b6109d3565b3480156104a257600080fd5b5060405160068152602001610222565b3480156104be57600080fd5b506000546001600160a01b031661024b565b3480156104dc57600080fd5b506105047f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610222565b34801561051e57600080fd5b5060016103c2565b34801561053257600080fd5b5060025461024b906001600160a01b031681565b34801561055257600080fd5b50610276610561366004612083565b6109e8565b34801561057257600080fd5b506105046105813660046120c4565b60016020526000908152604090205481565b34801561059f57600080fd5b5061037e6105ae3660046120df565b610a02565b6102766105c1366004612083565b610baa565b6105d96105d436600461213f565b610d34565b6040516102229291906121ac565b3480156105f357600080fd5b50610276610602366004611fbc565b610e2f565b610276610615366004611e0c565b610eb5565b34801561062657600080fd5b50610276610635366004611fbc565b610ee4565b34801561064657600080fd5b50610276610655366004611fbc565b610f3a565b34801561066657600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061024b565b34801561069957600080fd5b506103c26106a83660046121fe565b610f78565b604080518082019091526000808252602082015260606106e0604051806040016040528060008152602001600081525090565b60408051808201825260008082526001600160401b0360208084018290528451838152908101909452919550918261073b565b6040805180820190915260008152606060208201528152602001906001900390816107135790505b509350600080610760604089013560608a013561075b60208c018c6120c4565b610fae565b60408051808201909152918252602082015296989597505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633146107ce576040516391ac5e4f60e01b81523360048201526024015b60405180910390fd5b602087018035906107e8906107e3908a6120c4565b610ff2565b14610826576107fa60208801886120c4565b60405163309afaf360e21b815263ffffffff9091166004820152602088013560248201526044016107c5565b6108358787878787878761102e565b50505050505050565b610846611195565b61085082826111c2565b5050565b604080518082019091526000808252602082015260006108846040850135606086013561075b60208801886120c4565b9150506000806108948684611217565b90925090506108b16108a960208801886120c4565b83838861133b565b93505050505b92915050565b6003602090815260009283526040808420909152908252902080546108e190612230565b80601f016020809104026020016040519081016040528092919081815260200182805461090d90612230565b801561095a5780601f1061092f5761010080835404028352916020019161095a565b820191906000526020600020905b81548152906001019060200180831161093d57829003601f168201915b505050505081565b61096a611195565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527ff0be4f1e87349231d80c36b33f9e8639658eeaf474014dee15a3e6a4d4414197906020015b60405180910390a150565b6109c7611195565b6109d1600061141c565b565b6001600160a01b03811630145b949350505050565b6109f0611195565b6108506109fd8284612305565b61146c565b63ffffffff8416600090815260036020908152604080832061ffff87168452909152812080546060929190610a3690612230565b80601f0160208091040260200160405190810160405280929190818152602001828054610a6290612230565b8015610aaf5780601f10610a8457610100808354040283529160200191610aaf565b820191906000526020600020905b815481529060010190602001808311610a9257829003601f168201915b505050505090508051600003610aff5783838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509294506109e09350505050565b6000839003610b0f5790506109e0565b60028310610b8d57610b5684848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061157392505050565b80610b64846002818861241a565b604051602001610b7693929190612444565b6040516020818303038152906040529150506109e0565b8383604051639a6d49cd60e01b81526004016107c5929190612495565b60005b81811015610cb35736838383818110610bc857610bc86124a9565b9050602002810190610bda91906124bf565b9050610c0d610bec60208301836120c4565b602083013563ffffffff919091166000908152600160205260409020541490565b610c175750610cab565b3063d045a0dc60c08301358360a0810135610c366101008301836124e0565b610c47610100890160e08a01611fbc565b610c556101208a018a6124e0565b6040518963ffffffff1660e01b8152600401610c77979695949392919061253b565b6000604051808303818588803b158015610c9057600080fd5b505af1158015610ca4573d6000803e3d6000fd5b5050505050505b600101610bad565b50336001600160a01b0316638e9e70996040518163ffffffff1660e01b8152600401600060405180830381865afa158015610cf2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d1a91908101906125c1565b604051638351eea760e01b81526004016107c59190611fa9565b610d3c611c21565b6040805180820190915260008082526020820152600080610d7333604089013560608a0135610d6e60208c018c6120c4565b61159f565b91509150600080610d848984611217565b9092509050610db0610d9960208b018b6120c4565b8383610daa368d90038d018d61262e565b8b6115f0565b60408051808201909152858152602080820186905282519298509096503391907f85496b760a4b7f8d66384b9df21b381f5d1b1e79f229a47aaf4c232edc2fe59a90610dfe908d018d6120c4565b6040805163ffffffff909216825260208201899052810187905260600160405180910390a350505050935093915050565b610e37611195565b60405163ca5eb5e160e01b81526001600160a01b0382811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063ca5eb5e190602401600060405180830381600087803b158015610e9a57600080fd5b505af1158015610eae573d6000803e3d6000fd5b5050505050565b333014610ed55760405163029a949d60e31b815260040160405180910390fd5b61083587878787878787610826565b610eec611195565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527fd48d879cef83a1c0bdda516f27b13ddb1b3f8bbac1c9e1511bb2a659c2427760906020016109b4565b610f42611195565b6001600160a01b038116610f6c57604051631e4fbdf760e01b8152600060048201526024016107c5565b610f758161141c565b50565b6000602082018035906001908390610f9090866120c4565b63ffffffff1681526020810191909152604001600020541492915050565b600080610fba856116fb565b915081905083811015610fea576040516371c4efed60e01b815260048101829052602481018590526044016107c5565b935093915050565b63ffffffff8116600090815260016020526040812054806108b75760405163f6ff4fb760e01b815263ffffffff841660048201526024016107c5565b600061104061103d8787611732565b90565b9050600061106c8261105a6110558a8a611751565b611774565b61106760208d018d6120c4565b6117a9565b905060288611156111335760006110a961108c60608c0160408d01612660565b61109960208d018d6120c4565b846110a48c8c6117e7565b611832565b604051633e5ac80960e11b81529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690637cb59012906110ff9086908d90600090879060040161267d565b600060405180830381600087803b15801561111957600080fd5b505af115801561112d573d6000803e3d6000fd5b50505050505b6001600160a01b038216887fefed6d3500546b29533b128a29e3a94d70788727f0507505ac12eaf2e578fd9c61116c60208d018d6120c4565b6040805163ffffffff9092168252602082018690520160405180910390a3505050505050505050565b6000546001600160a01b031633146109d15760405163118cdaa760e01b81523360048201526024016107c5565b63ffffffff8216600081815260016020908152604091829020849055815192835282018390527f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b910160405180910390a15050565b6060806000611274856020013561122d86611864565b61123a60a08901896124e0565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061189092505050565b909350905060008161128757600161128a565b60025b90506112aa61129c60208801886120c4565b826105ae60808a018a6124e0565b6004549093506001600160a01b031615611332576004805460405163043a78eb60e01b81526001600160a01b039091169163043a78eb916112ef9188918891016126ae565b602060405180830381865afa15801561130c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061133091906126d3565b505b50509250929050565b60408051808201909152600080825260208201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ddc28c586040518060a001604052808863ffffffff16815260200161139e89610ff2565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b81526004016113d39291906126f0565b6040805180830381865afa1580156113ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114139190612799565b95945050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60005b81518110156115435761149e82828151811061148d5761148d6124a9565b602002602001015160400151611573565b8181815181106114b0576114b06124a9565b602002602001015160400151600360008484815181106114d2576114d26124a9565b60200260200101516000015163ffffffff1663ffffffff168152602001908152602001600020600084848151811061150c5761150c6124a9565b60200260200101516020015161ffff1661ffff168152602001908152602001600020908161153a9190612805565b5060010161146f565b507fbe4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b674816040516109b491906128c4565b600281015161ffff81166003146108505781604051639a6d49cd60e01b81526004016107c59190611fa9565b6000806115ad858585610fae565b90925090506115e76001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001687308561190a565b94509492505050565b6115f8611c21565b60006116078460000151611977565b60208501519091501561162157611621846020015161199f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632637a450826040518060a001604052808b63ffffffff1681526020016116718c610ff2565b81526020018a815260200189815260200160008960200151111515815250866040518463ffffffff1660e01b81526004016116ad9291906126f0565b60806040518083038185885af11580156116cb573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906116f0919061294f565b979650505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006117288184612999565b6108b791906129bb565b6000611741602082848661241a565b61174a916129e0565b9392505050565b600061176160286020848661241a565b61176a916129fe565b60c01c9392505050565b60006108b77f00000000000000000000000000000000000000000000000000000000000000006001600160401b0384166129bb565b60006117df6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168585611a81565b509092915050565b60606117f6826028818661241a565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929695505050505050565b60608484848460405160200161184b9493929190612a2e565b6040516020818303038152906040529050949350505050565b60006108b77f000000000000000000000000000000000000000000000000000000000000000083612999565b80516060901515806118d95784846040516020016118c592919091825260c01b6001600160c01b031916602082015260280190565b604051602081830303815290604052611900565b848433856040516020016118f09493929190612a7d565b6040516020818303038152906040525b9150935093915050565b6040516001600160a01b0384811660248301528381166044830152606482018390526119719186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050611ab7565b50505050565b600081341461199b576040516304fb820960e51b81523460048201526024016107c5565b5090565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a239190612ac0565b90506001600160a01b038116611a4c576040516329b99a9560e11b815260040160405180910390fd5b6108506001600160a01b038216337f00000000000000000000000000000000000000000000000000000000000000008561190a565b6040516001600160a01b03838116602483015260448201839052611ab291859182169063a9059cbb9060640161193f565b505050565b6000611acc6001600160a01b03841683611b1a565b90508051600014158015611af1575080806020019051810190611aef91906126d3565b155b15611ab257604051635274afe760e01b81526001600160a01b03841660048201526024016107c5565b606061174a8383600084600080856001600160a01b03168486604051611b409190612add565b60006040518083038185875af1925050503d8060008114611b7d576040519150601f19603f3d011682016040523d82523d6000602084013e611b82565b606091505b5091509150611b92868383611b9c565b9695505050505050565b606082611bb157611bac82611bf8565b61174a565b8151158015611bc857506001600160a01b0384163b155b15611bf157604051639996b31560e01b81526001600160a01b03851660048201526024016107c5565b508061174a565b805115611c085780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b60405180606001604052806000801916815260200160006001600160401b03168152602001611c63604051806040016040528060008152602001600081525090565b905290565b600060e08284031215611c7a57600080fd5b50919050565b600060208284031215611c9257600080fd5b81356001600160401b03811115611ca857600080fd5b6109e084828501611c68565b60005b83811015611ccf578181015183820152602001611cb7565b50506000910152565b60008151808452611cf0816020860160208601611cb4565b601f01601f19169290920160200192915050565b8351815260208085015190820152600060a08201604060a0604085015281865180845260c08601915060c08160051b8701019350602080890160005b83811015611d7f5788870360bf19018552815180518852830151838801879052611d6c87890182611cd8565b9750509382019390820190600101611d40565b505087516060880152505050602085015160808501525090506109e0565b600060608284031215611c7a57600080fd5b60008083601f840112611dc157600080fd5b5081356001600160401b03811115611dd857600080fd5b602083019150836020828501011115611df057600080fd5b9250929050565b6001600160a01b0381168114610f7557600080fd5b600080600080600080600060e0888a031215611e2757600080fd5b611e318989611d9d565b96506060880135955060808801356001600160401b0380821115611e5457600080fd5b611e608b838c01611daf565b909750955060a08a01359150611e7582611df7565b90935060c08901359080821115611e8b57600080fd5b50611e988a828b01611daf565b989b979a50959850939692959293505050565b803563ffffffff81168114611ebf57600080fd5b919050565b60008060408385031215611ed757600080fd5b611ee083611eab565b946020939093013593505050565b8015158114610f7557600080fd5b60008060408385031215611f0f57600080fd5b82356001600160401b03811115611f2557600080fd5b611f3185828601611c68565b9250506020830135611f4281611eee565b809150509250929050565b8151815260208083015190820152604081016108b7565b803561ffff81168114611ebf57600080fd5b60008060408385031215611f8957600080fd5b611f9283611eab565b9150611fa060208401611f64565b90509250929050565b60208152600061174a6020830184611cd8565b600060208284031215611fce57600080fd5b813561174a81611df7565b60008060008060a08587031215611fef57600080fd5b611ff98686611d9d565b935060608501356001600160401b0381111561201457600080fd5b61202087828801611daf565b909450925050608085013561203481611df7565b939692955090935050565b60008083601f84011261205157600080fd5b5081356001600160401b0381111561206857600080fd5b6020830191508360208260051b8501011115611df057600080fd5b6000806020838503121561209657600080fd5b82356001600160401b038111156120ac57600080fd5b6120b88582860161203f565b90969095509350505050565b6000602082840312156120d657600080fd5b61174a82611eab565b600080600080606085870312156120f557600080fd5b6120fe85611eab565b935061210c60208601611f64565b925060408501356001600160401b0381111561212757600080fd5b61213387828801611daf565b95989497509550505050565b6000806000838503608081121561215557600080fd5b84356001600160401b0381111561216b57600080fd5b61217787828801611c68565b9450506040601f198201121561218c57600080fd5b5060208401915060608401356121a181611df7565b809150509250925092565b600060c082019050835182526001600160401b03602085015116602083015260408401516121e7604084018280518252602090810151910152565b5082516080830152602083015160a083015261174a565b60006060828403121561221057600080fd5b61174a8383611d9d565b634e487b7160e01b600052604160045260246000fd5b600181811c9082168061224457607f821691505b602082108103611c7a57634e487b7160e01b600052602260045260246000fd5b604051606081016001600160401b03811182821017156122865761228661221a565b60405290565b604080519081016001600160401b03811182821017156122865761228661221a565b604051601f8201601f191681016001600160401b03811182821017156122d6576122d661221a565b604052919050565b60006001600160401b038211156122f7576122f761221a565b50601f01601f191660200190565b60006001600160401b038084111561231f5761231f61221a565b8360051b60206123308183016122ae565b86815291850191818101903684111561234857600080fd5b865b8481101561240e578035868111156123625760008081fd5b880160603682900312156123765760008081fd5b61237e612264565b61238782611eab565b8152612394868301611f64565b86820152604080830135898111156123ac5760008081fd5b929092019136601f8401126123c15760008081fd5b82356123d46123cf826122de565b6122ae565b81815236898387010111156123e95760008081fd5b818986018a83013760009181018901919091529082015284525091830191830161234a565b50979650505050505050565b6000808585111561242a57600080fd5b8386111561243757600080fd5b5050820193919092039150565b60008451612456818460208901611cb4565b8201838582376000930192835250909392505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6020815260006109e060208301848661246c565b634e487b7160e01b600052603260045260246000fd5b6000823561013e198336030181126124d657600080fd5b9190910192915050565b6000808335601e198436030181126124f757600080fd5b8301803591506001600160401b0382111561251157600080fd5b602001915036819003821315611df057600080fd5b6001600160401b0381168114610f7557600080fd5b63ffffffff61254989611eab565b168152602088013560208201526000604089013561256681612526565b6001600160401b03811660408401525087606083015260e0608083015261259160e08301878961246c565b6001600160a01b03861660a084015282810360c08401526125b381858761246c565b9a9950505050505050505050565b6000602082840312156125d357600080fd5b81516001600160401b038111156125e957600080fd5b8201601f810184136125fa57600080fd5b80516126086123cf826122de565b81815285602083850101111561261d57600080fd5b611413826020830160208601611cb4565b60006040828403121561264057600080fd5b61264861228c565b82358152602083013560208201528091505092915050565b60006020828403121561267257600080fd5b813561174a81612526565b60018060a01b038516815283602082015261ffff83166040820152608060608201526000611b926080830184611cd8565b6040815260006126c16040830185611cd8565b82810360208401526114138185611cd8565b6000602082840312156126e557600080fd5b815161174a81611eee565b6040815263ffffffff8351166040820152602083015160608201526000604084015160a0608084015261272660e0840182611cd8565b90506060850151603f198483030160a08501526127438282611cd8565b60809690960151151560c08501525050506001600160a01b039190911660209091015290565b60006040828403121561277b57600080fd5b61278361228c565b9050815181526020820151602082015292915050565b6000604082840312156127ab57600080fd5b61174a8383612769565b601f821115611ab2576000816000526020600020601f850160051c810160208610156127de5750805b601f850160051c820191505b818110156127fd578281556001016127ea565b505050505050565b81516001600160401b0381111561281e5761281e61221a565b6128328161282c8454612230565b846127b5565b602080601f831160018114612867576000841561284f5750858301515b600019600386901b1c1916600185901b1785556127fd565b600085815260208120601f198616915b8281101561289657888601518255948401946001909101908401612877565b50858210156128b45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b8381101561294157888303603f190185528151805163ffffffff1684528781015161ffff1688850152860151606087850181905261292d81860183611cd8565b9689019694505050908601906001016128ed565b509098975050505050505050565b60006080828403121561296157600080fd5b612969612264565b82518152602083015161297b81612526565b602082015261298d8460408501612769565b60408201529392505050565b6000826129b657634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176108b757634e487b7160e01b600052601160045260246000fd5b803560208310156108b757600019602084900360031b1b1692915050565b6001600160c01b03198135818116916008851015612a265780818660080360031b1b83161692505b505092915050565b6001600160401b0360c01b8560c01b16815263ffffffff60e01b8460e01b16600882015282600c82015260008251612a6d81602c850160208701611cb4565b91909101602c0195945050505050565b8481526001600160401b0360c01b8460c01b16602082015282602882015260008251612ab0816048850160208701611cb4565b9190910160480195945050505050565b600060208284031215612ad257600080fd5b815161174a81611df7565b600082516124d6818460208701611cb456fea26469706673582212203ca2d3dcb375f0cfde542247a24413e11061896e5c0b5c77ecc7972b9910e91f64736f6c634300081600330000000000000000000000004691937a7508860f876c9c0a2a617e7d9e945d4b0000000000000000000000001a44076050125825900e736c501f859c50fe728c0000000000000000000000005373ce2eb223b80efd0326f7090b31f534cdc0a4
Deployed Bytecode
0x6080604052600436106101ee5760003560e01c806382413eac1161010d578063bc70b354116100a0578063d045a0dc1161006f578063d045a0dc14610607578063d42438851461061a578063f2fde38b1461063a578063fc0c546a1461065a578063ff7bd03d1461068d57600080fd5b8063bc70b35414610593578063bd815db0146105b3578063c7c7f5b3146105c6578063ca5eb5e1146105e757600080fd5b80639f68b964116100dc5780639f68b96414610512578063b731ea0a14610526578063b98bd07014610546578063bb0b6a531461056657600080fd5b806382413eac14610476578063857749b0146104965780638da5cb5b146104b2578063963efcaa146104d057600080fd5b80633b6f743b116101855780635e280f11116101545780635e280f11146103d25780636fc1b31e14610406578063715018a6146104265780637d25a05e1461043b57600080fd5b80633b6f743b1461031e57806352ae28791461034b5780635535d4611461035e5780635a0dfe4d1461038b57600080fd5b8063156a0d0f116101c1578063156a0d0f146102a057806317442b70146102c75780631f5e1334146102e95780633400288b146102fe57600080fd5b80630d35b415146101f3578063111ecdad1461022b57806313137d6514610263578063134d4f2514610278575b600080fd5b3480156101ff57600080fd5b5061021361020e366004611c80565b6106ad565b60405161022293929190611d04565b60405180910390f35b34801561023757600080fd5b5060045461024b906001600160a01b031681565b6040516001600160a01b039091168152602001610222565b610276610271366004611e0c565b61077e565b005b34801561028457600080fd5b5061028d600281565b60405161ffff9091168152602001610222565b3480156102ac57600080fd5b506040805162b9270b60e21b81526001602082015201610222565b3480156102d357600080fd5b5060408051600181526002602082015201610222565b3480156102f557600080fd5b5061028d600181565b34801561030a57600080fd5b50610276610319366004611ec4565b61083e565b34801561032a57600080fd5b5061033e610339366004611efc565b610854565b6040516102229190611f4d565b34801561035757600080fd5b503061024b565b34801561036a57600080fd5b5061037e610379366004611f76565b6108bd565b6040516102229190611fa9565b34801561039757600080fd5b506103c26103a6366004611ec4565b63ffffffff919091166000908152600160205260409020541490565b6040519015158152602001610222565b3480156103de57600080fd5b5061024b7f0000000000000000000000001a44076050125825900e736c501f859c50fe728c81565b34801561041257600080fd5b50610276610421366004611fbc565b610962565b34801561043257600080fd5b506102766109bf565b34801561044757600080fd5b5061045e610456366004611ec4565b600092915050565b6040516001600160401b039091168152602001610222565b34801561048257600080fd5b506103c2610491366004611fd9565b6109d3565b3480156104a257600080fd5b5060405160068152602001610222565b3480156104be57600080fd5b506000546001600160a01b031661024b565b3480156104dc57600080fd5b506105047f000000000000000000000000000000000000000000000000000000e8d4a5100081565b604051908152602001610222565b34801561051e57600080fd5b5060016103c2565b34801561053257600080fd5b5060025461024b906001600160a01b031681565b34801561055257600080fd5b50610276610561366004612083565b6109e8565b34801561057257600080fd5b506105046105813660046120c4565b60016020526000908152604090205481565b34801561059f57600080fd5b5061037e6105ae3660046120df565b610a02565b6102766105c1366004612083565b610baa565b6105d96105d436600461213f565b610d34565b6040516102229291906121ac565b3480156105f357600080fd5b50610276610602366004611fbc565b610e2f565b610276610615366004611e0c565b610eb5565b34801561062657600080fd5b50610276610635366004611fbc565b610ee4565b34801561064657600080fd5b50610276610655366004611fbc565b610f3a565b34801561066657600080fd5b507f0000000000000000000000004691937a7508860f876c9c0a2a617e7d9e945d4b61024b565b34801561069957600080fd5b506103c26106a83660046121fe565b610f78565b604080518082019091526000808252602082015260606106e0604051806040016040528060008152602001600081525090565b60408051808201825260008082526001600160401b0360208084018290528451838152908101909452919550918261073b565b6040805180820190915260008152606060208201528152602001906001900390816107135790505b509350600080610760604089013560608a013561075b60208c018c6120c4565b610fae565b60408051808201909152918252602082015296989597505050505050565b7f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b031633146107ce576040516391ac5e4f60e01b81523360048201526024015b60405180910390fd5b602087018035906107e8906107e3908a6120c4565b610ff2565b14610826576107fa60208801886120c4565b60405163309afaf360e21b815263ffffffff9091166004820152602088013560248201526044016107c5565b6108358787878787878761102e565b50505050505050565b610846611195565b61085082826111c2565b5050565b604080518082019091526000808252602082015260006108846040850135606086013561075b60208801886120c4565b9150506000806108948684611217565b90925090506108b16108a960208801886120c4565b83838861133b565b93505050505b92915050565b6003602090815260009283526040808420909152908252902080546108e190612230565b80601f016020809104026020016040519081016040528092919081815260200182805461090d90612230565b801561095a5780601f1061092f5761010080835404028352916020019161095a565b820191906000526020600020905b81548152906001019060200180831161093d57829003601f168201915b505050505081565b61096a611195565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527ff0be4f1e87349231d80c36b33f9e8639658eeaf474014dee15a3e6a4d4414197906020015b60405180910390a150565b6109c7611195565b6109d1600061141c565b565b6001600160a01b03811630145b949350505050565b6109f0611195565b6108506109fd8284612305565b61146c565b63ffffffff8416600090815260036020908152604080832061ffff87168452909152812080546060929190610a3690612230565b80601f0160208091040260200160405190810160405280929190818152602001828054610a6290612230565b8015610aaf5780601f10610a8457610100808354040283529160200191610aaf565b820191906000526020600020905b815481529060010190602001808311610a9257829003601f168201915b505050505090508051600003610aff5783838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509294506109e09350505050565b6000839003610b0f5790506109e0565b60028310610b8d57610b5684848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061157392505050565b80610b64846002818861241a565b604051602001610b7693929190612444565b6040516020818303038152906040529150506109e0565b8383604051639a6d49cd60e01b81526004016107c5929190612495565b60005b81811015610cb35736838383818110610bc857610bc86124a9565b9050602002810190610bda91906124bf565b9050610c0d610bec60208301836120c4565b602083013563ffffffff919091166000908152600160205260409020541490565b610c175750610cab565b3063d045a0dc60c08301358360a0810135610c366101008301836124e0565b610c47610100890160e08a01611fbc565b610c556101208a018a6124e0565b6040518963ffffffff1660e01b8152600401610c77979695949392919061253b565b6000604051808303818588803b158015610c9057600080fd5b505af1158015610ca4573d6000803e3d6000fd5b5050505050505b600101610bad565b50336001600160a01b0316638e9e70996040518163ffffffff1660e01b8152600401600060405180830381865afa158015610cf2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d1a91908101906125c1565b604051638351eea760e01b81526004016107c59190611fa9565b610d3c611c21565b6040805180820190915260008082526020820152600080610d7333604089013560608a0135610d6e60208c018c6120c4565b61159f565b91509150600080610d848984611217565b9092509050610db0610d9960208b018b6120c4565b8383610daa368d90038d018d61262e565b8b6115f0565b60408051808201909152858152602080820186905282519298509096503391907f85496b760a4b7f8d66384b9df21b381f5d1b1e79f229a47aaf4c232edc2fe59a90610dfe908d018d6120c4565b6040805163ffffffff909216825260208201899052810187905260600160405180910390a350505050935093915050565b610e37611195565b60405163ca5eb5e160e01b81526001600160a01b0382811660048301527f0000000000000000000000001a44076050125825900e736c501f859c50fe728c169063ca5eb5e190602401600060405180830381600087803b158015610e9a57600080fd5b505af1158015610eae573d6000803e3d6000fd5b5050505050565b333014610ed55760405163029a949d60e31b815260040160405180910390fd5b61083587878787878787610826565b610eec611195565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527fd48d879cef83a1c0bdda516f27b13ddb1b3f8bbac1c9e1511bb2a659c2427760906020016109b4565b610f42611195565b6001600160a01b038116610f6c57604051631e4fbdf760e01b8152600060048201526024016107c5565b610f758161141c565b50565b6000602082018035906001908390610f9090866120c4565b63ffffffff1681526020810191909152604001600020541492915050565b600080610fba856116fb565b915081905083811015610fea576040516371c4efed60e01b815260048101829052602481018590526044016107c5565b935093915050565b63ffffffff8116600090815260016020526040812054806108b75760405163f6ff4fb760e01b815263ffffffff841660048201526024016107c5565b600061104061103d8787611732565b90565b9050600061106c8261105a6110558a8a611751565b611774565b61106760208d018d6120c4565b6117a9565b905060288611156111335760006110a961108c60608c0160408d01612660565b61109960208d018d6120c4565b846110a48c8c6117e7565b611832565b604051633e5ac80960e11b81529091506001600160a01b037f0000000000000000000000001a44076050125825900e736c501f859c50fe728c1690637cb59012906110ff9086908d90600090879060040161267d565b600060405180830381600087803b15801561111957600080fd5b505af115801561112d573d6000803e3d6000fd5b50505050505b6001600160a01b038216887fefed6d3500546b29533b128a29e3a94d70788727f0507505ac12eaf2e578fd9c61116c60208d018d6120c4565b6040805163ffffffff9092168252602082018690520160405180910390a3505050505050505050565b6000546001600160a01b031633146109d15760405163118cdaa760e01b81523360048201526024016107c5565b63ffffffff8216600081815260016020908152604091829020849055815192835282018390527f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b910160405180910390a15050565b6060806000611274856020013561122d86611864565b61123a60a08901896124e0565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061189092505050565b909350905060008161128757600161128a565b60025b90506112aa61129c60208801886120c4565b826105ae60808a018a6124e0565b6004549093506001600160a01b031615611332576004805460405163043a78eb60e01b81526001600160a01b039091169163043a78eb916112ef9188918891016126ae565b602060405180830381865afa15801561130c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061133091906126d3565b505b50509250929050565b60408051808201909152600080825260208201527f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b031663ddc28c586040518060a001604052808863ffffffff16815260200161139e89610ff2565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b81526004016113d39291906126f0565b6040805180830381865afa1580156113ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114139190612799565b95945050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60005b81518110156115435761149e82828151811061148d5761148d6124a9565b602002602001015160400151611573565b8181815181106114b0576114b06124a9565b602002602001015160400151600360008484815181106114d2576114d26124a9565b60200260200101516000015163ffffffff1663ffffffff168152602001908152602001600020600084848151811061150c5761150c6124a9565b60200260200101516020015161ffff1661ffff168152602001908152602001600020908161153a9190612805565b5060010161146f565b507fbe4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b674816040516109b491906128c4565b600281015161ffff81166003146108505781604051639a6d49cd60e01b81526004016107c59190611fa9565b6000806115ad858585610fae565b90925090506115e76001600160a01b037f0000000000000000000000004691937a7508860f876c9c0a2a617e7d9e945d4b1687308561190a565b94509492505050565b6115f8611c21565b60006116078460000151611977565b60208501519091501561162157611621846020015161199f565b7f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b0316632637a450826040518060a001604052808b63ffffffff1681526020016116718c610ff2565b81526020018a815260200189815260200160008960200151111515815250866040518463ffffffff1660e01b81526004016116ad9291906126f0565b60806040518083038185885af11580156116cb573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906116f0919061294f565b979650505050505050565b60007f000000000000000000000000000000000000000000000000000000e8d4a510006117288184612999565b6108b791906129bb565b6000611741602082848661241a565b61174a916129e0565b9392505050565b600061176160286020848661241a565b61176a916129fe565b60c01c9392505050565b60006108b77f000000000000000000000000000000000000000000000000000000e8d4a510006001600160401b0384166129bb565b60006117df6001600160a01b037f0000000000000000000000004691937a7508860f876c9c0a2a617e7d9e945d4b168585611a81565b509092915050565b60606117f6826028818661241a565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929695505050505050565b60608484848460405160200161184b9493929190612a2e565b6040516020818303038152906040529050949350505050565b60006108b77f000000000000000000000000000000000000000000000000000000e8d4a5100083612999565b80516060901515806118d95784846040516020016118c592919091825260c01b6001600160c01b031916602082015260280190565b604051602081830303815290604052611900565b848433856040516020016118f09493929190612a7d565b6040516020818303038152906040525b9150935093915050565b6040516001600160a01b0384811660248301528381166044830152606482018390526119719186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050611ab7565b50505050565b600081341461199b576040516304fb820960e51b81523460048201526024016107c5565b5090565b60007f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b031663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a239190612ac0565b90506001600160a01b038116611a4c576040516329b99a9560e11b815260040160405180910390fd5b6108506001600160a01b038216337f0000000000000000000000001a44076050125825900e736c501f859c50fe728c8561190a565b6040516001600160a01b03838116602483015260448201839052611ab291859182169063a9059cbb9060640161193f565b505050565b6000611acc6001600160a01b03841683611b1a565b90508051600014158015611af1575080806020019051810190611aef91906126d3565b155b15611ab257604051635274afe760e01b81526001600160a01b03841660048201526024016107c5565b606061174a8383600084600080856001600160a01b03168486604051611b409190612add565b60006040518083038185875af1925050503d8060008114611b7d576040519150601f19603f3d011682016040523d82523d6000602084013e611b82565b606091505b5091509150611b92868383611b9c565b9695505050505050565b606082611bb157611bac82611bf8565b61174a565b8151158015611bc857506001600160a01b0384163b155b15611bf157604051639996b31560e01b81526001600160a01b03851660048201526024016107c5565b508061174a565b805115611c085780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b60405180606001604052806000801916815260200160006001600160401b03168152602001611c63604051806040016040528060008152602001600081525090565b905290565b600060e08284031215611c7a57600080fd5b50919050565b600060208284031215611c9257600080fd5b81356001600160401b03811115611ca857600080fd5b6109e084828501611c68565b60005b83811015611ccf578181015183820152602001611cb7565b50506000910152565b60008151808452611cf0816020860160208601611cb4565b601f01601f19169290920160200192915050565b8351815260208085015190820152600060a08201604060a0604085015281865180845260c08601915060c08160051b8701019350602080890160005b83811015611d7f5788870360bf19018552815180518852830151838801879052611d6c87890182611cd8565b9750509382019390820190600101611d40565b505087516060880152505050602085015160808501525090506109e0565b600060608284031215611c7a57600080fd5b60008083601f840112611dc157600080fd5b5081356001600160401b03811115611dd857600080fd5b602083019150836020828501011115611df057600080fd5b9250929050565b6001600160a01b0381168114610f7557600080fd5b600080600080600080600060e0888a031215611e2757600080fd5b611e318989611d9d565b96506060880135955060808801356001600160401b0380821115611e5457600080fd5b611e608b838c01611daf565b909750955060a08a01359150611e7582611df7565b90935060c08901359080821115611e8b57600080fd5b50611e988a828b01611daf565b989b979a50959850939692959293505050565b803563ffffffff81168114611ebf57600080fd5b919050565b60008060408385031215611ed757600080fd5b611ee083611eab565b946020939093013593505050565b8015158114610f7557600080fd5b60008060408385031215611f0f57600080fd5b82356001600160401b03811115611f2557600080fd5b611f3185828601611c68565b9250506020830135611f4281611eee565b809150509250929050565b8151815260208083015190820152604081016108b7565b803561ffff81168114611ebf57600080fd5b60008060408385031215611f8957600080fd5b611f9283611eab565b9150611fa060208401611f64565b90509250929050565b60208152600061174a6020830184611cd8565b600060208284031215611fce57600080fd5b813561174a81611df7565b60008060008060a08587031215611fef57600080fd5b611ff98686611d9d565b935060608501356001600160401b0381111561201457600080fd5b61202087828801611daf565b909450925050608085013561203481611df7565b939692955090935050565b60008083601f84011261205157600080fd5b5081356001600160401b0381111561206857600080fd5b6020830191508360208260051b8501011115611df057600080fd5b6000806020838503121561209657600080fd5b82356001600160401b038111156120ac57600080fd5b6120b88582860161203f565b90969095509350505050565b6000602082840312156120d657600080fd5b61174a82611eab565b600080600080606085870312156120f557600080fd5b6120fe85611eab565b935061210c60208601611f64565b925060408501356001600160401b0381111561212757600080fd5b61213387828801611daf565b95989497509550505050565b6000806000838503608081121561215557600080fd5b84356001600160401b0381111561216b57600080fd5b61217787828801611c68565b9450506040601f198201121561218c57600080fd5b5060208401915060608401356121a181611df7565b809150509250925092565b600060c082019050835182526001600160401b03602085015116602083015260408401516121e7604084018280518252602090810151910152565b5082516080830152602083015160a083015261174a565b60006060828403121561221057600080fd5b61174a8383611d9d565b634e487b7160e01b600052604160045260246000fd5b600181811c9082168061224457607f821691505b602082108103611c7a57634e487b7160e01b600052602260045260246000fd5b604051606081016001600160401b03811182821017156122865761228661221a565b60405290565b604080519081016001600160401b03811182821017156122865761228661221a565b604051601f8201601f191681016001600160401b03811182821017156122d6576122d661221a565b604052919050565b60006001600160401b038211156122f7576122f761221a565b50601f01601f191660200190565b60006001600160401b038084111561231f5761231f61221a565b8360051b60206123308183016122ae565b86815291850191818101903684111561234857600080fd5b865b8481101561240e578035868111156123625760008081fd5b880160603682900312156123765760008081fd5b61237e612264565b61238782611eab565b8152612394868301611f64565b86820152604080830135898111156123ac5760008081fd5b929092019136601f8401126123c15760008081fd5b82356123d46123cf826122de565b6122ae565b81815236898387010111156123e95760008081fd5b818986018a83013760009181018901919091529082015284525091830191830161234a565b50979650505050505050565b6000808585111561242a57600080fd5b8386111561243757600080fd5b5050820193919092039150565b60008451612456818460208901611cb4565b8201838582376000930192835250909392505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6020815260006109e060208301848661246c565b634e487b7160e01b600052603260045260246000fd5b6000823561013e198336030181126124d657600080fd5b9190910192915050565b6000808335601e198436030181126124f757600080fd5b8301803591506001600160401b0382111561251157600080fd5b602001915036819003821315611df057600080fd5b6001600160401b0381168114610f7557600080fd5b63ffffffff61254989611eab565b168152602088013560208201526000604089013561256681612526565b6001600160401b03811660408401525087606083015260e0608083015261259160e08301878961246c565b6001600160a01b03861660a084015282810360c08401526125b381858761246c565b9a9950505050505050505050565b6000602082840312156125d357600080fd5b81516001600160401b038111156125e957600080fd5b8201601f810184136125fa57600080fd5b80516126086123cf826122de565b81815285602083850101111561261d57600080fd5b611413826020830160208601611cb4565b60006040828403121561264057600080fd5b61264861228c565b82358152602083013560208201528091505092915050565b60006020828403121561267257600080fd5b813561174a81612526565b60018060a01b038516815283602082015261ffff83166040820152608060608201526000611b926080830184611cd8565b6040815260006126c16040830185611cd8565b82810360208401526114138185611cd8565b6000602082840312156126e557600080fd5b815161174a81611eee565b6040815263ffffffff8351166040820152602083015160608201526000604084015160a0608084015261272660e0840182611cd8565b90506060850151603f198483030160a08501526127438282611cd8565b60809690960151151560c08501525050506001600160a01b039190911660209091015290565b60006040828403121561277b57600080fd5b61278361228c565b9050815181526020820151602082015292915050565b6000604082840312156127ab57600080fd5b61174a8383612769565b601f821115611ab2576000816000526020600020601f850160051c810160208610156127de5750805b601f850160051c820191505b818110156127fd578281556001016127ea565b505050505050565b81516001600160401b0381111561281e5761281e61221a565b6128328161282c8454612230565b846127b5565b602080601f831160018114612867576000841561284f5750858301515b600019600386901b1c1916600185901b1785556127fd565b600085815260208120601f198616915b8281101561289657888601518255948401946001909101908401612877565b50858210156128b45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b8381101561294157888303603f190185528151805163ffffffff1684528781015161ffff1688850152860151606087850181905261292d81860183611cd8565b9689019694505050908601906001016128ed565b509098975050505050505050565b60006080828403121561296157600080fd5b612969612264565b82518152602083015161297b81612526565b602082015261298d8460408501612769565b60408201529392505050565b6000826129b657634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176108b757634e487b7160e01b600052601160045260246000fd5b803560208310156108b757600019602084900360031b1b1692915050565b6001600160c01b03198135818116916008851015612a265780818660080360031b1b83161692505b505092915050565b6001600160401b0360c01b8560c01b16815263ffffffff60e01b8460e01b16600882015282600c82015260008251612a6d81602c850160208701611cb4565b91909101602c0195945050505050565b8481526001600160401b0360c01b8460c01b16602082015282602882015260008251612ab0816048850160208701611cb4565b9190910160480195945050505050565b600060208284031215612ad257600080fd5b815161174a81611df7565b600082516124d6818460208701611cb456fea26469706673582212203ca2d3dcb375f0cfde542247a24413e11061896e5c0b5c77ecc7972b9910e91f64736f6c63430008160033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000004691937a7508860f876c9c0a2a617e7d9e945d4b0000000000000000000000001a44076050125825900e736c501f859c50fe728c0000000000000000000000005373ce2eb223b80efd0326f7090b31f534cdc0a4
-----Decoded View---------------
Arg [0] : _token (address): 0x4691937a7508860F876c9c0a2a617E7d9E945D4B
Arg [1] : _lzEndpoint (address): 0x1a44076050125825900e736c501f859c50fE728c
Arg [2] : _delegate (address): 0x5373CE2Eb223b80eFD0326f7090B31F534Cdc0a4
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000004691937a7508860f876c9c0a2a617e7d9e945d4b
Arg [1] : 0000000000000000000000001a44076050125825900e736c501f859c50fe728c
Arg [2] : 0000000000000000000000005373ce2eb223b80efd0326f7090b31f534cdc0a4
Deployed Bytecode Sourcemap
289:202:40:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4928:1258:11;;;;;;;;;;-1:-1:-1;4928:1258:11;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;2132:27;;;;;;;;;;-1:-1:-1;2132:27:11;;;;-1:-1:-1;;;;;2132:27:11;;;;;;-1:-1:-1;;;;;2732:32:41;;;2714:51;;2702:2;2687:18;2132:27:11;2568:203:41;4368:708:2;;;;;;:::i;:::-;;:::i;:::-;;2006:40:11;;;;;;;;;;;;2045:1;2006:40;;;;;4650:6:41;4638:19;;;4620:38;;4608:2;4593:18;2006:40:11;4476:188:41;3277:140:11;;;;;;;;;;-1:-1:-1;3277:140:11;;;-1:-1:-1;;;4839:52:41;;3408:1:11;4922:2:41;4907:18;;4900:59;4812:18;3277:140:11;4669:296:41;1287:235:0;;;;;;;;;;-1:-1:-1;1287:235:0;;;843:1:3;5177:34:41;;678:1:2;5242:2:41;5227:18;;5220:43;5113:18;1287:235:0;4970:299:41;1969:31:11;;;;;;;;;;;;1999:1;1969:31;;1724:108:1;;;;;;;;;;-1:-1:-1;1724:108:1;;;;;:::i;:::-;;:::i;6637:774:11:-;;;;;;;;;;-1:-1:-1;6637:774:11;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;875:93:15:-;;;;;;;;;;-1:-1:-1;956:4:15;875:93;;538::8;;;;;;;;;;-1:-1:-1;538:93:8;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;14792:132:11:-;;;;;;;;;;-1:-1:-1;14792:132:11;;;;;:::i;:::-;14897:11;;;;;14874:4;14897:11;;;:5;:11;;;;;;:20;;14792:132;;;;7391:14:41;;7384:22;7366:41;;7354:2;7339:18;14792:132:11;7226:187:41;446:46:1;;;;;;;;;;;;;;;4459:163:11;;;;;;;;;;-1:-1:-1;4459:163:11;;;;;:::i;:::-;;:::i;2293:101:29:-;;;;;;;;;;;;;:::i;3507:128:2:-;;;;;;;;;;-1:-1:-1;3507:128:2;;;;;:::i;:::-;3596:12;3507:128;;;;;;;;-1:-1:-1;;;;;8069:31:41;;;8051:50;;8039:2;8024:18;3507:128:2;7907:200:41;2013:216:2;;;;;;;;;;-1:-1:-1;2013:216:2;;;;;:::i;:::-;;:::i;4024:87:11:-;;;;;;;;;;-1:-1:-1;4024:87:11;;4103:1;8929:36:41;;8917:2;8902:18;4024:87:11;8787:184:41;1638:85:29;;;;;;;;;;-1:-1:-1;1684:7:29;1710:6;-1:-1:-1;;;;;1710:6:29;1638:85;;1663:46:11;;;;;;;;;;;;;;;;;;9122:25:41;;;9110:2;9095:18;1663:46:11;8976:177:41;2358:93:10;;;;;;;;;;-1:-1:-1;2440:4:10;2358:93;;559:23:15;;;;;;;;;;-1:-1:-1;559:23:15;;;;-1:-1:-1;;;;;559:23:15;;;1391:156:8;;;;;;;;;;-1:-1:-1;1391:156:8;;;;;:::i;:::-;;:::i;569:48:1:-;;;;;;;;;;-1:-1:-1;569:48:1;;;;;:::i;:::-;;;;;;;;;;;;;;3510:981:8;;;;;;;;;;-1:-1:-1;3510:981:8;;;;;:::i;:::-;;:::i;1698:1333:15:-;;;;;;:::i;:::-;;:::i;8099:1340:11:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;3252:105:1:-;;;;;;;;;;-1:-1:-1;3252:105:1;;;;;:::i;:::-;;:::i;3679:409:15:-;;;;;;:::i;:::-;;:::i;1100:139::-;;;;;;;;;;-1:-1:-1;1100:139:15;;;;;:::i;:::-;;:::i;2543:215:29:-;;;;;;;;;;-1:-1:-1;2543:215:29;;;;;:::i;:::-;;:::i;1867:90:10:-;;;;;;;;;;-1:-1:-1;1939:10:10;1867:90;;2771:149:2;;;;;;;;;;-1:-1:-1;2771:149:2;;;;;:::i;:::-;;:::i;4928:1258:11:-;-1:-1:-1;;;;;;;;;;;;;;;;;5080:35:11;5117:28;-1:-1:-1;;;;;;;;;;;;;;;;;;;5117:28:11;5335:34;;;;;;;;-1:-1:-1;5335:34:11;;;-1:-1:-1;;;;;5335:34:11;;;;;;;5486:21;;;;;;;;;;;5335:34;;-1:-1:-1;;;5486:21:11;;;-1:-1:-1;;;;;;;;;;;;;;;;;5486:21:11;;;;;;;;;;;;;;;-1:-1:-1;5470:37:11;-1:-1:-1;5944:20:11;;5994:120;6018:19;;;;6051:22;;;;6087:17;;;;6018:10;6087:17;:::i;:::-;5994:10;:120::i;:::-;6137:42;;;;;;;;;;;;;;;;4928:1258;;;;-1:-1:-1;;;;;;4928:1258:11:o;4368:708:2:-;4681:8;-1:-1:-1;;;;;4673:31:2;4694:10;4673:31;4669:68;;4713:24;;-1:-1:-1;;;4713:24:2;;4726:10;4713:24;;;2714:51:41;2687:18;;4713:24:2;;;;;;;;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:2;;13353:10:41;13341:23;;;4896:40:2;;;13323:42:41;4921:14:2;;;;13381:18:41;;;13374:34;13296:18;;4896:40:2;13151:263:41;4833:103:2;5010:59;5021:7;5030:5;5037:8;;5047:9;5058:10;;5010;:59::i;:::-;4368:708;;;;;;;:::o;1724:108:1:-;1531:13:29;:11;:13::i;:::-;1804:21:1::1;1813:4;1819:5;1804:8;:21::i;:::-;1724:108:::0;;:::o;6637:774:11:-;-1:-1:-1;;;;;;;;;;;;;;;;;6971:24:11;6999:74;7010:19;;;;7031:22;;;;7055:17;;;;7010:10;7055:17;:::i;6999:74::-;6968:105;;;7162:20;7184;7208:49;7228:10;7240:16;7208:19;:49::i;:::-;7161:96;;-1:-1:-1;7161:96:11;-1:-1:-1;7346:58:11;7353:17;;;;:10;:17;:::i;:::-;7372:7;7381;7390:13;7346:6;:58::i;:::-;7339:65;;;;;6637:774;;;;;:::o;538:93:8:-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;4459:163:11:-;1531:13:29;:11;:13::i;:::-;4542:12:11::1;:28:::0;;-1:-1:-1;;;;;;4542:28:11::1;-1:-1:-1::0;;;;;4542:28:11;::::1;::::0;;::::1;::::0;;;4585:30:::1;::::0;2714:51:41;;;4585:30:11::1;::::0;2702:2:41;2687:18;4585:30:11::1;;;;;;;;4459:163:::0;:::o;2293:101:29:-;1531:13;:11;:13::i;:::-;2357:30:::1;2384:1;2357:18;:30::i;:::-;2293:101::o:0;2013:216:2:-;-1:-1:-1;;;;;2198:24:2;;2217:4;2198:24;2013:216;;;;;;;:::o;1391:156:8:-;1531:13:29;:11;:13::i;:::-;1503:37:8::1;;1523:16:::0;;1503:37:::1;:::i;:::-;:19;:37::i;3510:981::-:0;3701:21;;;3677;3701;;;:15;:21;;;;;;;;:31;;;;;;;;;;3677:55;;3653:12;;3677:21;3701:31;3677:55;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3861:8;:15;3880:1;3861:20;3857:46;;3890:13;;3883:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3883:20:8;;-1:-1:-1;3883:20:8;;-1:-1:-1;;;;3883:20:8;3857:46;3988:1;3964:25;;;3960:46;;3998:8;-1:-1:-1;3991:15:8;;3960:46;4153:1;4129:25;;4125:267;;4170:34;4190:13;;4170:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4170:19:8;;-1:-1:-1;;;4170:34:8:i;:::-;4353:8;4363:17;:13;4377:1;4363:13;;:17;:::i;:::-;4340:41;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;4333:48;;;;;4125:267;4470:13;;4455:29;;-1:-1:-1;;;4455:29:8;;;;;;;;;:::i;1698:1333:15:-;1799:9;1794:1037;1814:19;;;1794:1037;;;1854:29;1886:8;;1895:1;1886:11;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;1854:43;-1:-1:-1;1980:50:15;1987:20;;;;1854:43;1987:20;:::i;:::-;2009;;;;14897:11:11;;;;;14874:4;14897:11;;;:5;:11;;;;;;:20;;14792:132;1980:50:15;1975:65;;2032:8;;;1975:65;2602:4;:22;2633:12;;;;:6;2696:11;;;;2725:14;;;;2633:6;2725:14;:::i;:::-;2757:15;;;;;;;;:::i;:::-;2790:16;;;;:6;:16;:::i;:::-;2602:218;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1840:991;1794:1037;1835:3;;1794:1037;;;;2988:10;-1:-1:-1;;;;;2978:43:15;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;2978:45:15;;;;;;;;;;;;:::i;:::-;2961:63;;-1:-1:-1;;;2961:63:15;;;;;;;;:::i;8099:1340:11:-;8260:34;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;8658:20:11;;8708:140;8728:10;8752:19;;;;8785:22;;;;8821:17;;;;8752:10;8821:17;:::i;:::-;8708:6;:140::i;:::-;8657:191;;;;8937:20;8959;8983:49;9003:10;9015:16;8983:19;:49::i;:::-;8936:96;;-1:-1:-1;8936:96:11;-1:-1:-1;9155:66:11;9163:17;;;;:10;:17;:::i;:::-;9182:7;9191;9155:66;;;;;;;9200:4;9155:66;:::i;:::-;9206:14;9155:7;:66::i;:::-;9287:42;;;;;;;;;;;;;;;;;;;9353:15;;9142:79;;-1:-1:-1;9287:42:11;;-1:-1:-1;9389:10:11;;9353:15;9345:87;;9370:17;;;;:10;:17;:::i;:::-;9345:87;;;21606:10:41;21594:23;;;21576:42;;21649:2;21634:18;;21627:34;;;21677:18;;21670:34;;;21564:2;21549:18;9345:87:11;;;;;;;8326:1113;;;;8099:1340;;;;;;:::o;3252:105:1:-;1531:13:29;:11;:13::i;:::-;3319:31:1::1;::::0;-1:-1:-1;;;3319:31:1;;-1:-1:-1;;;;;2732:32:41;;;3319:31:1::1;::::0;::::1;2714:51:41::0;3319:8:1::1;:20;::::0;::::1;::::0;2687:18:41;;3319:31:1::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;3252:105:::0;:::o;3679:409:15:-;3958:10;3980:4;3958:27;3954:50;;3994:10;;-1:-1:-1;;;3994:10:15;;;;;;;;;;;3954:50;4014:67;4033:7;4042:5;4049:8;;4059:9;4070:10;;4014:18;:67::i;1100:139::-;1531:13:29;:11;:13::i;:::-;1175:8:15::1;:20:::0;;-1:-1:-1;;;;;;1175:20:15::1;-1:-1:-1::0;;;;;1175:20:15;::::1;::::0;;::::1;::::0;;;1210:22:::1;::::0;2714:51:41;;;1210:22:15::1;::::0;2702:2:41;2687:18;1210:22:15::1;2568:203:41::0;2543:215:29;1531:13;:11;:13::i;:::-;-1:-1:-1;;;;;2627:22:29;::::1;2623:91;;2672:31;::::0;-1:-1:-1;;;2672:31:29;;2700:1:::1;2672:31;::::0;::::1;2714:51:41::0;2687:18;;2672:31:29::1;2568:203:41::0;2623:91:29::1;2723:28;2742:8;2723:18;:28::i;:::-;2543:215:::0;:::o;2771:149:2:-;2853:4;2900:13;;;;;;2876:5;;2853:4;;2882:13;;2900:6;2882:13;:::i;:::-;2876:20;;;;;;;;;;;;;-1:-1:-1;2876:20:2;;:37;;2771:149;-1:-1:-1;;2771:149:2:o;16809:668:11:-;16951:20;16973:24;17147:22;17159:9;17147:11;:22::i;:::-;17132:37;;17295:12;17276:31;;17377:12;17358:16;:31;17354:117;;;17412:48;;-1:-1:-1;;;17412:48:11;;;;;21889:25:41;;;21930:18;;;21923:34;;;21862:18;;17412:48:11;21715:248:41;17354:117:11;16809:668;;;;;;:::o;2718:196:1:-;2822:11;;;2788:7;2822:11;;;:5;:11;;;;;;;2843:43;;2874:12;;-1:-1:-1;;;2874:12:1;;22142:10:41;22130:23;;2874:12:1;;;22112:42:41;22085:18;;2874:12:1;21968:192:41;11585:1806:11;12062:17;12082:36;:17;:8;;:15;:17::i;:::-;2891:2:14;2780:123;12082:36:11;12062:56;;12251:24;12278:62;12286:9;12297:26;12303:19;:8;;:17;:19::i;:::-;12297:5;:26::i;:::-;12325:14;;;;:7;:14;:::i;:::-;12278:7;:62::i;:::-;12251:89;-1:-1:-1;243:2:14;-1:-1:-1;;12351:955:11;;;12455:23;12481:175;12524:13;;;;;;;;:::i;:::-;12555:14;;;;:7;:14;:::i;:::-;12587:16;12621:21;:8;;:19;:21::i;:::-;12481:25;:175::i;:::-;13203:92;;-1:-1:-1;;;13203:92:11;;12455:201;;-1:-1:-1;;;;;;13203:8:11;:20;;;;:92;;13224:9;;13235:5;;13242:1;;12455:201;;13203:92;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12378:928;12351:955;-1:-1:-1;;;;;13321:63:11;;13333:5;13321:63;13340:14;;;;:7;:14;:::i;:::-;13321:63;;;13353:10:41;13341:23;;;13323:42;;13396:2;13381:18;;13374:34;;;13296:18;13321:63:11;;;;;;;11888:1503;;11585:1806;;;;;;;:::o;1796:162:29:-;1684:7;1710:6;-1:-1:-1;;;;;1710:6:29;735:10:37;1855:23:29;1851:101;;1901:40;;-1:-1:-1;;;1901:40:29;;735:10:37;1901:40:29;;;2714:51:41;2687:18;;1901:40:29;2568:203:41;2286:134:1;2359:11;;;;;;;:5;:11;;;;;;;;;:19;;;2393:20;;13323:42:41;;;13381:18;;13374:34;;;2393:20:1;;13296:18:41;2393:20:1;;;;;;;2286:134;;:::o;9733:1334:11:-;9865:20;9887;9919:15;10090:324;10122:10;:13;;;10149:16;10155:9;10149:5;:16::i;:::-;10383:21;;;;:10;:21;:::i;:::-;10090:324;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10090:18:11;;-1:-1:-1;;;10090:324:11:i;:::-;10066:348;;-1:-1:-1;10066:348:11;-1:-1:-1;10494:14:11;10066:348;10511:33;;1999:1;10511:33;;;2045:1;10511:33;10494:50;-1:-1:-1;10666:67:11;10681:17;;;;:10;:17;:::i;:::-;10700:7;10709:23;;;;:10;:23;:::i;10666:67::-;10975:12;;10656:77;;-1:-1:-1;;;;;;10975:12:11;:26;10971:89;;11021:12;;;11003:57;;-1:-1:-1;;;11003:57:11;;-1:-1:-1;;;;;11021:12:11;;;;11003:39;;:57;;11043:7;;11052;;11003:57;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;10971:89;9909:1158;;9733:1334;;;;;:::o;2038:391:3:-;-1:-1:-1;;;;;;;;;;;;;;;;;2259:8:3;-1:-1:-1;;;;;2259:14:3;;2291:86;;;;;;;;2307:7;2291:86;;;;;;2316:25;2333:7;2316:16;:25::i;:::-;2291:86;;;;2343:8;2291:86;;;;2353:8;2291:86;;;;2363:13;2291:86;;;;;2403:4;2259:163;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2240:182;2038:391;-1:-1:-1;;;;;2038:391:3:o;2912:187:29:-;2985:16;3004:6;;-1:-1:-1;;;;;3020:17:29;;;-1:-1:-1;;;;;;3020:17:29;;;;;;3052:40;;3004:6;;;;;;;3052:40;;2985:16;3052:40;2975:124;2912:187;:::o;2237:514:8:-;2345:9;2340:354;2364:16;:23;2360:1;:27;2340:354;;;2522:48;2542:16;2559:1;2542:19;;;;;;;;:::i;:::-;;;;;;;:27;;;2522:19;:48::i;:::-;2656:16;2673:1;2656:19;;;;;;;;:::i;:::-;;;;;;;:27;;;2584:15;:40;2600:16;2617:1;2600:19;;;;;;;;:::i;:::-;;;;;;;:23;;;2584:40;;;;;;;;;;;;;;;:69;2625:16;2642:1;2625:19;;;;;;;;:::i;:::-;;;;;;;:27;;;2584:69;;;;;;;;;;;;;;;:99;;;;;;:::i;:::-;-1:-1:-1;2389:3:8;;2340:354;;;;2709:35;2727:16;2709:35;;;;;;:::i;4631:264::-;4801:1;4787:16;;4781:23;4827:28;;;463:1;4827:28;4823:65;;4879:8;4864:24;;-1:-1:-1;;;4864:24:8;;;;;;;;:::i;3352:457:10:-;3513:20;3535:24;3606:44;3617:9;3628:12;3642:7;3606:10;:44::i;:::-;3571:79;;-1:-1:-1;3571:79:10;-1:-1:-1;3739:63:10;-1:-1:-1;;;;;3739:10:10;:27;3767:5;3782:4;3571:79;3739:27;:63::i;:::-;3352:457;;;;;;;:::o;3188:766:3:-;3389:31;;:::i;:::-;3554:20;3577:26;3588:4;:14;;;3577:10;:26::i;:::-;3617:15;;;;3554:49;;-1:-1:-1;3617:19:3;3613:53;;3638:28;3650:4;:15;;;3638:11;:28::i;:::-;3755:8;-1:-1:-1;;;;;3755:13:3;;3777:12;3809:92;;;;;;;;3825:7;3809:92;;;;;;3834:25;3851:7;3834:16;:25::i;:::-;3809:92;;;;3861:8;3809:92;;;;3871:8;3809:92;;;;3899:1;3881:4;:15;;;:19;3809:92;;;;;3919:14;3755:192;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3677:270;3188:766;-1:-1:-1;;;;;;;3188:766:3:o;15318:172:11:-;15389:16;15462:21;15425:33;15462:21;15425:9;:33;:::i;:::-;15424:59;;;;:::i;1573:123:14:-;1633:7;1667:21;188:2;1633:7;1667:4;;:21;:::i;:::-;1659:30;;;:::i;:::-;1652:37;1573:123;-1:-1:-1;;;1573:123:14:o;1874:152::-;1936:6;1975:42;243:2;188;1975:4;;:42;:::i;:::-;1968:50;;;:::i;:::-;1961:58;;;1874:152;-1:-1:-1;;;1874:152:14:o;15714:139:11:-;15778:16;15813:33;15825:21;-1:-1:-1;;;;;15813:33:11;;;:::i;4450:409:10:-;4584:24;4685:39;-1:-1:-1;;;;;4685:10:10;:23;4709:3;4714:9;4685:23;:39::i;:::-;-1:-1:-1;4843:9:10;;4450:409;-1:-1:-1;;4450:409:10:o;2186:130:14:-;2250:12;2281:28;:4;243:2;2281:4;;:28;:::i;:::-;2274:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2274:35:14;;2186:130;-1:-1:-1;;;;;;2186:130:14:o;640:284:13:-;824:17;877:6;885:7;894:9;905:11;860:57;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;853:64;;640:284;;;;;;:::o;16077:147:11:-;16142:15;16183:33;16195:21;16183:9;:33;:::i;598:506:14:-;791:18;;732:17;;791:22;;;934:163;;1074:7;1083:13;1057:40;;;;;;;;30952:19:41;;;31027:3;31005:16;-1:-1:-1;;;;;;31001:51:41;30996:2;30987:12;;30980:73;31078:2;31069:12;;30797:290;1057:40:14;;;;;;;;;;;;;934:163;;;976:7;985:13;1017:10;1030:11;959:83;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;934:163;927:170;;598:506;;;;;;:::o;1702:188:35:-;1829:53;;-1:-1:-1;;;;;31887:15:41;;;1829:53:35;;;31869:34:41;31939:15;;;31919:18;;;31912:43;31971:18;;;31964:34;;;1802:81:35;;1822:5;;1844:18;;;;;31804::41;;1829:53:35;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1829:53:35;;;;;;;;;;;1802:19;:81::i;:::-;1702:188;;;;:::o;4650:191:3:-;4716:17;4762:10;4749:9;:23;4745:62;;4781:26;;-1:-1:-1;;;4781:26:3;;4797:9;4781:26;;;9122:25:41;9095:18;;4781:26:3;8976:177:41;4745:62:3;-1:-1:-1;4824:10:3;4650:191::o;5218:410::-;5371:15;5389:8;-1:-1:-1;;;;;5389:16:3;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5371:36;-1:-1:-1;;;;;;5421:21:3;;5417:54;;5451:20;;-1:-1:-1;;;5451:20:3;;;;;;;;;;;5417:54;5545:76;-1:-1:-1;;;;;5545:32:3;;5578:10;5598:8;5609:11;5545:32;:76::i;1303:160:35:-;1412:43;;-1:-1:-1;;;;;32457:32:41;;;1412:43:35;;;32439:51:41;32506:18;;;32499:34;;;1385:71:35;;1405:5;;1427:14;;;;;32412:18:41;;1412:43:35;32265:274:41;1385:71:35;1303:160;;;:::o;4059:629::-;4478:23;4504:33;-1:-1:-1;;;;;4504:27:35;;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:35;;-1:-1:-1;;;;;2732:32:41;;4631:40:35;;;2714:51:41;2687:18;;4631:40:35;2568:203:41;2705:151:36;2780:12;2811:38;2833:6;2841:4;2847:1;2780:12;3421;3435:23;3462:6;-1:-1:-1;;;;;3462:11:36;3481:5;3488:4;3462:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3420:73;;;;3510:55;3537:6;3545:7;3554:10;3510:26;:55::i;:::-;3503:62;3180:392;-1:-1:-1;;;;;;3180:392:36:o;4625:582::-;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:36;;;:23;5045:49;5041:119;;;5121:24;;-1:-1:-1;;;5121:24:36;;-1:-1:-1;;;;;2732:32:41;;5121:24:36;;;2714:51:41;2687:18;;5121:24:36;2568:203:41;5041:119:36;-1:-1:-1;5180:10:36;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:36;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:158:41:-;76:5;121:3;112:6;107:3;103:16;99:26;96:46;;;138:1;135;128:12;96:46;-1:-1:-1;160:6:41;14:158;-1:-1:-1;14:158:41:o;177:360::-;265:6;318:2;306:9;297:7;293:23;289:32;286:52;;;334:1;331;324:12;286:52;374:9;361:23;-1:-1:-1;;;;;399:6:41;396:30;393:50;;;439:1;436;429:12;393:50;462:69;523:7;514:6;503:9;499:22;462:69;:::i;696:250::-;781:1;791:113;805:6;802:1;799:13;791:113;;;881:11;;;875:18;862:11;;;855:39;827:2;820:10;791:113;;;-1:-1:-1;;938:1:41;920:16;;913:27;696:250::o;951:271::-;993:3;1031:5;1025:12;1058:6;1053:3;1046:19;1074:76;1143:6;1136:4;1131:3;1127:14;1120:4;1113:5;1109:16;1074:76;:::i;:::-;1204:2;1183:15;-1:-1:-1;;1179:29:41;1170:39;;;;1211:4;1166:50;;951:271;-1:-1:-1;;951:271:41:o;1227:1336::-;616:12;;604:25;;678:4;667:16;;;661:23;645:14;;;638:47;1593:4;1641:3;1626:19;;1718:2;1756:3;1751:2;1740:9;1736:18;1729:31;1780:6;1815;1809:13;1846:6;1838;1831:22;1884:3;1873:9;1869:19;1862:26;;1947:3;1937:6;1934:1;1930:14;1919:9;1915:30;1911:40;1897:54;;1970:4;2009;2001:6;1997:17;2032:1;2042:429;2056:6;2053:1;2050:13;2042:429;;;2121:22;;;-1:-1:-1;;2117:37:41;2105:50;;2178:13;;2219:9;;2204:25;;2268:11;;2262:18;2300:15;;;2293:27;;;2343:48;2375:15;;;2262:18;2343:48;:::i;:::-;2333:58;-1:-1:-1;;2449:12:41;;;;2414:15;;;;2078:1;2071:9;2042:429;;;-1:-1:-1;;616:12:41;;2553:2;2538:18;;604:25;-1:-1:-1;;;678:4:41;667:16;;661:23;645:14;;;638:47;-1:-1:-1;2488:6:41;-1:-1:-1;2503:54:41;542:149;2776:154;2835:5;2880:2;2871:6;2866:3;2862:16;2858:25;2855:45;;;2896:1;2893;2886:12;2935:347;2986:8;2996:6;3050:3;3043:4;3035:6;3031:17;3027:27;3017:55;;3068:1;3065;3058:12;3017:55;-1:-1:-1;3091:20:41;;-1:-1:-1;;;;;3123:30:41;;3120:50;;;3166:1;3163;3156:12;3120:50;3203:4;3195:6;3191:17;3179:29;;3255:3;3248:4;3239:6;3231;3227:19;3223:30;3220:39;3217:59;;;3272:1;3269;3262:12;3217:59;2935:347;;;;;:::o;3287:131::-;-1:-1:-1;;;;;3362:31:41;;3352:42;;3342:70;;3408:1;3405;3398:12;3423:1048;3566:6;3574;3582;3590;3598;3606;3614;3667:3;3655:9;3646:7;3642:23;3638:33;3635:53;;;3684:1;3681;3674:12;3635:53;3707;3752:7;3741:9;3707:53;:::i;:::-;3697:63;;3807:2;3796:9;3792:18;3779:32;3769:42;;3862:3;3851:9;3847:19;3834:33;-1:-1:-1;;;;;3927:2:41;3919:6;3916:14;3913:34;;;3943:1;3940;3933:12;3913:34;3982:58;4032:7;4023:6;4012:9;4008:22;3982:58;:::i;:::-;4059:8;;-1:-1:-1;3956:84:41;-1:-1:-1;4144:3:41;4129:19;;4116:33;;-1:-1:-1;4158:31:41;4116:33;4158:31;:::i;:::-;4208:5;;-1:-1:-1;4266:3:41;4251:19;;4238:33;;4283:16;;;4280:36;;;4312:1;4309;4302:12;4280:36;;4351:60;4403:7;4392:8;4381:9;4377:24;4351:60;:::i;:::-;3423:1048;;;;-1:-1:-1;3423:1048:41;;-1:-1:-1;3423:1048:41;;;;4325:86;;-1:-1:-1;;;3423:1048:41:o;5274:163::-;5341:20;;5401:10;5390:22;;5380:33;;5370:61;;5427:1;5424;5417:12;5370:61;5274:163;;;:::o;5442:252::-;5509:6;5517;5570:2;5558:9;5549:7;5545:23;5541:32;5538:52;;;5586:1;5583;5576:12;5538:52;5609:28;5627:9;5609:28;:::i;:::-;5599:38;5684:2;5669:18;;;;5656:32;;-1:-1:-1;;;5442:252:41:o;5699:118::-;5785:5;5778:13;5771:21;5764:5;5761:32;5751:60;;5807:1;5804;5797:12;5822:489;5916:6;5924;5977:2;5965:9;5956:7;5952:23;5948:32;5945:52;;;5993:1;5990;5983:12;5945:52;6033:9;6020:23;-1:-1:-1;;;;;6058:6:41;6055:30;6052:50;;;6098:1;6095;6088:12;6052:50;6121:69;6182:7;6173:6;6162:9;6158:22;6121:69;:::i;:::-;6111:79;;;6240:2;6229:9;6225:18;6212:32;6253:28;6275:5;6253:28;:::i;:::-;6300:5;6290:15;;;5822:489;;;;;:::o;6316:257::-;616:12;;604:25;;678:4;667:16;;;661:23;645:14;;;638:47;6510:2;6495:18;;6522:45;542:149;6578:159;6645:20;;6705:6;6694:18;;6684:29;;6674:57;;6727:1;6724;6717:12;6742:256;6808:6;6816;6869:2;6857:9;6848:7;6844:23;6840:32;6837:52;;;6885:1;6882;6875:12;6837:52;6908:28;6926:9;6908:28;:::i;:::-;6898:38;;6955:37;6988:2;6977:9;6973:18;6955:37;:::i;:::-;6945:47;;6742:256;;;;;:::o;7003:218::-;7150:2;7139:9;7132:21;7113:4;7170:45;7211:2;7200:9;7196:18;7188:6;7170:45;:::i;7655:247::-;7714:6;7767:2;7755:9;7746:7;7742:23;7738:32;7735:52;;;7783:1;7780;7773:12;7735:52;7822:9;7809:23;7841:31;7866:5;7841:31;:::i;8112:670::-;8226:6;8234;8242;8250;8303:3;8291:9;8282:7;8278:23;8274:33;8271:53;;;8320:1;8317;8310:12;8271:53;8343;8388:7;8377:9;8343:53;:::i;:::-;8333:63;;8447:2;8436:9;8432:18;8419:32;-1:-1:-1;;;;;8466:6:41;8463:30;8460:50;;;8506:1;8503;8496:12;8460:50;8545:58;8595:7;8586:6;8575:9;8571:22;8545:58;:::i;:::-;8622:8;;-1:-1:-1;8519:84:41;-1:-1:-1;;8707:3:41;8692:19;;8679:33;8721:31;8679:33;8721:31;:::i;:::-;8112:670;;;;-1:-1:-1;8112:670:41;;-1:-1:-1;;8112:670:41:o;9158:395::-;9249:8;9259:6;9313:3;9306:4;9298:6;9294:17;9290:27;9280:55;;9331:1;9328;9321:12;9280:55;-1:-1:-1;9354:20:41;;-1:-1:-1;;;;;9386:30:41;;9383:50;;;9429:1;9426;9419:12;9383:50;9466:4;9458:6;9454:17;9442:29;;9526:3;9519:4;9509:6;9506:1;9502:14;9494:6;9490:27;9486:38;9483:47;9480:67;;;9543:1;9540;9533:12;9558:503;9682:6;9690;9743:2;9731:9;9722:7;9718:23;9714:32;9711:52;;;9759:1;9756;9749:12;9711:52;9799:9;9786:23;-1:-1:-1;;;;;9824:6:41;9821:30;9818:50;;;9864:1;9861;9854:12;9818:50;9903:98;9993:7;9984:6;9973:9;9969:22;9903:98;:::i;:::-;10020:8;;9877:124;;-1:-1:-1;9558:503:41;-1:-1:-1;;;;9558:503:41:o;10066:184::-;10124:6;10177:2;10165:9;10156:7;10152:23;10148:32;10145:52;;;10193:1;10190;10183:12;10145:52;10216:28;10234:9;10216:28;:::i;10437:553::-;10523:6;10531;10539;10547;10600:2;10588:9;10579:7;10575:23;10571:32;10568:52;;;10616:1;10613;10606:12;10568:52;10639:28;10657:9;10639:28;:::i;:::-;10629:38;;10686:37;10719:2;10708:9;10704:18;10686:37;:::i;:::-;10676:47;;10774:2;10763:9;10759:18;10746:32;-1:-1:-1;;;;;10793:6:41;10790:30;10787:50;;;10833:1;10830;10823:12;10787:50;10872:58;10922:7;10913:6;10902:9;10898:22;10872:58;:::i;:::-;10437:553;;;;-1:-1:-1;10949:8:41;-1:-1:-1;;;;10437:553:41:o;11498:657::-;11636:6;11644;11652;11696:9;11687:7;11683:23;11726:3;11722:2;11718:12;11715:32;;;11743:1;11740;11733:12;11715:32;11783:9;11770:23;-1:-1:-1;;;;;11808:6:41;11805:30;11802:50;;;11848:1;11845;11838:12;11802:50;11871:69;11932:7;11923:6;11912:9;11908:22;11871:69;:::i;:::-;11861:79;-1:-1:-1;;11974:2:41;-1:-1:-1;;11956:16:41;;11952:25;11949:45;;;11990:1;11987;11980:12;11949:45;;12028:2;12017:9;12013:18;12003:28;;12081:2;12070:9;12066:18;12053:32;12094:31;12119:5;12094:31;:::i;:::-;12144:5;12134:15;;;11498:657;;;;;:::o;12160:613::-;12404:4;12446:3;12435:9;12431:19;12423:27;;12483:6;12477:13;12466:9;12459:32;-1:-1:-1;;;;;12551:4:41;12543:6;12539:17;12533:24;12529:49;12522:4;12511:9;12507:20;12500:79;12626:4;12618:6;12614:17;12608:24;12641:62;12697:4;12686:9;12682:20;12668:12;616;;604:25;;678:4;667:16;;;661:23;645:14;;638:47;542:149;12641:62;-1:-1:-1;616:12:41;;12762:3;12747:19;;604:25;678:4;667:16;;661:23;645:14;;;638:47;12712:55;542:149;12778:236;12863:6;12916:2;12904:9;12895:7;12891:23;12887:32;12884:52;;;12932:1;12929;12922:12;12884:52;12955:53;13000:7;12989:9;12955:53;:::i;13019:127::-;13080:10;13075:3;13071:20;13068:1;13061:31;13111:4;13108:1;13101:15;13135:4;13132:1;13125:15;13419:380;13498:1;13494:12;;;;13541;;;13562:61;;13616:4;13608:6;13604:17;13594:27;;13562:61;13669:2;13661:6;13658:14;13638:18;13635:38;13632:161;;13715:10;13710:3;13706:20;13703:1;13696:31;13750:4;13747:1;13740:15;13778:4;13775:1;13768:15;13804:253;13876:2;13870:9;13918:4;13906:17;;-1:-1:-1;;;;;13938:34:41;;13974:22;;;13935:62;13932:88;;;14000:18;;:::i;:::-;14036:2;14029:22;13804:253;:::o;14062:251::-;14134:2;14128:9;;;14164:15;;-1:-1:-1;;;;;14194:34:41;;14230:22;;;14191:62;14188:88;;;14256:18;;:::i;14318:275::-;14389:2;14383:9;14454:2;14435:13;;-1:-1:-1;;14431:27:41;14419:40;;-1:-1:-1;;;;;14474:34:41;;14510:22;;;14471:62;14468:88;;;14536:18;;:::i;:::-;14572:2;14565:22;14318:275;;-1:-1:-1;14318:275:41:o;14598:186::-;14646:4;-1:-1:-1;;;;;14671:6:41;14668:30;14665:56;;;14701:18;;:::i;:::-;-1:-1:-1;14767:2:41;14746:15;-1:-1:-1;;14742:29:41;14773:4;14738:40;;14598:186::o;14789:2115::-;14979:9;-1:-1:-1;;;;;15054:2:41;15046:6;15043:14;15040:40;;;15060:18;;:::i;:::-;15106:6;15103:1;15099:14;15132:4;15156:28;15180:2;15176;15172:11;15156:28;:::i;:::-;15218:19;;;15288:14;;;;15253:12;;;;15325:14;15314:26;;15311:46;;;15353:1;15350;15343:12;15311:46;15377:5;15391:1480;15407:6;15402:3;15399:15;15391:1480;;;15493:3;15480:17;15529:2;15516:11;15513:19;15510:109;;;15573:1;15602:2;15598;15591:14;15510:109;15642:23;;15710:4;15689:14;15685:23;;;15681:34;15678:124;;;15756:1;15785:2;15781;15774:14;15678:124;15830:22;;:::i;:::-;15881:21;15899:2;15881:21;:::i;:::-;15872:7;15865:38;15941:30;15967:2;15963;15959:11;15941:30;:::i;:::-;15936:2;15927:7;15923:16;15916:56;15995:2;16045;16041;16037:11;16024:25;16076:2;16068:6;16065:14;16062:104;;;16120:1;16149:2;16145;16138:14;16062:104;16189:15;;;;;16246:14;16239:4;16231:13;;16227:34;16217:135;;16304:1;16334:3;16329;16322:16;16217:135;16389:2;16376:16;16418:49;16434:32;16462:3;16434:32;:::i;:::-;16418:49;:::i;:::-;16494:3;16487:5;16480:18;16540:14;16535:2;16529:3;16525:2;16521:12;16517:21;16514:41;16511:134;;;16597:1;16627:3;16622;16615:16;16511:134;16700:3;16695:2;16691;16687:11;16682:2;16675:5;16671:14;16658:46;16750:1;16728:15;;;16724:24;;16717:35;;;;16772:16;;;16765:31;16809:20;;-1:-1:-1;16849:12:41;;;;15424;;15391:1480;;;-1:-1:-1;16893:5:41;14789:2115;-1:-1:-1;;;;;;;14789:2115:41:o;16909:331::-;17014:9;17025;17067:8;17055:10;17052:24;17049:44;;;17089:1;17086;17079:12;17049:44;17118:6;17108:8;17105:20;17102:40;;;17138:1;17135;17128:12;17102:40;-1:-1:-1;;17164:23:41;;;17209:25;;;;;-1:-1:-1;16909:331:41:o;17245:476::-;17436:3;17474:6;17468:13;17490:66;17549:6;17544:3;17537:4;17529:6;17525:17;17490:66;:::i;:::-;17578:16;;17631:6;17623;17578:16;17603:35;17695:1;17657:18;;17684:13;;;-1:-1:-1;17657:18:41;;17245:476;-1:-1:-1;;;17245:476:41:o;17726:266::-;17814:6;17809:3;17802:19;17866:6;17859:5;17852:4;17847:3;17843:14;17830:43;-1:-1:-1;17918:1:41;17893:16;;;17911:4;17889:27;;;17882:38;;;;17974:2;17953:15;;;-1:-1:-1;;17949:29:41;17940:39;;;17936:50;;17726:266::o;17997:244::-;18154:2;18143:9;18136:21;18117:4;18174:61;18231:2;18220:9;18216:18;18208:6;18200;18174:61;:::i;18246:127::-;18307:10;18302:3;18298:20;18295:1;18288:31;18338:4;18335:1;18328:15;18362:4;18359:1;18352:15;18378:331;18477:4;18535:11;18522:25;18629:3;18625:8;18614;18598:14;18594:29;18590:44;18570:18;18566:69;18556:97;;18649:1;18646;18639:12;18556:97;18670:33;;;;;18378:331;-1:-1:-1;;18378:331:41:o;18714:521::-;18791:4;18797:6;18857:11;18844:25;18951:2;18947:7;18936:8;18920:14;18916:29;18912:43;18892:18;18888:68;18878:96;;18970:1;18967;18960:12;18878:96;18997:33;;19049:20;;;-1:-1:-1;;;;;;19081:30:41;;19078:50;;;19124:1;19121;19114:12;19078:50;19157:4;19145:17;;-1:-1:-1;19188:14:41;19184:27;;;19174:38;;19171:58;;;19225:1;19222;19215:12;19240:129;-1:-1:-1;;;;;19318:5:41;19314:30;19307:5;19304:41;19294:69;;19359:1;19356;19349:12;19374:992;19752:10;19725:25;19743:6;19725:25;:::i;:::-;19721:42;19710:9;19703:61;19827:4;19819:6;19815:17;19802:31;19795:4;19784:9;19780:20;19773:61;19684:4;19881;19873:6;19869:17;19856:31;19896:30;19920:5;19896:30;:::i;:::-;-1:-1:-1;;;;;19968:5:41;19964:30;19957:4;19946:9;19942:20;19935:60;;20031:6;20026:2;20015:9;20011:18;20004:34;20075:3;20069;20058:9;20054:19;20047:32;20102:62;20159:3;20148:9;20144:19;20136:6;20128;20102:62;:::i;:::-;-1:-1:-1;;;;;20201:32:41;;20221:3;20180:19;;20173:61;20271:22;;;20265:3;20250:19;;20243:51;20311:49;20275:6;20345;20337;20311:49;:::i;:::-;20303:57;19374:992;-1:-1:-1;;;;;;;;;;19374:992:41:o;20371:647::-;20450:6;20503:2;20491:9;20482:7;20478:23;20474:32;20471:52;;;20519:1;20516;20509:12;20471:52;20552:9;20546:16;-1:-1:-1;;;;;20577:6:41;20574:30;20571:50;;;20617:1;20614;20607:12;20571:50;20640:22;;20693:4;20685:13;;20681:27;-1:-1:-1;20671:55:41;;20722:1;20719;20712:12;20671:55;20751:2;20745:9;20776:48;20792:31;20820:2;20792:31;:::i;20776:48::-;20847:2;20840:5;20833:17;20887:7;20882:2;20877;20873;20869:11;20865:20;20862:33;20859:53;;;20908:1;20905;20898:12;20859:53;20921:67;20985:2;20980;20973:5;20969:14;20964:2;20960;20956:11;20921:67;:::i;21023:348::-;21112:6;21165:2;21153:9;21144:7;21140:23;21136:32;21133:52;;;21181:1;21178;21171:12;21133:52;21207:22;;:::i;:::-;21265:9;21252:23;21245:5;21238:38;21336:2;21325:9;21321:18;21308:32;21303:2;21296:5;21292:14;21285:56;21360:5;21350:15;;;21023:348;;;;:::o;22165:245::-;22223:6;22276:2;22264:9;22255:7;22251:23;22247:32;22244:52;;;22292:1;22289;22282:12;22244:52;22331:9;22318:23;22350:30;22374:5;22350:30;:::i;22415:479::-;22682:1;22678;22673:3;22669:11;22665:19;22657:6;22653:32;22642:9;22635:51;22722:6;22717:2;22706:9;22702:18;22695:34;22777:6;22769;22765:19;22760:2;22749:9;22745:18;22738:47;22821:3;22816:2;22805:9;22801:18;22794:31;22616:4;22842:46;22883:3;22872:9;22868:19;22860:6;22842:46;:::i;23167:379::-;23360:2;23349:9;23342:21;23323:4;23386:45;23427:2;23416:9;23412:18;23404:6;23386:45;:::i;:::-;23479:9;23471:6;23467:22;23462:2;23451:9;23447:18;23440:50;23507:33;23533:6;23525;23507:33;:::i;23551:245::-;23618:6;23671:2;23659:9;23650:7;23646:23;23642:32;23639:52;;;23687:1;23684;23677:12;23639:52;23719:9;23713:16;23738:28;23760:5;23738:28;:::i;23801:891::-;24024:2;24013:9;24006:21;24082:10;24073:6;24067:13;24063:30;24058:2;24047:9;24043:18;24036:58;24148:4;24140:6;24136:17;24130:24;24125:2;24114:9;24110:18;24103:52;23987:4;24202:2;24194:6;24190:15;24184:22;24243:4;24237:3;24226:9;24222:19;24215:33;24271:52;24318:3;24307:9;24303:19;24289:12;24271:52;:::i;:::-;24257:66;;24372:2;24364:6;24360:15;24354:22;24446:2;24442:7;24430:9;24422:6;24418:22;24414:36;24407:4;24396:9;24392:20;24385:66;24474:41;24508:6;24492:14;24474:41;:::i;:::-;24584:3;24572:16;;;;24566:23;24559:31;24552:39;24546:3;24531:19;;24524:68;-1:-1:-1;;;;;;;;24653:32:41;;;;24646:4;24631:20;;;24624:62;24460:55;23801:891::o;24697:284::-;24767:5;24815:4;24803:9;24798:3;24794:19;24790:30;24787:50;;;24833:1;24830;24823:12;24787:50;24855:22;;:::i;:::-;24846:31;;24906:9;24900:16;24893:5;24886:31;24970:2;24959:9;24955:18;24949:25;24944:2;24937:5;24933:14;24926:49;24697:284;;;;:::o;24986:259::-;25086:6;25139:2;25127:9;25118:7;25114:23;25110:32;25107:52;;;25155:1;25152;25145:12;25107:52;25178:61;25231:7;25220:9;25178:61;:::i;25375:542::-;25476:2;25471:3;25468:11;25465:446;;;25512:1;25536:5;25533:1;25526:16;25580:4;25577:1;25567:18;25650:2;25638:10;25634:19;25631:1;25627:27;25621:4;25617:38;25686:4;25674:10;25671:20;25668:47;;;-1:-1:-1;25709:4:41;25668:47;25764:2;25759:3;25755:12;25752:1;25748:20;25742:4;25738:31;25728:41;;25819:82;25837:2;25830:5;25827:13;25819:82;;;25882:17;;;25863:1;25852:13;25819:82;;;25823:3;;;25375:542;;;:::o;26093:1341::-;26217:3;26211:10;-1:-1:-1;;;;;26236:6:41;26233:30;26230:56;;;26266:18;;:::i;:::-;26295:96;26384:6;26344:38;26376:4;26370:11;26344:38;:::i;:::-;26338:4;26295:96;:::i;:::-;26446:4;;26503:2;26492:14;;26520:1;26515:662;;;;27221:1;27238:6;27235:89;;;-1:-1:-1;27290:19:41;;;27284:26;27235:89;-1:-1:-1;;26050:1:41;26046:11;;;26042:24;26038:29;26028:40;26074:1;26070:11;;;26025:57;27337:81;;26485:943;;26515:662;25322:1;25315:14;;;25359:4;25346:18;;-1:-1:-1;;26551:20:41;;;26668:236;26682:7;26679:1;26676:14;26668:236;;;26771:19;;;26765:26;26750:42;;26863:27;;;;26831:1;26819:14;;;;26698:19;;26668:236;;;26672:3;26932:6;26923:7;26920:19;26917:201;;;26993:19;;;26987:26;-1:-1:-1;;27076:1:41;27072:14;;;27088:3;27068:24;27064:37;27060:42;27045:58;27030:74;;26917:201;-1:-1:-1;;;;;27164:1:41;27148:14;;;27144:22;27131:36;;-1:-1:-1;26093:1341:41:o;27439:1162::-;27653:4;27682:2;27722;27711:9;27707:18;27752:2;27741:9;27734:21;27775:6;27810;27804:13;27841:6;27833;27826:22;27867:2;27857:12;;27900:2;27889:9;27885:18;27878:25;;27962:2;27952:6;27949:1;27945:14;27934:9;27930:30;27926:39;28000:2;27992:6;27988:15;28021:1;28031:541;28045:6;28042:1;28039:13;28031:541;;;28110:22;;;-1:-1:-1;;28106:36:41;28094:49;;28166:13;;28238:9;;28249:10;28234:26;28219:42;;28308:11;;;28302:18;28322:6;28298:31;28281:15;;;28274:56;28369:11;;28363:18;28202:4;28401:15;;;28394:27;;;28444:48;28476:15;;;28363:18;28444:48;:::i;:::-;28550:12;;;;28434:58;-1:-1:-1;;;28515:15:41;;;;28067:1;28060:9;28031:541;;;-1:-1:-1;28589:6:41;;27439:1162;-1:-1:-1;;;;;;;;27439:1162:41:o;28606:525::-;28710:6;28763:3;28751:9;28742:7;28738:23;28734:33;28731:53;;;28780:1;28777;28770:12;28731:53;28806:22;;:::i;:::-;28857:9;28851:16;28844:5;28837:31;28913:2;28902:9;28898:18;28892:25;28926:32;28950:7;28926:32;:::i;:::-;28985:2;28974:14;;28967:31;29030:70;29092:7;29087:2;29072:18;;29030:70;:::i;:::-;29025:2;29014:14;;29007:94;29018:5;28606:525;-1:-1:-1;;;28606:525:41:o;29136:217::-;29176:1;29202;29192:132;;29246:10;29241:3;29237:20;29234:1;29227:31;29281:4;29278:1;29271:15;29309:4;29306:1;29299:15;29192:132;-1:-1:-1;29338:9:41;;29136:217::o;29358:265::-;29431:9;;;29462;;29479:15;;;29473:22;;29459:37;29449:168;;29539:10;29534:3;29530:20;29527:1;29520:31;29574:4;29571:1;29564:15;29602:4;29599:1;29592:15;29628:255;29748:19;;29787:2;29779:11;;29776:101;;;-1:-1:-1;;29848:2:41;29844:12;;;29841:1;29837:20;29833:33;29822:45;29628:255;;;;:::o;29888:331::-;-1:-1:-1;;;;;;30008:19:41;;30092:11;;;;30123:1;30115:10;;30112:101;;;30200:2;30194;30187:3;30184:1;30180:11;30177:1;30173:19;30169:28;30165:2;30161:37;30157:46;30148:55;;30112:101;;;29888:331;;;;:::o;30224:568::-;-1:-1:-1;;;;;30489:3:41;30485:28;30476:6;30471:3;30467:16;30463:51;30458:3;30451:64;30575:10;30570:3;30566:20;30557:6;30552:3;30548:16;30544:43;30540:1;30535:3;30531:11;30524:64;30618:6;30613:2;30608:3;30604:12;30597:28;30433:3;30654:6;30648:13;30670:75;30738:6;30733:2;30728:3;30724:12;30717:4;30709:6;30705:17;30670:75;:::i;:::-;30765:16;;;;30783:2;30761:25;;30224:568;-1:-1:-1;;;;;30224:568:41:o;31092:532::-;31333:6;31328:3;31321:19;-1:-1:-1;;;;;31396:3:41;31392:28;31383:6;31378:3;31374:16;31370:51;31365:2;31360:3;31356:12;31349:73;31452:6;31447:2;31442:3;31438:12;31431:28;31303:3;31488:6;31482:13;31504:73;31570:6;31565:2;31560:3;31556:12;31551:2;31543:6;31539:15;31504:73;:::i;:::-;31597:16;;;;31615:2;31593:25;;31092:532;-1:-1:-1;;;;;31092:532:41:o;32009:251::-;32079:6;32132:2;32120:9;32111:7;32107:23;32103:32;32100:52;;;32148:1;32145;32138:12;32100:52;32180:9;32174:16;32199:31;32224:5;32199:31;:::i;32544:287::-;32673:3;32711:6;32705:13;32727:66;32786:6;32781:3;32774:4;32766:6;32762:17;32727:66;:::i
Swarm Source
ipfs://3ca2d3dcb375f0cfde542247a24413e11061896e5c0b5c77ecc7972b9910e91f
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
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.