More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 280 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Send | 21551725 | 4 hrs ago | IN | 0.00002807 ETH | 0.00369643 | ||||
Send | 21550511 | 8 hrs ago | IN | 0.00002807 ETH | 0.00141162 | ||||
Send | 21550271 | 9 hrs ago | IN | 0.00002807 ETH | 0.00139903 | ||||
Send | 21550248 | 9 hrs ago | IN | 0.00002807 ETH | 0.00136847 | ||||
Send | 21549885 | 10 hrs ago | IN | 0.00002807 ETH | 0.00137371 | ||||
Send | 21548728 | 14 hrs ago | IN | 0.00002807 ETH | 0.00143594 | ||||
Send | 21548609 | 14 hrs ago | IN | 0.00002807 ETH | 0.00128951 | ||||
Send | 21547266 | 19 hrs ago | IN | 0.00002807 ETH | 0.00169382 | ||||
Send | 21547061 | 20 hrs ago | IN | 0.00002807 ETH | 0.00213172 | ||||
Send | 21545961 | 23 hrs ago | IN | 0.00002807 ETH | 0.00466039 | ||||
Send | 21544438 | 28 hrs ago | IN | 0.00002987 ETH | 0.00271139 | ||||
Send | 21544436 | 28 hrs ago | IN | 0.00002987 ETH | 0.00275566 | ||||
Send | 21542631 | 34 hrs ago | IN | 0.00002987 ETH | 0.00137422 | ||||
Send | 21541388 | 39 hrs ago | IN | 0.00002987 ETH | 0.00134422 | ||||
Send | 21539591 | 45 hrs ago | IN | 0.00002987 ETH | 0.00258024 | ||||
Send | 21539497 | 45 hrs ago | IN | 0.00002987 ETH | 0.00232172 | ||||
Send | 21538027 | 2 days ago | IN | 0.00002987 ETH | 0.00291076 | ||||
Send | 21530016 | 3 days ago | IN | 0.00002987 ETH | 0.00165526 | ||||
Send | 21529231 | 3 days ago | IN | 0.00002987 ETH | 0.00194963 | ||||
Send | 21529195 | 3 days ago | IN | 0.00002987 ETH | 0.00175014 | ||||
Send | 21529114 | 3 days ago | IN | 0.00002987 ETH | 0.00232147 | ||||
Send | 21527062 | 3 days ago | IN | 0.00002987 ETH | 0.00073344 | ||||
Send | 21526139 | 3 days ago | IN | 0.00002987 ETH | 0.00097835 | ||||
Send | 21521442 | 4 days ago | IN | 0.00002987 ETH | 0.00363755 | ||||
Send | 21520193 | 4 days ago | IN | 0.00002987 ETH | 0.00068469 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
21551725 | 4 hrs ago | 0.00002807 ETH | ||||
21550511 | 8 hrs ago | 0.00002807 ETH | ||||
21550271 | 9 hrs ago | 0.00002807 ETH | ||||
21550248 | 9 hrs ago | 0.00002807 ETH | ||||
21549885 | 10 hrs ago | 0.00002807 ETH | ||||
21548728 | 14 hrs ago | 0.00002807 ETH | ||||
21548609 | 14 hrs ago | 0.00002807 ETH | ||||
21547266 | 19 hrs ago | 0.00002807 ETH | ||||
21547061 | 20 hrs ago | 0.00002807 ETH | ||||
21545961 | 23 hrs ago | 0.00002807 ETH | ||||
21544438 | 28 hrs ago | 0.00002987 ETH | ||||
21544436 | 28 hrs ago | 0.00002987 ETH | ||||
21542631 | 34 hrs ago | 0.00002987 ETH | ||||
21541388 | 39 hrs ago | 0.00002987 ETH | ||||
21539591 | 45 hrs ago | 0.00002987 ETH | ||||
21539497 | 45 hrs ago | 0.00002987 ETH | ||||
21538027 | 2 days ago | 0.00002987 ETH | ||||
21530016 | 3 days ago | 0.00002987 ETH | ||||
21529231 | 3 days ago | 0.00002987 ETH | ||||
21529195 | 3 days ago | 0.00002987 ETH | ||||
21529114 | 3 days ago | 0.00002987 ETH | ||||
21527062 | 3 days ago | 0.00002987 ETH | ||||
21526139 | 3 days ago | 0.00002987 ETH | ||||
21521442 | 4 days ago | 0.00002987 ETH | ||||
21520193 | 4 days ago | 0.00002987 ETH |
Loading...
Loading
Contract Name:
SwellOFTAdapter
Compiler Version
v0.8.22+commit.4fc1097e
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.22; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { OFTAdapter } from "@layerzerolabs/oft-evm/contracts/OFTAdapter.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. */ contract SwellOFTAdapter is OFTAdapter { constructor( address _token, address _lzEndpoint, address _delegate ) OFTAdapter(_token, _lzEndpoint, _delegate) Ownable(_delegate) {} }
// 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 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; // @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.20; import { MessagingReceipt, MessagingFee } from "@layerzerolabs/oapp-evm/contracts/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 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 for 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 for 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) { if (_to == address(0x0)) _to = address(0xdead); // _mint(...) does not support address(0x0) // @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 Locks tokens from the sender's specified balance in this contract. * @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 "@layerzerolabs/oapp-evm/contracts/oapp/OApp.sol"; import { OAppOptionsType3 } from "@layerzerolabs/oapp-evm/contracts/oapp/libs/OAppOptionsType3.sol"; import { IOAppMsgInspector } from "@layerzerolabs/oapp-evm/contracts/oapp/interfaces/IOAppMsgInspector.sol"; import { OAppPreCrimeSimulator } from "@layerzerolabs/oapp-evm/contracts/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) { return _send(_sendParam, _fee, _refundAddress); } /** * @dev Internal function to execute 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 ) internal 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 address inspector = msgInspector; // caches the msgInspector to avoid potential double storage read if (inspector != address(0)) IOAppMsgInspector(inspector).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 // 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.1.0) (interfaces/draft-IERC6093.sol) pragma solidity ^0.8.20; /** * @dev Standard ERC-20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 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 ERC-721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-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 ERC-1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 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.1.0) (interfaces/IERC1363.sol) pragma solidity ^0.8.20; import {IERC20} from "./IERC20.sol"; import {IERC165} from "./IERC165.sol"; /** * @title IERC1363 * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363]. * * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction. */ interface IERC1363 is IERC20, IERC165 { /* * Note: the ERC-165 identifier for this interface is 0xb0202a11. * 0xb0202a11 === * bytes4(keccak256('transferAndCall(address,uint256)')) ^ * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^ * bytes4(keccak256('approveAndCall(address,uint256)')) ^ * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) */ /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @param data Additional data with no specified format, sent in call to `spender`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "../utils/introspection/IERC165.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.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 ERC-20 * applications. */ 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}. * * Skips emitting an {Approval} event indicating an allowance update. This is not * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve]. * * 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: * * ```solidity * 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.1.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 ERC-20 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.1.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-20 standard as defined in the ERC. */ 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.1.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; import {IERC1363} from "../../../interfaces/IERC1363.sol"; import {Address} from "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC-20 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 { /** * @dev An operation with an ERC-20 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. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ 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. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ 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. * * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function * only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being * set here. */ 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 Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { safeTransfer(token, to, value); } else if (!token.transferAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferFromAndCallRelaxed( IERC1363 token, address from, address to, uint256 value, bytes memory data ) internal { if (to.code.length == 0) { safeTransferFrom(token, from, to, value); } else if (!token.transferFromAndCall(from, to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}. * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall} * once without retrying, and relies on the returned value to be true. * * Reverts if the returned value is other than `true`. */ function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { forceApprove(token, to, value); } else if (!token.approveAndCall(to, value, data)) { 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 {_callOptionalReturnBool} that reverts if call fails to meet the requirements. */ function _callOptionalReturn(IERC20 token, bytes memory data) private { uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) // bubble errors if iszero(success) { let ptr := mload(0x40) returndatacopy(ptr, 0, returndatasize()) revert(ptr, returndatasize()) } returnSize := returndatasize() returnValue := mload(0) } if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) { 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 silently catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { bool success; uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) returnSize := returndatasize() returnValue := mload(0) } return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Address.sol) pragma solidity ^0.8.20; import {Errors} from "./Errors.sol"; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @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 Errors.InsufficientBalance(address(this).balance, amount); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert Errors.FailedCall(); } } /** * @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 * {Errors.FailedCall} 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 Errors.InsufficientBalance(address(this).balance, value); } (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 {Errors.FailedCall}) 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 {Errors.FailedCall} 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 {Errors.FailedCall}. */ 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 assembly ("memory-safe") { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert Errors.FailedCall(); } } }
// 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.1.0) (utils/Errors.sol) pragma solidity ^0.8.20; /** * @dev Collection of common custom errors used in multiple contracts * * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library. * It is recommended to avoid relying on the error API for critical functionality. * * _Available since v5.1._ */ library Errors { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error InsufficientBalance(uint256 balance, uint256 needed); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedCall(); /** * @dev The deployment failed. */ error FailedDeployment(); /** * @dev A necessary precompile is missing. */ error MissingPrecompile(address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * 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[ERC 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: UNLICENSED pragma solidity ^0.8.22; import { SwellOFTAdapter } from "../MyOFTAdapter.sol"; // @dev WARNING: This is for testing purposes only contract MyOFTAdapterMock is SwellOFTAdapter { constructor( address _token, address _lzEndpoint, address _delegate ) SwellOFTAdapter(_token, _lzEndpoint, _delegate) {} }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.22; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { OFT } from "@layerzerolabs/oft-evm/contracts/OFT.sol"; contract SwellToken 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":[],"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
60e06040523480156200001157600080fd5b5060405162002ee338038062002ee3833981016040819052620000349162000254565b828282826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000076573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009c91906200029e565b8282818181818a6001600160a01b038116620000d257604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b620000dd81620001e2565b506001600160a01b0380831660805281166200010c57604051632d618d8160e21b815260040160405180910390fd5b60805160405163ca5eb5e160e01b81526001600160a01b0383811660048301529091169063ca5eb5e190602401600060405180830381600087803b1580156200015457600080fd5b505af115801562000169573d6000803e3d6000fd5b5050505050505050620001816200023260201b60201c565b60ff168360ff161015620001a8576040516301e9714b60e41b815260040160405180910390fd5b620001b5600684620002e0565b620001c290600a620003ff565b60a0525050506001600160a01b0390921660c05250620004109350505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600690565b80516001600160a01b03811681146200024f57600080fd5b919050565b6000806000606084860312156200026a57600080fd5b620002758462000237565b9250620002856020850162000237565b9150620002956040850162000237565b90509250925092565b600060208284031215620002b157600080fd5b815160ff81168114620002c357600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b60ff8281168282160390811115620002fc57620002fc620002ca565b92915050565b600181815b8085111562000343578160001904821115620003275762000327620002ca565b808516156200033557918102915b93841c939080029062000307565b509250929050565b6000826200035c57506001620002fc565b816200036b57506000620002fc565b81600181146200038457600281146200038f57620003af565b6001915050620002fc565b60ff841115620003a357620003a3620002ca565b50506001821b620002fc565b5060208310610133831016604e8410600b8410161715620003d4575081810a620002fc565b620003e0838362000302565b8060001904821115620003f757620003f7620002ca565b029392505050565b6000620002c360ff8416836200034b565b60805160a05160c051612a4f62000494600039600081816106690152818161168701526117f90152600081816104e2015281816115ce0152818161164a015261173a0152600081816103e40152818161078001528181610d8f01528181610ff4015281816112810152818161185d01528181611a040152611abd0152612a4f6000f3fe6080604052600436106101ee5760003560e01c806382413eac1161010d578063bc70b354116100a0578063d045a0dc1161006f578063d045a0dc14610607578063d42438851461061a578063f2fde38b1461063a578063fc0c546a1461065a578063ff7bd03d1461068d57600080fd5b8063bc70b35414610593578063bd815db0146105b3578063c7c7f5b3146105c6578063ca5eb5e1146105e757600080fd5b80639f68b964116100dc5780639f68b96414610512578063b731ea0a14610526578063b98bd07014610546578063bb0b6a531461056657600080fd5b806382413eac14610476578063857749b0146104965780638da5cb5b146104b2578063963efcaa146104d057600080fd5b80633b6f743b116101855780635e280f11116101545780635e280f11146103d25780636fc1b31e14610406578063715018a6146104265780637d25a05e1461043b57600080fd5b80633b6f743b1461031e57806352ae28791461034b5780635535d4611461035e5780635a0dfe4d1461038b57600080fd5b8063156a0d0f116101c1578063156a0d0f146102a057806317442b70146102c75780631f5e1334146102e95780633400288b146102fe57600080fd5b80630d35b415146101f3578063111ecdad1461022b57806313137d6514610263578063134d4f2514610278575b600080fd5b3480156101ff57600080fd5b5061021361020e366004611bb2565b6106ad565b60405161022293929190611c36565b60405180910390f35b34801561023757600080fd5b5060045461024b906001600160a01b031681565b6040516001600160a01b039091168152602001610222565b610276610271366004611d3e565b61077e565b005b34801561028457600080fd5b5061028d600281565b60405161ffff9091168152602001610222565b3480156102ac57600080fd5b506040805162b9270b60e21b81526001602082015201610222565b3480156102d357600080fd5b5060408051600181526002602082015201610222565b3480156102f557600080fd5b5061028d600181565b34801561030a57600080fd5b50610276610319366004611df6565b61083e565b34801561032a57600080fd5b5061033e610339366004611e2e565b610854565b6040516102229190611e7f565b34801561035757600080fd5b503061024b565b34801561036a57600080fd5b5061037e610379366004611ea8565b6108bd565b6040516102229190611edb565b34801561039757600080fd5b506103c26103a6366004611df6565b63ffffffff919091166000908152600160205260409020541490565b6040519015158152602001610222565b3480156103de57600080fd5b5061024b7f000000000000000000000000000000000000000000000000000000000000000081565b34801561041257600080fd5b50610276610421366004611eee565b610962565b34801561043257600080fd5b506102766109bf565b34801561044757600080fd5b5061045e610456366004611df6565b600092915050565b6040516001600160401b039091168152602001610222565b34801561048257600080fd5b506103c2610491366004611f0b565b6109d3565b3480156104a257600080fd5b5060405160068152602001610222565b3480156104be57600080fd5b506000546001600160a01b031661024b565b3480156104dc57600080fd5b506105047f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610222565b34801561051e57600080fd5b5060016103c2565b34801561053257600080fd5b5060025461024b906001600160a01b031681565b34801561055257600080fd5b50610276610561366004611fb5565b6109e8565b34801561057257600080fd5b50610504610581366004611ff6565b60016020526000908152604090205481565b34801561059f57600080fd5b5061037e6105ae366004612011565b610a02565b6102766105c1366004611fb5565b610baa565b6105d96105d4366004612071565b610d34565b6040516102229291906120de565b3480156105f357600080fd5b50610276610602366004611eee565b610d68565b610276610615366004611d3e565b610dee565b34801561062657600080fd5b50610276610635366004611eee565b610e1d565b34801561064657600080fd5b50610276610655366004611eee565b610e73565b34801561066657600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061024b565b34801561069957600080fd5b506103c26106a8366004612130565b610eb1565b604080518082019091526000808252602082015260606106e0604051806040016040528060008152602001600081525090565b60408051808201825260008082526001600160401b0360208084018290528451838152908101909452919550918261073b565b6040805180820190915260008152606060208201528152602001906001900390816107135790505b509350600080610760604089013560608a013561075b60208c018c611ff6565b610ee7565b60408051808201909152918252602082015296989597505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633146107ce576040516391ac5e4f60e01b81523360048201526024015b60405180910390fd5b602087018035906107e8906107e3908a611ff6565b610f23565b14610826576107fa6020880188611ff6565b60405163309afaf360e21b815263ffffffff9091166004820152602088013560248201526044016107c5565b61083587878787878787610f5f565b50505050505050565b6108466110c6565b61085082826110f3565b5050565b604080518082019091526000808252602082015260006108846040850135606086013561075b6020880188611ff6565b9150506000806108948684611148565b90925090506108b16108a96020880188611ff6565b83838861126b565b93505050505b92915050565b6003602090815260009283526040808420909152908252902080546108e190612162565b80601f016020809104026020016040519081016040528092919081815260200182805461090d90612162565b801561095a5780601f1061092f5761010080835404028352916020019161095a565b820191906000526020600020905b81548152906001019060200180831161093d57829003601f168201915b505050505081565b61096a6110c6565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527ff0be4f1e87349231d80c36b33f9e8639658eeaf474014dee15a3e6a4d4414197906020015b60405180910390a150565b6109c76110c6565b6109d1600061134c565b565b6001600160a01b03811630145b949350505050565b6109f06110c6565b6108506109fd8284612237565b61139c565b63ffffffff8416600090815260036020908152604080832061ffff87168452909152812080546060929190610a3690612162565b80601f0160208091040260200160405190810160405280929190818152602001828054610a6290612162565b8015610aaf5780601f10610a8457610100808354040283529160200191610aaf565b820191906000526020600020905b815481529060010190602001808311610a9257829003601f168201915b505050505090508051600003610aff5783838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509294506109e09350505050565b6000839003610b0f5790506109e0565b60028310610b8d57610b5684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506114a392505050565b80610b64846002818861234c565b604051602001610b7693929190612376565b6040516020818303038152906040529150506109e0565b8383604051639a6d49cd60e01b81526004016107c59291906123c7565b60005b81811015610cb35736838383818110610bc857610bc86123db565b9050602002810190610bda91906123f1565b9050610c0d610bec6020830183611ff6565b602083013563ffffffff919091166000908152600160205260409020541490565b610c175750610cab565b3063d045a0dc60c08301358360a0810135610c36610100830183612412565b610c47610100890160e08a01611eee565b610c556101208a018a612412565b6040518963ffffffff1660e01b8152600401610c77979695949392919061246d565b6000604051808303818588803b158015610c9057600080fd5b505af1158015610ca4573d6000803e3d6000fd5b5050505050505b600101610bad565b50336001600160a01b0316638e9e70996040518163ffffffff1660e01b8152600401600060405180830381865afa158015610cf2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d1a91908101906124f3565b604051638351eea760e01b81526004016107c59190611edb565b610d3c611b53565b6040805180820190915260008082526020820152610d5b8585856114cf565b915091505b935093915050565b610d706110c6565b60405163ca5eb5e160e01b81526001600160a01b0382811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063ca5eb5e190602401600060405180830381600087803b158015610dd357600080fd5b505af1158015610de7573d6000803e3d6000fd5b5050505050565b333014610e0e5760405163029a949d60e31b815260040160405180910390fd5b61083587878787878787610826565b610e256110c6565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527fd48d879cef83a1c0bdda516f27b13ddb1b3f8bbac1c9e1511bb2a659c2427760906020016109b4565b610e7b6110c6565b6001600160a01b038116610ea557604051631e4fbdf760e01b8152600060048201526024016107c5565b610eae8161134c565b50565b6000602082018035906001908390610ec99086611ff6565b63ffffffff1681526020810191909152604001600020541492915050565b600080610ef3856115ca565b915081905083811015610d60576040516371c4efed60e01b815260048101829052602481018590526044016107c5565b63ffffffff8116600090815260016020526040812054806108b75760405163f6ff4fb760e01b815263ffffffff841660048201526024016107c5565b6000610f71610f6e8787611601565b90565b90506000610f9d82610f8b610f868a8a611620565b611643565b610f9860208d018d611ff6565b611678565b90506028861115611064576000610fda610fbd60608c0160408d01612560565b610fca60208d018d611ff6565b84610fd58c8c6116b6565b611701565b604051633e5ac80960e11b81529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690637cb59012906110309086908d90600090879060040161257d565b600060405180830381600087803b15801561104a57600080fd5b505af115801561105e573d6000803e3d6000fd5b50505050505b6001600160a01b038216887fefed6d3500546b29533b128a29e3a94d70788727f0507505ac12eaf2e578fd9c61109d60208d018d611ff6565b6040805163ffffffff9092168252602082018690520160405180910390a3505050505050505050565b6000546001600160a01b031633146109d15760405163118cdaa760e01b81523360048201526024016107c5565b63ffffffff8216600081815260016020908152604091829020849055815192835282018390527f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b910160405180910390a15050565b60608060006111a5856020013561115e86611733565b61116b60a0890189612412565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061175f92505050565b90935090506000816111b85760016111bb565b60025b90506111db6111cd6020880188611ff6565b826105ae60808a018a612412565b6004549093506001600160a01b031680156112615760405163043a78eb60e01b81526001600160a01b0382169063043a78eb9061121e90889088906004016125b8565b602060405180830381865afa15801561123b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125f91906125dd565b505b5050509250929050565b60408051808201909152600080825260208201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ddc28c586040518060a001604052808863ffffffff1681526020016112ce89610f23565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b81526004016113039291906125fa565b6040805180830381865afa15801561131f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134391906126a3565b95945050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60005b8151811015611473576113ce8282815181106113bd576113bd6123db565b6020026020010151604001516114a3565b8181815181106113e0576113e06123db565b60200260200101516040015160036000848481518110611402576114026123db565b60200260200101516000015163ffffffff1663ffffffff168152602001908152602001600020600084848151811061143c5761143c6123db565b60200260200101516020015161ffff1661ffff168152602001908152602001600020908161146a919061270f565b5060010161139f565b507fbe4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b674816040516109b491906127ce565b600281015161ffff81166003146108505781604051639a6d49cd60e01b81526004016107c59190611edb565b6114d7611b53565b604080518082019091526000808252602082015260008061150e33604089013560608a013561150960208c018c611ff6565b6117d9565b9150915060008061151f8984611148565b909250905061154b61153460208b018b611ff6565b8383611545368d90038d018d612859565b8b61182a565b60408051808201909152858152602080820186905282519298509096503391907f85496b760a4b7f8d66384b9df21b381f5d1b1e79f229a47aaf4c232edc2fe59a90611599908d018d611ff6565b6040805163ffffffff909216825260208201899052810187905260600160405180910390a350505050935093915050565b60007f00000000000000000000000000000000000000000000000000000000000000006115f7818461288b565b6108b791906128ad565b6000611610602082848661234c565b611619916128d2565b9392505050565b600061163060286020848661234c565b611639916128f0565b60c01c9392505050565b60006108b77f00000000000000000000000000000000000000000000000000000000000000006001600160401b0384166128ad565b60006116ae6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168585611935565b509092915050565b60606116c5826028818661234c565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929695505050505050565b60608484848460405160200161171a9493929190612920565b6040516020818303038152906040529050949350505050565b60006108b77f00000000000000000000000000000000000000000000000000000000000000008361288b565b80516060901515806117a857848460405160200161179492919091825260c01b6001600160c01b031916602082015260280190565b6040516020818303038152906040526117cf565b848433856040516020016117bf949392919061296f565b6040516020818303038152906040525b9150935093915050565b6000806117e7858585610ee7565b90925090506118216001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016873085611999565b94509492505050565b611832611b53565b600061184184600001516119d8565b60208501519091501561185b5761185b8460200151611a00565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632637a450826040518060a001604052808b63ffffffff1681526020016118ab8c610f23565b81526020018a815260200189815260200160008960200151111515815250866040518463ffffffff1660e01b81526004016118e79291906125fa565b60806040518083038185885af1158015611905573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061192a91906129b2565b979650505050505050565b6040516001600160a01b0383811660248301526044820183905261199491859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050611ae2565b505050565b6040516001600160a01b0384811660248301528381166044830152606482018390526119d29186918216906323b872dd90608401611962565b50505050565b60008134146119fc576040516304fb820960e51b81523460048201526024016107c5565b5090565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8491906129fc565b90506001600160a01b038116611aad576040516329b99a9560e11b815260040160405180910390fd5b6108506001600160a01b038216337f000000000000000000000000000000000000000000000000000000000000000085611999565b600080602060008451602086016000885af180611b05576040513d6000823e3d81fd5b50506000513d91508115611b1d578060011415611b2a565b6001600160a01b0384163b155b156119d257604051635274afe760e01b81526001600160a01b03851660048201526024016107c5565b60405180606001604052806000801916815260200160006001600160401b03168152602001611b95604051806040016040528060008152602001600081525090565b905290565b600060e08284031215611bac57600080fd5b50919050565b600060208284031215611bc457600080fd5b81356001600160401b03811115611bda57600080fd5b6109e084828501611b9a565b60005b83811015611c01578181015183820152602001611be9565b50506000910152565b60008151808452611c22816020860160208601611be6565b601f01601f19169290920160200192915050565b8351815260208085015190820152600060a08201604060a0604085015281865180845260c08601915060c08160051b8701019350602080890160005b83811015611cb15788870360bf19018552815180518852830151838801879052611c9e87890182611c0a565b9750509382019390820190600101611c72565b505087516060880152505050602085015160808501525090506109e0565b600060608284031215611bac57600080fd5b60008083601f840112611cf357600080fd5b5081356001600160401b03811115611d0a57600080fd5b602083019150836020828501011115611d2257600080fd5b9250929050565b6001600160a01b0381168114610eae57600080fd5b600080600080600080600060e0888a031215611d5957600080fd5b611d638989611ccf565b96506060880135955060808801356001600160401b0380821115611d8657600080fd5b611d928b838c01611ce1565b909750955060a08a01359150611da782611d29565b90935060c08901359080821115611dbd57600080fd5b50611dca8a828b01611ce1565b989b979a50959850939692959293505050565b803563ffffffff81168114611df157600080fd5b919050565b60008060408385031215611e0957600080fd5b611e1283611ddd565b946020939093013593505050565b8015158114610eae57600080fd5b60008060408385031215611e4157600080fd5b82356001600160401b03811115611e5757600080fd5b611e6385828601611b9a565b9250506020830135611e7481611e20565b809150509250929050565b8151815260208083015190820152604081016108b7565b803561ffff81168114611df157600080fd5b60008060408385031215611ebb57600080fd5b611ec483611ddd565b9150611ed260208401611e96565b90509250929050565b6020815260006116196020830184611c0a565b600060208284031215611f0057600080fd5b813561161981611d29565b60008060008060a08587031215611f2157600080fd5b611f2b8686611ccf565b935060608501356001600160401b03811115611f4657600080fd5b611f5287828801611ce1565b9094509250506080850135611f6681611d29565b939692955090935050565b60008083601f840112611f8357600080fd5b5081356001600160401b03811115611f9a57600080fd5b6020830191508360208260051b8501011115611d2257600080fd5b60008060208385031215611fc857600080fd5b82356001600160401b03811115611fde57600080fd5b611fea85828601611f71565b90969095509350505050565b60006020828403121561200857600080fd5b61161982611ddd565b6000806000806060858703121561202757600080fd5b61203085611ddd565b935061203e60208601611e96565b925060408501356001600160401b0381111561205957600080fd5b61206587828801611ce1565b95989497509550505050565b6000806000838503608081121561208757600080fd5b84356001600160401b0381111561209d57600080fd5b6120a987828801611b9a565b9450506040601f19820112156120be57600080fd5b5060208401915060608401356120d381611d29565b809150509250925092565b600060c082019050835182526001600160401b0360208501511660208301526040840151612119604084018280518252602090810151910152565b5082516080830152602083015160a0830152611619565b60006060828403121561214257600080fd5b6116198383611ccf565b634e487b7160e01b600052604160045260246000fd5b600181811c9082168061217657607f821691505b602082108103611bac57634e487b7160e01b600052602260045260246000fd5b604051606081016001600160401b03811182821017156121b8576121b861214c565b60405290565b604080519081016001600160401b03811182821017156121b8576121b861214c565b604051601f8201601f191681016001600160401b03811182821017156122085761220861214c565b604052919050565b60006001600160401b038211156122295761222961214c565b50601f01601f191660200190565b60006001600160401b03808411156122515761225161214c565b8360051b60206122628183016121e0565b86815291850191818101903684111561227a57600080fd5b865b84811015612340578035868111156122945760008081fd5b880160603682900312156122a85760008081fd5b6122b0612196565b6122b982611ddd565b81526122c6868301611e96565b86820152604080830135898111156122de5760008081fd5b929092019136601f8401126122f35760008081fd5b823561230661230182612210565b6121e0565b818152368983870101111561231b5760008081fd5b818986018a83013760009181018901919091529082015284525091830191830161227c565b50979650505050505050565b6000808585111561235c57600080fd5b8386111561236957600080fd5b5050820193919092039150565b60008451612388818460208901611be6565b8201838582376000930192835250909392505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6020815260006109e060208301848661239e565b634e487b7160e01b600052603260045260246000fd5b6000823561013e1983360301811261240857600080fd5b9190910192915050565b6000808335601e1984360301811261242957600080fd5b8301803591506001600160401b0382111561244357600080fd5b602001915036819003821315611d2257600080fd5b6001600160401b0381168114610eae57600080fd5b63ffffffff61247b89611ddd565b168152602088013560208201526000604089013561249881612458565b6001600160401b03811660408401525087606083015260e060808301526124c360e08301878961239e565b6001600160a01b03861660a084015282810360c08401526124e581858761239e565b9a9950505050505050505050565b60006020828403121561250557600080fd5b81516001600160401b0381111561251b57600080fd5b8201601f8101841361252c57600080fd5b805161253a61230182612210565b81815285602083850101111561254f57600080fd5b611343826020830160208601611be6565b60006020828403121561257257600080fd5b813561161981612458565b60018060a01b038516815283602082015261ffff831660408201526080606082015260006125ae6080830184611c0a565b9695505050505050565b6040815260006125cb6040830185611c0a565b82810360208401526113438185611c0a565b6000602082840312156125ef57600080fd5b815161161981611e20565b6040815263ffffffff8351166040820152602083015160608201526000604084015160a0608084015261263060e0840182611c0a565b90506060850151603f198483030160a085015261264d8282611c0a565b60809690960151151560c08501525050506001600160a01b039190911660209091015290565b60006040828403121561268557600080fd5b61268d6121be565b9050815181526020820151602082015292915050565b6000604082840312156126b557600080fd5b6116198383612673565b601f821115611994576000816000526020600020601f850160051c810160208610156126e85750805b601f850160051c820191505b81811015612707578281556001016126f4565b505050505050565b81516001600160401b038111156127285761272861214c565b61273c816127368454612162565b846126bf565b602080601f83116001811461277157600084156127595750858301515b600019600386901b1c1916600185901b178555612707565b600085815260208120601f198616915b828110156127a057888601518255948401946001909101908401612781565b50858210156127be5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b8381101561284b57888303603f190185528151805163ffffffff1684528781015161ffff1688850152860151606087850181905261283781860183611c0a565b9689019694505050908601906001016127f7565b509098975050505050505050565b60006040828403121561286b57600080fd5b6128736121be565b82358152602083013560208201528091505092915050565b6000826128a857634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176108b757634e487b7160e01b600052601160045260246000fd5b803560208310156108b757600019602084900360031b1b1692915050565b6001600160c01b031981358181169160088510156129185780818660080360031b1b83161692505b505092915050565b6001600160401b0360c01b8560c01b16815263ffffffff60e01b8460e01b16600882015282600c8201526000825161295f81602c850160208701611be6565b91909101602c0195945050505050565b8481526001600160401b0360c01b8460c01b166020820152826028820152600082516129a2816048850160208701611be6565b9190910160480195945050505050565b6000608082840312156129c457600080fd5b6129cc612196565b8251815260208301516129de81612458565b60208201526129f08460408501612673565b60408201529392505050565b600060208284031215612a0e57600080fd5b815161161981611d2956fea26469706673582212207f40c76ec506a6d4547f0edcd18f0446f8ae35cc89647cd59d6247e42ed8250b64736f6c634300081600330000000000000000000000000a6e7ba5042b38349e437ec6db6214aec7b356760000000000000000000000001a44076050125825900e736c501f859c50fe728c000000000000000000000000af994551f4f940224825f54f810ed5439651e5f9
Deployed Bytecode
0x6080604052600436106101ee5760003560e01c806382413eac1161010d578063bc70b354116100a0578063d045a0dc1161006f578063d045a0dc14610607578063d42438851461061a578063f2fde38b1461063a578063fc0c546a1461065a578063ff7bd03d1461068d57600080fd5b8063bc70b35414610593578063bd815db0146105b3578063c7c7f5b3146105c6578063ca5eb5e1146105e757600080fd5b80639f68b964116100dc5780639f68b96414610512578063b731ea0a14610526578063b98bd07014610546578063bb0b6a531461056657600080fd5b806382413eac14610476578063857749b0146104965780638da5cb5b146104b2578063963efcaa146104d057600080fd5b80633b6f743b116101855780635e280f11116101545780635e280f11146103d25780636fc1b31e14610406578063715018a6146104265780637d25a05e1461043b57600080fd5b80633b6f743b1461031e57806352ae28791461034b5780635535d4611461035e5780635a0dfe4d1461038b57600080fd5b8063156a0d0f116101c1578063156a0d0f146102a057806317442b70146102c75780631f5e1334146102e95780633400288b146102fe57600080fd5b80630d35b415146101f3578063111ecdad1461022b57806313137d6514610263578063134d4f2514610278575b600080fd5b3480156101ff57600080fd5b5061021361020e366004611bb2565b6106ad565b60405161022293929190611c36565b60405180910390f35b34801561023757600080fd5b5060045461024b906001600160a01b031681565b6040516001600160a01b039091168152602001610222565b610276610271366004611d3e565b61077e565b005b34801561028457600080fd5b5061028d600281565b60405161ffff9091168152602001610222565b3480156102ac57600080fd5b506040805162b9270b60e21b81526001602082015201610222565b3480156102d357600080fd5b5060408051600181526002602082015201610222565b3480156102f557600080fd5b5061028d600181565b34801561030a57600080fd5b50610276610319366004611df6565b61083e565b34801561032a57600080fd5b5061033e610339366004611e2e565b610854565b6040516102229190611e7f565b34801561035757600080fd5b503061024b565b34801561036a57600080fd5b5061037e610379366004611ea8565b6108bd565b6040516102229190611edb565b34801561039757600080fd5b506103c26103a6366004611df6565b63ffffffff919091166000908152600160205260409020541490565b6040519015158152602001610222565b3480156103de57600080fd5b5061024b7f0000000000000000000000001a44076050125825900e736c501f859c50fe728c81565b34801561041257600080fd5b50610276610421366004611eee565b610962565b34801561043257600080fd5b506102766109bf565b34801561044757600080fd5b5061045e610456366004611df6565b600092915050565b6040516001600160401b039091168152602001610222565b34801561048257600080fd5b506103c2610491366004611f0b565b6109d3565b3480156104a257600080fd5b5060405160068152602001610222565b3480156104be57600080fd5b506000546001600160a01b031661024b565b3480156104dc57600080fd5b506105047f000000000000000000000000000000000000000000000000000000e8d4a5100081565b604051908152602001610222565b34801561051e57600080fd5b5060016103c2565b34801561053257600080fd5b5060025461024b906001600160a01b031681565b34801561055257600080fd5b50610276610561366004611fb5565b6109e8565b34801561057257600080fd5b50610504610581366004611ff6565b60016020526000908152604090205481565b34801561059f57600080fd5b5061037e6105ae366004612011565b610a02565b6102766105c1366004611fb5565b610baa565b6105d96105d4366004612071565b610d34565b6040516102229291906120de565b3480156105f357600080fd5b50610276610602366004611eee565b610d68565b610276610615366004611d3e565b610dee565b34801561062657600080fd5b50610276610635366004611eee565b610e1d565b34801561064657600080fd5b50610276610655366004611eee565b610e73565b34801561066657600080fd5b507f0000000000000000000000000a6e7ba5042b38349e437ec6db6214aec7b3567661024b565b34801561069957600080fd5b506103c26106a8366004612130565b610eb1565b604080518082019091526000808252602082015260606106e0604051806040016040528060008152602001600081525090565b60408051808201825260008082526001600160401b0360208084018290528451838152908101909452919550918261073b565b6040805180820190915260008152606060208201528152602001906001900390816107135790505b509350600080610760604089013560608a013561075b60208c018c611ff6565b610ee7565b60408051808201909152918252602082015296989597505050505050565b7f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b031633146107ce576040516391ac5e4f60e01b81523360048201526024015b60405180910390fd5b602087018035906107e8906107e3908a611ff6565b610f23565b14610826576107fa6020880188611ff6565b60405163309afaf360e21b815263ffffffff9091166004820152602088013560248201526044016107c5565b61083587878787878787610f5f565b50505050505050565b6108466110c6565b61085082826110f3565b5050565b604080518082019091526000808252602082015260006108846040850135606086013561075b6020880188611ff6565b9150506000806108948684611148565b90925090506108b16108a96020880188611ff6565b83838861126b565b93505050505b92915050565b6003602090815260009283526040808420909152908252902080546108e190612162565b80601f016020809104026020016040519081016040528092919081815260200182805461090d90612162565b801561095a5780601f1061092f5761010080835404028352916020019161095a565b820191906000526020600020905b81548152906001019060200180831161093d57829003601f168201915b505050505081565b61096a6110c6565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527ff0be4f1e87349231d80c36b33f9e8639658eeaf474014dee15a3e6a4d4414197906020015b60405180910390a150565b6109c76110c6565b6109d1600061134c565b565b6001600160a01b03811630145b949350505050565b6109f06110c6565b6108506109fd8284612237565b61139c565b63ffffffff8416600090815260036020908152604080832061ffff87168452909152812080546060929190610a3690612162565b80601f0160208091040260200160405190810160405280929190818152602001828054610a6290612162565b8015610aaf5780601f10610a8457610100808354040283529160200191610aaf565b820191906000526020600020905b815481529060010190602001808311610a9257829003601f168201915b505050505090508051600003610aff5783838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509294506109e09350505050565b6000839003610b0f5790506109e0565b60028310610b8d57610b5684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506114a392505050565b80610b64846002818861234c565b604051602001610b7693929190612376565b6040516020818303038152906040529150506109e0565b8383604051639a6d49cd60e01b81526004016107c59291906123c7565b60005b81811015610cb35736838383818110610bc857610bc86123db565b9050602002810190610bda91906123f1565b9050610c0d610bec6020830183611ff6565b602083013563ffffffff919091166000908152600160205260409020541490565b610c175750610cab565b3063d045a0dc60c08301358360a0810135610c36610100830183612412565b610c47610100890160e08a01611eee565b610c556101208a018a612412565b6040518963ffffffff1660e01b8152600401610c77979695949392919061246d565b6000604051808303818588803b158015610c9057600080fd5b505af1158015610ca4573d6000803e3d6000fd5b5050505050505b600101610bad565b50336001600160a01b0316638e9e70996040518163ffffffff1660e01b8152600401600060405180830381865afa158015610cf2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d1a91908101906124f3565b604051638351eea760e01b81526004016107c59190611edb565b610d3c611b53565b6040805180820190915260008082526020820152610d5b8585856114cf565b915091505b935093915050565b610d706110c6565b60405163ca5eb5e160e01b81526001600160a01b0382811660048301527f0000000000000000000000001a44076050125825900e736c501f859c50fe728c169063ca5eb5e190602401600060405180830381600087803b158015610dd357600080fd5b505af1158015610de7573d6000803e3d6000fd5b5050505050565b333014610e0e5760405163029a949d60e31b815260040160405180910390fd5b61083587878787878787610826565b610e256110c6565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527fd48d879cef83a1c0bdda516f27b13ddb1b3f8bbac1c9e1511bb2a659c2427760906020016109b4565b610e7b6110c6565b6001600160a01b038116610ea557604051631e4fbdf760e01b8152600060048201526024016107c5565b610eae8161134c565b50565b6000602082018035906001908390610ec99086611ff6565b63ffffffff1681526020810191909152604001600020541492915050565b600080610ef3856115ca565b915081905083811015610d60576040516371c4efed60e01b815260048101829052602481018590526044016107c5565b63ffffffff8116600090815260016020526040812054806108b75760405163f6ff4fb760e01b815263ffffffff841660048201526024016107c5565b6000610f71610f6e8787611601565b90565b90506000610f9d82610f8b610f868a8a611620565b611643565b610f9860208d018d611ff6565b611678565b90506028861115611064576000610fda610fbd60608c0160408d01612560565b610fca60208d018d611ff6565b84610fd58c8c6116b6565b611701565b604051633e5ac80960e11b81529091506001600160a01b037f0000000000000000000000001a44076050125825900e736c501f859c50fe728c1690637cb59012906110309086908d90600090879060040161257d565b600060405180830381600087803b15801561104a57600080fd5b505af115801561105e573d6000803e3d6000fd5b50505050505b6001600160a01b038216887fefed6d3500546b29533b128a29e3a94d70788727f0507505ac12eaf2e578fd9c61109d60208d018d611ff6565b6040805163ffffffff9092168252602082018690520160405180910390a3505050505050505050565b6000546001600160a01b031633146109d15760405163118cdaa760e01b81523360048201526024016107c5565b63ffffffff8216600081815260016020908152604091829020849055815192835282018390527f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b910160405180910390a15050565b60608060006111a5856020013561115e86611733565b61116b60a0890189612412565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061175f92505050565b90935090506000816111b85760016111bb565b60025b90506111db6111cd6020880188611ff6565b826105ae60808a018a612412565b6004549093506001600160a01b031680156112615760405163043a78eb60e01b81526001600160a01b0382169063043a78eb9061121e90889088906004016125b8565b602060405180830381865afa15801561123b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125f91906125dd565b505b5050509250929050565b60408051808201909152600080825260208201527f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b031663ddc28c586040518060a001604052808863ffffffff1681526020016112ce89610f23565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b81526004016113039291906125fa565b6040805180830381865afa15801561131f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134391906126a3565b95945050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60005b8151811015611473576113ce8282815181106113bd576113bd6123db565b6020026020010151604001516114a3565b8181815181106113e0576113e06123db565b60200260200101516040015160036000848481518110611402576114026123db565b60200260200101516000015163ffffffff1663ffffffff168152602001908152602001600020600084848151811061143c5761143c6123db565b60200260200101516020015161ffff1661ffff168152602001908152602001600020908161146a919061270f565b5060010161139f565b507fbe4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b674816040516109b491906127ce565b600281015161ffff81166003146108505781604051639a6d49cd60e01b81526004016107c59190611edb565b6114d7611b53565b604080518082019091526000808252602082015260008061150e33604089013560608a013561150960208c018c611ff6565b6117d9565b9150915060008061151f8984611148565b909250905061154b61153460208b018b611ff6565b8383611545368d90038d018d612859565b8b61182a565b60408051808201909152858152602080820186905282519298509096503391907f85496b760a4b7f8d66384b9df21b381f5d1b1e79f229a47aaf4c232edc2fe59a90611599908d018d611ff6565b6040805163ffffffff909216825260208201899052810187905260600160405180910390a350505050935093915050565b60007f000000000000000000000000000000000000000000000000000000e8d4a510006115f7818461288b565b6108b791906128ad565b6000611610602082848661234c565b611619916128d2565b9392505050565b600061163060286020848661234c565b611639916128f0565b60c01c9392505050565b60006108b77f000000000000000000000000000000000000000000000000000000e8d4a510006001600160401b0384166128ad565b60006116ae6001600160a01b037f0000000000000000000000000a6e7ba5042b38349e437ec6db6214aec7b35676168585611935565b509092915050565b60606116c5826028818661234c565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929695505050505050565b60608484848460405160200161171a9493929190612920565b6040516020818303038152906040529050949350505050565b60006108b77f000000000000000000000000000000000000000000000000000000e8d4a510008361288b565b80516060901515806117a857848460405160200161179492919091825260c01b6001600160c01b031916602082015260280190565b6040516020818303038152906040526117cf565b848433856040516020016117bf949392919061296f565b6040516020818303038152906040525b9150935093915050565b6000806117e7858585610ee7565b90925090506118216001600160a01b037f0000000000000000000000000a6e7ba5042b38349e437ec6db6214aec7b3567616873085611999565b94509492505050565b611832611b53565b600061184184600001516119d8565b60208501519091501561185b5761185b8460200151611a00565b7f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b0316632637a450826040518060a001604052808b63ffffffff1681526020016118ab8c610f23565b81526020018a815260200189815260200160008960200151111515815250866040518463ffffffff1660e01b81526004016118e79291906125fa565b60806040518083038185885af1158015611905573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061192a91906129b2565b979650505050505050565b6040516001600160a01b0383811660248301526044820183905261199491859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050611ae2565b505050565b6040516001600160a01b0384811660248301528381166044830152606482018390526119d29186918216906323b872dd90608401611962565b50505050565b60008134146119fc576040516304fb820960e51b81523460048201526024016107c5565b5090565b60007f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b031663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8491906129fc565b90506001600160a01b038116611aad576040516329b99a9560e11b815260040160405180910390fd5b6108506001600160a01b038216337f0000000000000000000000001a44076050125825900e736c501f859c50fe728c85611999565b600080602060008451602086016000885af180611b05576040513d6000823e3d81fd5b50506000513d91508115611b1d578060011415611b2a565b6001600160a01b0384163b155b156119d257604051635274afe760e01b81526001600160a01b03851660048201526024016107c5565b60405180606001604052806000801916815260200160006001600160401b03168152602001611b95604051806040016040528060008152602001600081525090565b905290565b600060e08284031215611bac57600080fd5b50919050565b600060208284031215611bc457600080fd5b81356001600160401b03811115611bda57600080fd5b6109e084828501611b9a565b60005b83811015611c01578181015183820152602001611be9565b50506000910152565b60008151808452611c22816020860160208601611be6565b601f01601f19169290920160200192915050565b8351815260208085015190820152600060a08201604060a0604085015281865180845260c08601915060c08160051b8701019350602080890160005b83811015611cb15788870360bf19018552815180518852830151838801879052611c9e87890182611c0a565b9750509382019390820190600101611c72565b505087516060880152505050602085015160808501525090506109e0565b600060608284031215611bac57600080fd5b60008083601f840112611cf357600080fd5b5081356001600160401b03811115611d0a57600080fd5b602083019150836020828501011115611d2257600080fd5b9250929050565b6001600160a01b0381168114610eae57600080fd5b600080600080600080600060e0888a031215611d5957600080fd5b611d638989611ccf565b96506060880135955060808801356001600160401b0380821115611d8657600080fd5b611d928b838c01611ce1565b909750955060a08a01359150611da782611d29565b90935060c08901359080821115611dbd57600080fd5b50611dca8a828b01611ce1565b989b979a50959850939692959293505050565b803563ffffffff81168114611df157600080fd5b919050565b60008060408385031215611e0957600080fd5b611e1283611ddd565b946020939093013593505050565b8015158114610eae57600080fd5b60008060408385031215611e4157600080fd5b82356001600160401b03811115611e5757600080fd5b611e6385828601611b9a565b9250506020830135611e7481611e20565b809150509250929050565b8151815260208083015190820152604081016108b7565b803561ffff81168114611df157600080fd5b60008060408385031215611ebb57600080fd5b611ec483611ddd565b9150611ed260208401611e96565b90509250929050565b6020815260006116196020830184611c0a565b600060208284031215611f0057600080fd5b813561161981611d29565b60008060008060a08587031215611f2157600080fd5b611f2b8686611ccf565b935060608501356001600160401b03811115611f4657600080fd5b611f5287828801611ce1565b9094509250506080850135611f6681611d29565b939692955090935050565b60008083601f840112611f8357600080fd5b5081356001600160401b03811115611f9a57600080fd5b6020830191508360208260051b8501011115611d2257600080fd5b60008060208385031215611fc857600080fd5b82356001600160401b03811115611fde57600080fd5b611fea85828601611f71565b90969095509350505050565b60006020828403121561200857600080fd5b61161982611ddd565b6000806000806060858703121561202757600080fd5b61203085611ddd565b935061203e60208601611e96565b925060408501356001600160401b0381111561205957600080fd5b61206587828801611ce1565b95989497509550505050565b6000806000838503608081121561208757600080fd5b84356001600160401b0381111561209d57600080fd5b6120a987828801611b9a565b9450506040601f19820112156120be57600080fd5b5060208401915060608401356120d381611d29565b809150509250925092565b600060c082019050835182526001600160401b0360208501511660208301526040840151612119604084018280518252602090810151910152565b5082516080830152602083015160a0830152611619565b60006060828403121561214257600080fd5b6116198383611ccf565b634e487b7160e01b600052604160045260246000fd5b600181811c9082168061217657607f821691505b602082108103611bac57634e487b7160e01b600052602260045260246000fd5b604051606081016001600160401b03811182821017156121b8576121b861214c565b60405290565b604080519081016001600160401b03811182821017156121b8576121b861214c565b604051601f8201601f191681016001600160401b03811182821017156122085761220861214c565b604052919050565b60006001600160401b038211156122295761222961214c565b50601f01601f191660200190565b60006001600160401b03808411156122515761225161214c565b8360051b60206122628183016121e0565b86815291850191818101903684111561227a57600080fd5b865b84811015612340578035868111156122945760008081fd5b880160603682900312156122a85760008081fd5b6122b0612196565b6122b982611ddd565b81526122c6868301611e96565b86820152604080830135898111156122de5760008081fd5b929092019136601f8401126122f35760008081fd5b823561230661230182612210565b6121e0565b818152368983870101111561231b5760008081fd5b818986018a83013760009181018901919091529082015284525091830191830161227c565b50979650505050505050565b6000808585111561235c57600080fd5b8386111561236957600080fd5b5050820193919092039150565b60008451612388818460208901611be6565b8201838582376000930192835250909392505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6020815260006109e060208301848661239e565b634e487b7160e01b600052603260045260246000fd5b6000823561013e1983360301811261240857600080fd5b9190910192915050565b6000808335601e1984360301811261242957600080fd5b8301803591506001600160401b0382111561244357600080fd5b602001915036819003821315611d2257600080fd5b6001600160401b0381168114610eae57600080fd5b63ffffffff61247b89611ddd565b168152602088013560208201526000604089013561249881612458565b6001600160401b03811660408401525087606083015260e060808301526124c360e08301878961239e565b6001600160a01b03861660a084015282810360c08401526124e581858761239e565b9a9950505050505050505050565b60006020828403121561250557600080fd5b81516001600160401b0381111561251b57600080fd5b8201601f8101841361252c57600080fd5b805161253a61230182612210565b81815285602083850101111561254f57600080fd5b611343826020830160208601611be6565b60006020828403121561257257600080fd5b813561161981612458565b60018060a01b038516815283602082015261ffff831660408201526080606082015260006125ae6080830184611c0a565b9695505050505050565b6040815260006125cb6040830185611c0a565b82810360208401526113438185611c0a565b6000602082840312156125ef57600080fd5b815161161981611e20565b6040815263ffffffff8351166040820152602083015160608201526000604084015160a0608084015261263060e0840182611c0a565b90506060850151603f198483030160a085015261264d8282611c0a565b60809690960151151560c08501525050506001600160a01b039190911660209091015290565b60006040828403121561268557600080fd5b61268d6121be565b9050815181526020820151602082015292915050565b6000604082840312156126b557600080fd5b6116198383612673565b601f821115611994576000816000526020600020601f850160051c810160208610156126e85750805b601f850160051c820191505b81811015612707578281556001016126f4565b505050505050565b81516001600160401b038111156127285761272861214c565b61273c816127368454612162565b846126bf565b602080601f83116001811461277157600084156127595750858301515b600019600386901b1c1916600185901b178555612707565b600085815260208120601f198616915b828110156127a057888601518255948401946001909101908401612781565b50858210156127be5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b8381101561284b57888303603f190185528151805163ffffffff1684528781015161ffff1688850152860151606087850181905261283781860183611c0a565b9689019694505050908601906001016127f7565b509098975050505050505050565b60006040828403121561286b57600080fd5b6128736121be565b82358152602083013560208201528091505092915050565b6000826128a857634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176108b757634e487b7160e01b600052601160045260246000fd5b803560208310156108b757600019602084900360031b1b1692915050565b6001600160c01b031981358181169160088510156129185780818660080360031b1b83161692505b505092915050565b6001600160401b0360c01b8560c01b16815263ffffffff60e01b8460e01b16600882015282600c8201526000825161295f81602c850160208701611be6565b91909101602c0195945050505050565b8481526001600160401b0360c01b8460c01b166020820152826028820152600082516129a2816048850160208701611be6565b9190910160480195945050505050565b6000608082840312156129c457600080fd5b6129cc612196565b8251815260208301516129de81612458565b60208201526129f08460408501612673565b60408201529392505050565b600060208284031215612a0e57600080fd5b815161161981611d2956fea26469706673582212207f40c76ec506a6d4547f0edcd18f0446f8ae35cc89647cd59d6247e42ed8250b64736f6c63430008160033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000a6e7ba5042b38349e437ec6db6214aec7b356760000000000000000000000001a44076050125825900e736c501f859c50fe728c000000000000000000000000af994551f4f940224825f54f810ed5439651e5f9
-----Decoded View---------------
Arg [0] : _token (address): 0x0a6E7Ba5042B38349e437ec6Db6214AEC7B35676
Arg [1] : _lzEndpoint (address): 0x1a44076050125825900e736c501f859c50fE728c
Arg [2] : _delegate (address): 0xaf994551f4f940224825F54F810ed5439651E5f9
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000000a6e7ba5042b38349e437ec6db6214aec7b35676
Arg [1] : 0000000000000000000000001a44076050125825900e736c501f859c50fe728c
Arg [2] : 000000000000000000000000af994551f4f940224825f54f810ed5439651e5f9
Deployed Bytecode Sourcemap
924:215:43:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5052:1258:25;;;;;;;;;;-1:-1:-1;5052:1258:25;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;2256:27;;;;;;;;;;-1:-1:-1;2256:27:25;;;;-1:-1:-1;;;;;2256:27:25;;;;;;-1:-1:-1;;;;;2732:32:45;;;2714:51;;2702:2;2687:18;2256:27:25;2568:203:45;4368:708:12;;;;;;:::i;:::-;;:::i;:::-;;2130:40:25;;;;;;;;;;;;2169:1;2130:40;;;;;4648:6:45;4636:19;;;4618:38;;4606:2;4591:18;2130:40:25;4474:188:45;3401:140:25;;;;;;;;;;-1:-1:-1;3401:140:25;;;-1:-1:-1;;;4837:52:45;;3532:1:25;4920:2:45;4905:18;;4898:59;4810:18;3401:140:25;4667:296:45;1287:235:10;;;;;;;;;;-1:-1:-1;1287:235:10;;;843:1:13;5175:34:45;;678:1:12;5240:2:45;5225:18;;5218:43;5111:18;1287:235:10;4968:299:45;2093:31:25;;;;;;;;;;;;2123:1;2093:31;;1724:108:11;;;;;;;;;;-1:-1:-1;1724:108:11;;;;;:::i;:::-;;:::i;6761:774:25:-;;;;;;;;;;-1:-1:-1;6761:774:25;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;875:93:19:-;;;;;;;;;;-1:-1:-1;956:4:19;875:93;;538::18;;;;;;;;;;-1:-1:-1;538:93:18;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;16009:132:25:-;;;;;;;;;;-1:-1:-1;16009:132:25;;;;;:::i;:::-;16114:11;;;;;16091:4;16114:11;;;:5;:11;;;;;;:20;;16009:132;;;;7385:14:45;;7378:22;7360:41;;7348:2;7333:18;16009:132:25;7220:187:45;446:46:11;;;;;;;;;;;;;;;4583:163:25;;;;;;;;;;-1:-1:-1;4583:163:25;;;;;:::i;:::-;;:::i;2293:101:29:-;;;;;;;;;;;;;:::i;3507:128:12:-;;;;;;;;;;-1:-1:-1;3507:128:12;;;;;:::i;:::-;3596:12;3507:128;;;;;;;;-1:-1:-1;;;;;8062:31:45;;;8044:50;;8032:2;8017:18;3507:128:12;7900:200:45;2013:216:12;;;;;;;;;;-1:-1:-1;2013:216:12;;;;;:::i;:::-;;:::i;4148:87:25:-;;;;;;;;;;-1:-1:-1;4148:87:25;;4227:1;8920:36:45;;8908:2;8893:18;4148:87:25;8778:184:45;1638:85:29;;;;;;;;;;-1:-1:-1;1684:7:29;1710:6;-1:-1:-1;;;;;1710:6:29;1638:85;;1787:46:25;;;;;;;;;;;;;;;;;;9113:25:45;;;9101:2;9086:18;1787:46:25;8967:177:45;2358:93:24;;;;;;;;;;-1:-1:-1;2440:4:24;2358:93;;559:23:19;;;;;;;;;;-1:-1:-1;559:23:19;;;;-1:-1:-1;;;;;559:23:19;;;1391:156:18;;;;;;;;;;-1:-1:-1;1391:156:18;;;;;:::i;:::-;;:::i;569:48:11:-;;;;;;;;;;-1:-1:-1;569:48:11;;;;;:::i;:::-;;;;;;;;;;;;;;3510:981:18;;;;;;;;;;-1:-1:-1;3510:981:18;;;;;:::i;:::-;;:::i;1698:1333:19:-;;;;;;:::i;:::-;;:::i;8223:290:25:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;3252:105:11:-;;;;;;;;;;-1:-1:-1;3252:105:11;;;;;:::i;:::-;;:::i;3679:409:19:-;;;;;;:::i;:::-;;:::i;1100:139::-;;;;;;;;;;-1:-1:-1;1100:139:19;;;;;:::i;:::-;;:::i;2543:215:29:-;;;;;;;;;;-1:-1:-1;2543:215:29;;;;;:::i;:::-;;:::i;1867:90:24:-;;;;;;;;;;-1:-1:-1;1939:10:24;1867:90;;2771:149:12;;;;;;;;;;-1:-1:-1;2771:149:12;;;;;:::i;:::-;;:::i;5052:1258:25:-;-1:-1:-1;;;;;;;;;;;;;;;;;5204:35:25;5241:28;-1:-1:-1;;;;;;;;;;;;;;;;;;;5241:28:25;5459:34;;;;;;;;-1:-1:-1;5459:34:25;;;-1:-1:-1;;;;;5459:34:25;;;;;;;5610:21;;;;;;;;;;;5459:34;;-1:-1:-1;;;5610:21:25;;;-1:-1:-1;;;;;;;;;;;;;;;;;5610:21:25;;;;;;;;;;;;;;;-1:-1:-1;5594:37:25;-1:-1:-1;6068:20:25;;6118:120;6142:19;;;;6175:22;;;;6211:17;;;;6142:10;6211:17;:::i;:::-;6118:10;:120::i;:::-;6261:42;;;;;;;;;;;;;;;;5052:1258;;;;-1:-1:-1;;;;;;5052:1258:25:o;4368:708:12:-;4681:8;-1:-1:-1;;;;;4673:31:12;4694:10;4673:31;4669:68;;4713:24;;-1:-1:-1;;;4713:24:12;;4726:10;4713:24;;;2714:51:45;2687:18;;4713:24:12;;;;;;;;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:12;;13337:10:45;13325:23;;;4896:40:12;;;13307:42:45;4921:14:12;;;;13365:18:45;;;13358:34;13280:18;;4896:40:12;13135:263:45;4833:103:12;5010:59;5021:7;5030:5;5037:8;;5047:9;5058:10;;5010;:59::i;:::-;4368:708;;;;;;;:::o;1724:108:11:-;1531:13:29;:11;:13::i;:::-;1804:21:11::1;1813:4;1819:5;1804:8;:21::i;:::-;1724:108:::0;;:::o;6761:774:25:-;-1:-1:-1;;;;;;;;;;;;;;;;;7095:24:25;7123:74;7134:19;;;;7155:22;;;;7179:17;;;;7134:10;7179:17;:::i;7123:74::-;7092:105;;;7286:20;7308;7332:49;7352:10;7364:16;7332:19;:49::i;:::-;7285:96;;-1:-1:-1;7285:96:25;-1:-1:-1;7470:58:25;7477:17;;;;:10;:17;:::i;:::-;7496:7;7505;7514:13;7470:6;:58::i;:::-;7463:65;;;;;6761:774;;;;;:::o;538:93:18:-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;4583:163:25:-;1531:13:29;:11;:13::i;:::-;4666:12:25::1;:28:::0;;-1:-1:-1;;;;;;4666:28:25::1;-1:-1:-1::0;;;;;4666:28:25;::::1;::::0;;::::1;::::0;;;4709:30:::1;::::0;2714:51:45;;;4709:30:25::1;::::0;2702:2:45;2687:18;4709:30:25::1;;;;;;;;4583: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:12:-;-1:-1:-1;;;;;2198:24:12;;2217:4;2198:24;2013:216;;;;;;;:::o;1391:156:18:-;1531:13:29;:11;:13::i;:::-;1503:37:18::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:18;;-1:-1:-1;3883:20:18;;-1:-1:-1;;;;3883:20:18;3857:46;3988:1;3964:25;;;3960:46;;3998:8;-1:-1:-1;3991:15:18;;3960:46;4153:1;4129:25;;4125:267;;4170:34;4190:13;;4170:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4170:19:18;;-1:-1:-1;;;4170:34:18: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:18;;;;;;;;;:::i;1698:1333:19:-;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:19;1987:20;;;;1854:43;1987:20;:::i;:::-;2009;;;;16114:11:25;;;;;16091:4;16114:11;;;:5;:11;;;;;;:20;;16009:132;1980:50:19;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:19;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;2978:45:19;;;;;;;;;;;;:::i;:::-;2961:63;;-1:-1:-1;;;2961:63:19;;;;;;;;:::i;8223:290:25:-;8384:34;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;8467:39:25;8473:10;8485:4;8491:14;8467:5;:39::i;:::-;8460:46;;;;8223:290;;;;;;;:::o;3252:105:11:-;1531:13:29;:11;:13::i;:::-;3319:31:11::1;::::0;-1:-1:-1;;;3319:31:11;;-1:-1:-1;;;;;2732:32:45;;;3319:31:11::1;::::0;::::1;2714:51:45::0;3319:8:11::1;:20;::::0;::::1;::::0;2687:18:45;;3319:31:11::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;3252:105:::0;:::o;3679:409:19:-;3958:10;3980:4;3958:27;3954:50;;3994:10;;-1:-1:-1;;;3994:10:19;;;;;;;;;;;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:19::1;:20:::0;;-1:-1:-1;;;;;;1175:20:19::1;-1:-1:-1::0;;;;;1175:20:19;::::1;::::0;;::::1;::::0;;;1210:22:::1;::::0;2714:51:45;;;1210:22:19::1;::::0;2702:2:45;2687:18;1210:22:19::1;2568:203:45::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:45::0;2687:18;;2672:31:29::1;2568:203:45::0;2623:91:29::1;2723:28;2742:8;2723:18;:28::i;:::-;2543:215:::0;:::o;2771:149:12:-;2853:4;2900:13;;;;;;2876:5;;2853:4;;2882:13;;2900:6;2882:13;:::i;:::-;2876:20;;;;;;;;;;;;;-1:-1:-1;2876:20:12;;:37;;2771:149;-1:-1:-1;;2771:149:12:o;18026:668:25:-;18168:20;18190:24;18364:22;18376:9;18364:11;:22::i;:::-;18349:37;;18512:12;18493:31;;18594:12;18575:16;:31;18571:117;;;18629:48;;-1:-1:-1;;;18629:48:25;;;;;21185:25:45;;;21226:18;;;21219:34;;;21158:18;;18629:48:25;21011:248:45;2718:196:11;2822:11;;;2788:7;2822:11;;;:5;:11;;;;;;;2843:43;;2874:12;;-1:-1:-1;;;2874:12:11;;21438:10:45;21426:23;;2874:12:11;;;21408:42:45;21381:18;;2874:12:11;21264:192:45;12802:1806:25;13279:17;13299:36;:17;:8;;:15;:17::i;:::-;2891:2:28;2780:123;13299:36:25;13279:56;;13468:24;13495:62;13503:9;13514:26;13520:19;:8;;:17;:19::i;:::-;13514:5;:26::i;:::-;13542:14;;;;:7;:14;:::i;:::-;13495:7;:62::i;:::-;13468:89;-1:-1:-1;243:2:28;-1:-1:-1;;13568:955:25;;;13672:23;13698:175;13741:13;;;;;;;;:::i;:::-;13772:14;;;;:7;:14;:::i;:::-;13804:16;13838:21;:8;;:19;:21::i;:::-;13698:25;:175::i;:::-;14420:92;;-1:-1:-1;;;14420:92:25;;13672:201;;-1:-1:-1;;;;;;14420:8:25;:20;;;;:92;;14441:9;;14452:5;;14459:1;;13672:201;;14420:92;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13595:928;13568:955;-1:-1:-1;;;;;14538:63:25;;14550:5;14538:63;14557:14;;;;:7;:14;:::i;:::-;14538:63;;;13337:10:45;13325:23;;;13307:42;;13380:2;13365:18;;13358:34;;;13280:18;14538:63:25;;;;;;;13105:1503;;12802:1806;;;;;;;:::o;1796:162:29:-;1684:7;1710:6;-1:-1:-1;;;;;1710:6:29;735:10:39;1855:23:29;1851:101;;1901:40;;-1:-1:-1;;;1901:40:29;;735:10:39;1901:40:29;;;2714:51:45;2687:18;;1901:40:29;2568:203:45;2286:134:11;2359:11;;;;;;;:5;:11;;;;;;;;;:19;;;2393:20;;13307:42:45;;;13365:18;;13358:34;;;2393:20:11;;13280:18:45;2393:20:11;;;;;;;2286:134;;:::o;10848:1436:25:-;10980:20;11002;11034:15;11205:324;11237:10;:13;;;11264:16;11270:9;11264:5;:16::i;:::-;11498:21;;;;:10;:21;:::i;:::-;11205:324;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11205:18:25;;-1:-1:-1;;;11205:324:25:i;:::-;11181:348;;-1:-1:-1;11181:348:25;-1:-1:-1;11609:14:25;11181:348;11626:33;;2123:1;11626:33;;;2169:1;11626:33;11609:50;-1:-1:-1;11781:67:25;11796:17;;;;:10;:17;:::i;:::-;11815:7;11824:23;;;;:10;:23;:::i;11781:67::-;12106:12;;11771:77;;-1:-1:-1;;;;;;12106:12:25;12198:23;;12194:83;;12223:54;;-1:-1:-1;;;12223:54:25;;-1:-1:-1;;;;;12223:36:25;;;;;:54;;12260:7;;12269;;12223:54;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;12194:83;11024:1260;;;10848:1436;;;;;:::o;2038:391:13:-;-1:-1:-1;;;;;;;;;;;;;;;;;2259:8:13;-1:-1:-1;;;;;2259:14:13;;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:13: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:18:-;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:18;;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:18;;;;;;;;:::i;9221:1333:25:-;9375:34;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;9773:20:25;;9823:140;9843:10;9867:19;;;;9900:22;;;;9936:17;;;;9867:10;9936:17;:::i;:::-;9823:6;:140::i;:::-;9772:191;;;;10052:20;10074;10098:49;10118:10;10130:16;10098:19;:49::i;:::-;10051:96;;-1:-1:-1;10051:96:25;-1:-1:-1;10270:66:25;10278:17;;;;:10;:17;:::i;:::-;10297:7;10306;10270:66;;;;;;;10315:4;10270:66;:::i;:::-;10321:14;10270:7;:66::i;:::-;10402:42;;;;;;;;;;;;;;;;;;;10468:15;;10257:79;;-1:-1:-1;10402:42:25;;-1:-1:-1;10504:10:25;;10468:15;10460:87;;10485:17;;;;:10;:17;:::i;:::-;10460:87;;;28479:10:45;28467:23;;;28449:42;;28522:2;28507:18;;28500:34;;;28550:18;;28543:34;;;28437:2;28422:18;10460:87:25;;;;;;;9441:1113;;;;9221:1333;;;;;;:::o;16535:172::-;16606:16;16679:21;16642:33;16679:21;16642:9;:33;:::i;:::-;16641:59;;;;:::i;1573:123:28:-;1633:7;1667:21;188:2;1633:7;1667:4;;:21;:::i;:::-;1659:30;;;:::i;:::-;1652:37;1573:123;-1:-1:-1;;;1573:123:28: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:28:o;16931:139:25:-;16995:16;17030:33;17042:21;-1:-1:-1;;;;;17030:33:25;;;:::i;4450:409:24:-;4584:24;4685:39;-1:-1:-1;;;;;4685:10:24;:23;4709:3;4714:9;4685:23;:39::i;:::-;-1:-1:-1;4843:9:24;;4450:409;-1:-1:-1;;4450:409:24:o;2186:130:28:-;2250:12;2281:28;:4;243:2;2281:4;;:28;:::i;:::-;2274:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2274:35:28;;2186:130;-1:-1:-1;;;;;;2186:130:28:o;640:284:27:-;824:17;877:6;885:7;894:9;905:11;860:57;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;853:64;;640:284;;;;;;:::o;17294:147:25:-;17359:15;17400:33;17412:21;17400:9;:33;:::i;598:506:28:-;791:18;;732:17;;791:22;;;934:163;;1074:7;1083:13;1057:40;;;;;;;;30404:19:45;;;30479:3;30457:16;-1:-1:-1;;;;;;30453:51:45;30448:2;30439:12;;30432:73;30530:2;30521:12;;30249:290;1057:40:28;;;;;;;;;;;;;934:163;;;976:7;985:13;1017:10;1030:11;959:83;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;934:163;927:170;;598:506;;;;;;:::o;3352:457:24:-;3513:20;3535:24;3606:44;3617:9;3628:12;3642:7;3606:10;:44::i;:::-;3571:79;;-1:-1:-1;3571:79:24;-1:-1:-1;3739:63:24;-1:-1:-1;;;;;3739:10:24;:27;3767:5;3782:4;3571:79;3739:27;:63::i;:::-;3352:457;;;;;;;:::o;3188:766:13:-;3389:31;;:::i;:::-;3554:20;3577:26;3588:4;:14;;;3577:10;:26::i;:::-;3617:15;;;;3554:49;;-1:-1:-1;3617:19:13;3613:53;;3638:28;3650:4;:15;;;3638:11;:28::i;:::-;3755:8;-1:-1:-1;;;;;3755:13:13;;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:13:o;1271:160:37:-;1380:43;;-1:-1:-1;;;;;31801:32:45;;;1380:43:37;;;31783:51:45;31850:18;;;31843:34;;;1353:71:37;;1373:5;;1395:14;;;;;31756:18:45;;1380:43:37;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1380:43:37;;;;;;;;;;;1353:19;:71::i;:::-;1271:160;;;:::o;1670:188::-;1797:53;;-1:-1:-1;;;;;32146:15:45;;;1797:53:37;;;32128:34:45;32198:15;;;32178:18;;;32171:43;32230:18;;;32223:34;;;1770:81:37;;1790:5;;1812:18;;;;;32063::45;;1797:53:37;31888:375:45;1770:81:37;1670:188;;;;:::o;4650:191:13:-;4716:17;4762:10;4749:9;:23;4745:62;;4781:26;;-1:-1:-1;;;4781:26:13;;4797:9;4781:26;;;9113:25:45;9086:18;;4781:26:13;8967:177:45;4745:62:13;-1:-1:-1;4824:10:13;4650:191::o;5218:410::-;5371:15;5389:8;-1:-1:-1;;;;;5389:16:13;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5371:36;-1:-1:-1;;;;;;5421:21:13;;5417:54;;5451:20;;-1:-1:-1;;;5451:20:13;;;;;;;;;;;5417:54;5545:76;-1:-1:-1;;;;;5545:32:13;;5578:10;5598:8;5609:11;5545:32;:76::i;7738:720:37:-;7818:18;7846:19;7984:4;7981:1;7974:4;7968:11;7961:4;7955;7951:15;7948:1;7941:5;7934;7929:60;8041:7;8031:176;;8085:4;8079:11;8130:16;8127:1;8122:3;8107:40;8176:16;8171:3;8164:29;8031:176;-1:-1:-1;;8284:1:37;8278:8;8234:16;;-1:-1:-1;8310:15:37;;:68;;8362:11;8377:1;8362:16;;8310:68;;;-1:-1:-1;;;;;8328:26:37;;;:31;8310:68;8306:146;;;8401:40;;-1:-1:-1;;;8401:40:37;;-1:-1:-1;;;;;2732:32:45;;8401:40:37;;;2714:51:45;2687:18;;8401:40:37;2568:203:45;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:158:45:-;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:45;14:158;-1:-1:-1;14:158:45: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:45;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:45;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:45;1170:39;;;;1211:4;1166:50;;951:271;-1:-1:-1;;951:271:45: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:45;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:45;;;;2414:15;;;;2078:1;2071:9;2042:429;;;-1:-1:-1;;616:12:45;;2553:2;2538:18;;604:25;-1:-1:-1;;;678:4:45;667:16;;661:23;645:14;;;638:47;-1:-1:-1;2488:6:45;-1:-1:-1;2503:54:45;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:45;;-1:-1:-1;;;;;3123:30:45;;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:45;;3352:42;;3342:70;;3408:1;3405;3398:12;3423:1046;3564:6;3572;3580;3588;3596;3604;3612;3665:3;3653:9;3644:7;3640:23;3636:33;3633:53;;;3682:1;3679;3672:12;3633:53;3705;3750:7;3739:9;3705:53;:::i;:::-;3695:63;;3805:2;3794:9;3790:18;3777:32;3767:42;;3860:3;3849:9;3845:19;3832:33;-1:-1:-1;;;;;3925:2:45;3917:6;3914:14;3911:34;;;3941:1;3938;3931:12;3911:34;3980:58;4030:7;4021:6;4010:9;4006:22;3980:58;:::i;:::-;4057:8;;-1:-1:-1;3954:84:45;-1:-1:-1;4142:3:45;4127:19;;4114:33;;-1:-1:-1;4156:31:45;4114:33;4156:31;:::i;:::-;4206:5;;-1:-1:-1;4264:3:45;4249:19;;4236:33;;4281:16;;;4278:36;;;4310:1;4307;4300:12;4278:36;;4349:60;4401:7;4390:8;4379:9;4375:24;4349:60;:::i;:::-;3423:1046;;;;-1:-1:-1;3423:1046:45;;-1:-1:-1;3423:1046:45;;;;4323:86;;-1:-1:-1;;;3423:1046:45:o;5272:163::-;5339:20;;5399:10;5388:22;;5378:33;;5368:61;;5425:1;5422;5415:12;5368:61;5272:163;;;:::o;5440:252::-;5507:6;5515;5568:2;5556:9;5547:7;5543:23;5539:32;5536:52;;;5584:1;5581;5574:12;5536:52;5607:28;5625:9;5607:28;:::i;:::-;5597:38;5682:2;5667:18;;;;5654:32;;-1:-1:-1;;;5440:252:45:o;5697:118::-;5783:5;5776:13;5769:21;5762:5;5759:32;5749:60;;5805:1;5802;5795:12;5820:489;5914:6;5922;5975:2;5963:9;5954:7;5950:23;5946:32;5943:52;;;5991:1;5988;5981:12;5943:52;6031:9;6018:23;-1:-1:-1;;;;;6056:6:45;6053:30;6050:50;;;6096:1;6093;6086:12;6050:50;6119:69;6180:7;6171:6;6160:9;6156:22;6119:69;:::i;:::-;6109:79;;;6238:2;6227:9;6223:18;6210:32;6251:28;6273:5;6251:28;:::i;:::-;6298:5;6288:15;;;5820:489;;;;;:::o;6314:253::-;616:12;;604:25;;678:4;667:16;;;661:23;645:14;;;638:47;6504:2;6489:18;;6516:45;542:149;6572:159;6639:20;;6699:6;6688:18;;6678:29;;6668:57;;6721:1;6718;6711:12;6736:256;6802:6;6810;6863:2;6851:9;6842:7;6838:23;6834:32;6831:52;;;6879:1;6876;6869:12;6831:52;6902:28;6920:9;6902:28;:::i;:::-;6892:38;;6949:37;6982:2;6971:9;6967:18;6949:37;:::i;:::-;6939:47;;6736:256;;;;;:::o;6997:218::-;7144:2;7133:9;7126:21;7107:4;7164:45;7205:2;7194:9;7190:18;7182:6;7164:45;:::i;7648:247::-;7707:6;7760:2;7748:9;7739:7;7735:23;7731:32;7728:52;;;7776:1;7773;7766:12;7728:52;7815:9;7802:23;7834:31;7859:5;7834:31;:::i;8105:668::-;8217:6;8225;8233;8241;8294:3;8282:9;8273:7;8269:23;8265:33;8262:53;;;8311:1;8308;8301:12;8262:53;8334;8379:7;8368:9;8334:53;:::i;:::-;8324:63;;8438:2;8427:9;8423:18;8410:32;-1:-1:-1;;;;;8457:6:45;8454:30;8451:50;;;8497:1;8494;8487:12;8451:50;8536:58;8586:7;8577:6;8566:9;8562:22;8536:58;:::i;:::-;8613:8;;-1:-1:-1;8510:84:45;-1:-1:-1;;8698:3:45;8683:19;;8670:33;8712:31;8670:33;8712:31;:::i;:::-;8105:668;;;;-1:-1:-1;8105:668:45;;-1:-1:-1;;8105:668:45:o;9149:395::-;9240:8;9250:6;9304:3;9297:4;9289:6;9285:17;9281:27;9271:55;;9322:1;9319;9312:12;9271:55;-1:-1:-1;9345:20:45;;-1:-1:-1;;;;;9377:30:45;;9374:50;;;9420:1;9417;9410:12;9374:50;9457:4;9449:6;9445:17;9433:29;;9517:3;9510:4;9500:6;9497:1;9493:14;9485:6;9481:27;9477:38;9474:47;9471:67;;;9534:1;9531;9524:12;9549:504;9674:6;9682;9735:2;9723:9;9714:7;9710:23;9706:32;9703:52;;;9751:1;9748;9741:12;9703:52;9791:9;9778:23;-1:-1:-1;;;;;9816:6:45;9813:30;9810:50;;;9856:1;9853;9846:12;9810:50;9895:98;9985:7;9976:6;9965:9;9961:22;9895:98;:::i;:::-;10012:8;;9869:124;;-1:-1:-1;9549:504:45;-1:-1:-1;;;;9549:504:45:o;10058:184::-;10116:6;10169:2;10157:9;10148:7;10144:23;10140:32;10137:52;;;10185:1;10182;10175:12;10137:52;10208:28;10226:9;10208:28;:::i;10429:553::-;10515:6;10523;10531;10539;10592:2;10580:9;10571:7;10567:23;10563:32;10560:52;;;10608:1;10605;10598:12;10560:52;10631:28;10649:9;10631:28;:::i;:::-;10621:38;;10678:37;10711:2;10700:9;10696:18;10678:37;:::i;:::-;10668:47;;10766:2;10755:9;10751:18;10738:32;-1:-1:-1;;;;;10785:6:45;10782:30;10779:50;;;10825:1;10822;10815:12;10779:50;10864:58;10914:7;10905:6;10894:9;10890:22;10864:58;:::i;:::-;10429:553;;;;-1:-1:-1;10941:8:45;-1:-1:-1;;;;10429:553:45:o;11490:655::-;11626:6;11634;11642;11686:9;11677:7;11673:23;11716:3;11712:2;11708:12;11705:32;;;11733:1;11730;11723:12;11705:32;11773:9;11760:23;-1:-1:-1;;;;;11798:6:45;11795:30;11792:50;;;11838:1;11835;11828:12;11792:50;11861:69;11922:7;11913:6;11902:9;11898:22;11861:69;:::i;:::-;11851:79;-1:-1:-1;;11964:2:45;-1:-1:-1;;11946:16:45;;11942:25;11939:45;;;11980:1;11977;11970:12;11939:45;;12018:2;12007:9;12003:18;11993:28;;12071:2;12060:9;12056:18;12043:32;12084:31;12109:5;12084:31;:::i;:::-;12134:5;12124:15;;;11490:655;;;;;:::o;12150:609::-;12390:4;12432:3;12421:9;12417:19;12409:27;;12469:6;12463:13;12452:9;12445:32;-1:-1:-1;;;;;12537:4:45;12529:6;12525:17;12519:24;12515:49;12508:4;12497:9;12493:20;12486:79;12612:4;12604:6;12600:17;12594:24;12627:62;12683:4;12672:9;12668:20;12654:12;616;;604:25;;678:4;667:16;;;661:23;645:14;;638:47;542:149;12627:62;-1:-1:-1;616:12:45;;12748:3;12733:19;;604:25;678:4;667:16;;661:23;645:14;;;638:47;12698:55;542:149;12764:234;12847:6;12900:2;12888:9;12879:7;12875:23;12871:32;12868:52;;;12916:1;12913;12906:12;12868:52;12939:53;12984:7;12973:9;12939:53;:::i;13003:127::-;13064:10;13059:3;13055:20;13052:1;13045:31;13095:4;13092:1;13085:15;13119:4;13116:1;13109:15;13403:380;13482:1;13478:12;;;;13525;;;13546:61;;13600:4;13592:6;13588:17;13578:27;;13546:61;13653:2;13645:6;13642:14;13622:18;13619:38;13616:161;;13699:10;13694:3;13690:20;13687:1;13680:31;13734:4;13731:1;13724:15;13762:4;13759:1;13752:15;13788:253;13860:2;13854:9;13902:4;13890:17;;-1:-1:-1;;;;;13922:34:45;;13958:22;;;13919:62;13916:88;;;13984:18;;:::i;:::-;14020:2;14013:22;13788:253;:::o;14046:257::-;14118:4;14112:11;;;14150:17;;-1:-1:-1;;;;;14182:34:45;;14218:22;;;14179:62;14176:88;;;14244:18;;:::i;14308:275::-;14379:2;14373:9;14444:2;14425:13;;-1:-1:-1;;14421:27:45;14409:40;;-1:-1:-1;;;;;14464:34:45;;14500:22;;;14461:62;14458:88;;;14526:18;;:::i;:::-;14562:2;14555:22;14308:275;;-1:-1:-1;14308:275:45:o;14588:186::-;14636:4;-1:-1:-1;;;;;14661:6:45;14658:30;14655:56;;;14691:18;;:::i;:::-;-1:-1:-1;14757:2:45;14736:15;-1:-1:-1;;14732:29:45;14763:4;14728:40;;14588:186::o;14779:2117::-;14971:9;-1:-1:-1;;;;;15046:2:45;15038:6;15035:14;15032:40;;;15052:18;;:::i;:::-;15098:6;15095:1;15091:14;15124:4;15148:28;15172:2;15168;15164:11;15148:28;:::i;:::-;15210:19;;;15280:14;;;;15245:12;;;;15317:14;15306:26;;15303:46;;;15345:1;15342;15335:12;15303:46;15369:5;15383:1480;15399:6;15394:3;15391:15;15383:1480;;;15485:3;15472:17;15521:2;15508:11;15505:19;15502:109;;;15565:1;15594:2;15590;15583:14;15502:109;15634:23;;15702:4;15681:14;15677:23;;;15673:34;15670:124;;;15748:1;15777:2;15773;15766:14;15670:124;15822:22;;:::i;:::-;15873:21;15891:2;15873:21;:::i;:::-;15864:7;15857:38;15933:30;15959:2;15955;15951:11;15933:30;:::i;:::-;15928:2;15919:7;15915:16;15908:56;15987:2;16037;16033;16029:11;16016:25;16068:2;16060:6;16057:14;16054:104;;;16112:1;16141:2;16137;16130:14;16054:104;16181:15;;;;;16238:14;16231:4;16223:13;;16219:34;16209:135;;16296:1;16326:3;16321;16314:16;16209:135;16381:2;16368:16;16410:49;16426:32;16454:3;16426:32;:::i;:::-;16410:49;:::i;:::-;16486:3;16479:5;16472:18;16532:14;16527:2;16521:3;16517:2;16513:12;16509:21;16506:41;16503:134;;;16589:1;16619:3;16614;16607:16;16503:134;16692:3;16687:2;16683;16679:11;16674:2;16667:5;16663:14;16650:46;16742:1;16720:15;;;16716:24;;16709:35;;;;16764:16;;;16757:31;16801:20;;-1:-1:-1;16841:12:45;;;;15416;;15383:1480;;;-1:-1:-1;16885:5:45;14779:2117;-1:-1:-1;;;;;;;14779:2117:45:o;16901:331::-;17006:9;17017;17059:8;17047:10;17044:24;17041:44;;;17081:1;17078;17071:12;17041:44;17110:6;17100:8;17097:20;17094:40;;;17130:1;17127;17120:12;17094:40;-1:-1:-1;;17156:23:45;;;17201:25;;;;;-1:-1:-1;16901:331:45:o;17237:476::-;17428:3;17466:6;17460:13;17482:66;17541:6;17536:3;17529:4;17521:6;17517:17;17482:66;:::i;:::-;17570:16;;17623:6;17615;17570:16;17595:35;17687:1;17649:18;;17676:13;;;-1:-1:-1;17649:18:45;;17237:476;-1:-1:-1;;;17237:476:45:o;17718:266::-;17806:6;17801:3;17794:19;17858:6;17851:5;17844:4;17839:3;17835:14;17822:43;-1:-1:-1;17910:1:45;17885:16;;;17903:4;17881:27;;;17874:38;;;;17966:2;17945:15;;;-1:-1:-1;;17941:29:45;17932:39;;;17928:50;;17718:266::o;17989:244::-;18146:2;18135:9;18128:21;18109:4;18166:61;18223:2;18212:9;18208:18;18200:6;18192;18166:61;:::i;18238:127::-;18299:10;18294:3;18290:20;18287:1;18280:31;18330:4;18327:1;18320:15;18354:4;18351:1;18344:15;18370:331;18469:4;18527:11;18514:25;18621:3;18617:8;18606;18590:14;18586:29;18582:44;18562:18;18558:69;18548:97;;18641:1;18638;18631:12;18548:97;18662:33;;;;;18370:331;-1:-1:-1;;18370:331:45:o;18706:521::-;18783:4;18789:6;18849:11;18836:25;18943:2;18939:7;18928:8;18912:14;18908:29;18904:43;18884:18;18880:68;18870:96;;18962:1;18959;18952:12;18870:96;18989:33;;19041:20;;;-1:-1:-1;;;;;;19073:30:45;;19070:50;;;19116:1;19113;19106:12;19070:50;19149:4;19137:17;;-1:-1:-1;19180:14:45;19176:27;;;19166:38;;19163:58;;;19217:1;19214;19207:12;19232:129;-1:-1:-1;;;;;19310:5:45;19306:30;19299:5;19296:41;19286:69;;19351:1;19348;19341:12;19366:988;19740:10;19713:25;19731:6;19713:25;:::i;:::-;19709:42;19698:9;19691:61;19815:4;19807:6;19803:17;19790:31;19783:4;19772:9;19768:20;19761:61;19672:4;19869;19861:6;19857:17;19844:31;19884:30;19908:5;19884:30;:::i;:::-;-1:-1:-1;;;;;19956:5:45;19952:30;19945:4;19934:9;19930:20;19923:60;;20019:6;20014:2;20003:9;19999:18;19992:34;20063:3;20057;20046:9;20042:19;20035:32;20090:62;20147:3;20136:9;20132:19;20124:6;20116;20090:62;:::i;:::-;-1:-1:-1;;;;;20189:32:45;;20209:3;20168:19;;20161:61;20259:22;;;20253:3;20238:19;;20231:51;20299:49;20263:6;20333;20325;20299:49;:::i;:::-;20291:57;19366:988;-1:-1:-1;;;;;;;;;;19366:988:45:o;20359:647::-;20438:6;20491:2;20479:9;20470:7;20466:23;20462:32;20459:52;;;20507:1;20504;20497:12;20459:52;20540:9;20534:16;-1:-1:-1;;;;;20565:6:45;20562:30;20559:50;;;20605:1;20602;20595:12;20559:50;20628:22;;20681:4;20673:13;;20669:27;-1:-1:-1;20659:55:45;;20710:1;20707;20700:12;20659:55;20739:2;20733:9;20764:48;20780:31;20808:2;20780:31;:::i;20764:48::-;20835:2;20828:5;20821:17;20875:7;20870:2;20865;20861;20857:11;20853:20;20850:33;20847:53;;;20896:1;20893;20886:12;20847:53;20909:67;20973:2;20968;20961:5;20957:14;20952:2;20948;20944:11;20909:67;:::i;21461:245::-;21519:6;21572:2;21560:9;21551:7;21547:23;21543:32;21540:52;;;21588:1;21585;21578:12;21540:52;21627:9;21614:23;21646:30;21670:5;21646:30;:::i;21711:479::-;21978:1;21974;21969:3;21965:11;21961:19;21953:6;21949:32;21938:9;21931:51;22018:6;22013:2;22002:9;21998:18;21991:34;22073:6;22065;22061:19;22056:2;22045:9;22041:18;22034:47;22117:3;22112:2;22101:9;22097:18;22090:31;21912:4;22138:46;22179:3;22168:9;22164:19;22156:6;22138:46;:::i;:::-;22130:54;21711:479;-1:-1:-1;;;;;;21711:479:45:o;22463:379::-;22656:2;22645:9;22638:21;22619:4;22682:45;22723:2;22712:9;22708:18;22700:6;22682:45;:::i;:::-;22775:9;22767:6;22763:22;22758:2;22747:9;22743:18;22736:50;22803:33;22829:6;22821;22803:33;:::i;22847:245::-;22914:6;22967:2;22955:9;22946:7;22942:23;22938:32;22935:52;;;22983:1;22980;22973:12;22935:52;23015:9;23009:16;23034:28;23056:5;23034:28;:::i;23097:887::-;23316:2;23305:9;23298:21;23374:10;23365:6;23359:13;23355:30;23350:2;23339:9;23335:18;23328:58;23440:4;23432:6;23428:17;23422:24;23417:2;23406:9;23402:18;23395:52;23279:4;23494:2;23486:6;23482:15;23476:22;23535:4;23529:3;23518:9;23514:19;23507:33;23563:52;23610:3;23599:9;23595:19;23581:12;23563:52;:::i;:::-;23549:66;;23664:2;23656:6;23652:15;23646:22;23738:2;23734:7;23722:9;23714:6;23710:22;23706:36;23699:4;23688:9;23684:20;23677:66;23766:41;23800:6;23784:14;23766:41;:::i;:::-;23876:3;23864:16;;;;23858:23;23851:31;23844:39;23838:3;23823:19;;23816:68;-1:-1:-1;;;;;;;;23945:32:45;;;;23938:4;23923:20;;;23916:62;23752:55;23097:887::o;23989:284::-;24059:5;24107:4;24095:9;24090:3;24086:19;24082:30;24079:50;;;24125:1;24122;24115:12;24079:50;24147:22;;:::i;:::-;24138:31;;24198:9;24192:16;24185:5;24178:31;24262:2;24251:9;24247:18;24241:25;24236:2;24229:5;24225:14;24218:49;23989:284;;;;:::o;24278:257::-;24376:6;24429:2;24417:9;24408:7;24404:23;24400:32;24397:52;;;24445:1;24442;24435:12;24397:52;24468:61;24521:7;24510:9;24468:61;:::i;24665:542::-;24766:2;24761:3;24758:11;24755:446;;;24802:1;24826:5;24823:1;24816:16;24870:4;24867:1;24857:18;24940:2;24928:10;24924:19;24921:1;24917:27;24911:4;24907:38;24976:4;24964:10;24961:20;24958:47;;;-1:-1:-1;24999:4:45;24958:47;25054:2;25049:3;25045:12;25042:1;25038:20;25032:4;25028:31;25018:41;;25109:82;25127:2;25120:5;25117:13;25109:82;;;25172:17;;;25153:1;25142:13;25109:82;;;25113:3;;;24665:542;;;:::o;25383:1341::-;25507:3;25501:10;-1:-1:-1;;;;;25526:6:45;25523:30;25520:56;;;25556:18;;:::i;:::-;25585:96;25674:6;25634:38;25666:4;25660:11;25634:38;:::i;:::-;25628:4;25585:96;:::i;:::-;25736:4;;25793:2;25782:14;;25810:1;25805:662;;;;26511:1;26528:6;26525:89;;;-1:-1:-1;26580:19:45;;;26574:26;26525:89;-1:-1:-1;;25340:1:45;25336:11;;;25332:24;25328:29;25318:40;25364:1;25360:11;;;25315:57;26627:81;;25775:943;;25805:662;24612:1;24605:14;;;24649:4;24636:18;;-1:-1:-1;;25841:20:45;;;25958:236;25972:7;25969:1;25966:14;25958:236;;;26061:19;;;26055:26;26040:42;;26153:27;;;;26121:1;26109:14;;;;25988:19;;25958:236;;;25962:3;26222:6;26213:7;26210:19;26207:201;;;26283:19;;;26277:26;-1:-1:-1;;26366:1:45;26362:14;;;26378:3;26358:24;26354:37;26350:42;26335:58;26320:74;;26207:201;-1:-1:-1;;;;;26454:1:45;26438:14;;;26434:22;26421:36;;-1:-1:-1;25383:1341:45:o;26729:1164::-;26945:4;26974:2;27014;27003:9;26999:18;27044:2;27033:9;27026:21;27067:6;27102;27096:13;27133:6;27125;27118:22;27159:2;27149:12;;27192:2;27181:9;27177:18;27170:25;;27254:2;27244:6;27241:1;27237:14;27226:9;27222:30;27218:39;27292:2;27284:6;27280:15;27313:1;27323:541;27337:6;27334:1;27331:13;27323:541;;;27402:22;;;-1:-1:-1;;27398:36:45;27386:49;;27458:13;;27530:9;;27541:10;27526:26;27511:42;;27600:11;;;27594:18;27614:6;27590:31;27573:15;;;27566:56;27661:11;;27655:18;27494:4;27693:15;;;27686:27;;;27736:48;27768:15;;;27655:18;27736:48;:::i;:::-;27842:12;;;;27726:58;-1:-1:-1;;;27807:15:45;;;;27359:1;27352:9;27323:541;;;-1:-1:-1;27881:6:45;;26729:1164;-1:-1:-1;;;;;;;;26729:1164:45:o;27898:346::-;27985:6;28038:2;28026:9;28017:7;28013:23;28009:32;28006:52;;;28054:1;28051;28044:12;28006:52;28080:22;;:::i;:::-;28138:9;28125:23;28118:5;28111:38;28209:2;28198:9;28194:18;28181:32;28176:2;28169:5;28165:14;28158:56;28233:5;28223:15;;;27898:346;;;;:::o;28588:217::-;28628:1;28654;28644:132;;28698:10;28693:3;28689:20;28686:1;28679:31;28733:4;28730:1;28723:15;28761:4;28758:1;28751:15;28644:132;-1:-1:-1;28790:9:45;;28588:217::o;28810:265::-;28883:9;;;28914;;28931:15;;;28925:22;;28911:37;28901:168;;28991:10;28986:3;28982:20;28979:1;28972:31;29026:4;29023:1;29016:15;29054:4;29051:1;29044:15;29080:255;29200:19;;29239:2;29231:11;;29228:101;;;-1:-1:-1;;29300:2:45;29296:12;;;29293:1;29289:20;29285:33;29274:45;29080:255;;;;:::o;29340:331::-;-1:-1:-1;;;;;;29460:19:45;;29544:11;;;;29575:1;29567:10;;29564:101;;;29652:2;29646;29639:3;29636:1;29632:11;29629:1;29625:19;29621:28;29617:2;29613:37;29609:46;29600:55;;29564:101;;;29340:331;;;;:::o;29676:568::-;-1:-1:-1;;;;;29941:3:45;29937:28;29928:6;29923:3;29919:16;29915:51;29910:3;29903:64;30027:10;30022:3;30018:20;30009:6;30004:3;30000:16;29996:43;29992:1;29987:3;29983:11;29976:64;30070:6;30065:2;30060:3;30056:12;30049:28;29885:3;30106:6;30100:13;30122:75;30190:6;30185:2;30180:3;30176:12;30169:4;30161:6;30157:17;30122:75;:::i;:::-;30217:16;;;;30235:2;30213:25;;29676:568;-1:-1:-1;;;;;29676:568:45:o;30544:532::-;30785:6;30780:3;30773:19;-1:-1:-1;;;;;30848:3:45;30844:28;30835:6;30830:3;30826:16;30822:51;30817:2;30812:3;30808:12;30801:73;30904:6;30899:2;30894:3;30890:12;30883:28;30755:3;30940:6;30934:13;30956:73;31022:6;31017:2;31012:3;31008:12;31003:2;30995:6;30991:15;30956:73;:::i;:::-;31049:16;;;;31067:2;31045:25;;30544:532;-1:-1:-1;;;;;30544:532:45:o;31081:523::-;31183:6;31236:3;31224:9;31215:7;31211:23;31207:33;31204:53;;;31253:1;31250;31243:12;31204:53;31279:22;;:::i;:::-;31330:9;31324:16;31317:5;31310:31;31386:2;31375:9;31371:18;31365:25;31399:32;31423:7;31399:32;:::i;:::-;31458:2;31447:14;;31440:31;31503:70;31565:7;31560:2;31545:18;;31503:70;:::i;:::-;31498:2;31487:14;;31480:94;31491:5;31081:523;-1:-1:-1;;;31081:523:45:o;32268:251::-;32338:6;32391:2;32379:9;32370:7;32366:23;32362:32;32359:52;;;32407:1;32404;32397:12;32359:52;32439:9;32433:16;32458:31;32483:5;32458:31;:::i
Swarm Source
ipfs://7f40c76ec506a6d4547f0edcd18f0446f8ae35cc89647cd59d6247e42ed8250b
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $0.034529 | 62,581,082.4369 | $2,160,869.08 |
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.