Source Code
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 194 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Approve | 24566123 | 58 mins ago | IN | 0 ETH | 0.00000324 | ||||
| Approve | 24563291 | 10 hrs ago | IN | 0 ETH | 0.00000251 | ||||
| Send | 24558123 | 27 hrs ago | IN | 0.00021707 ETH | 0.00001334 | ||||
| Migrate | 24558120 | 27 hrs ago | IN | 0 ETH | 0.00000414 | ||||
| Migrate | 24554948 | 38 hrs ago | IN | 0 ETH | 0.00005252 | ||||
| Migrate | 24553193 | 44 hrs ago | IN | 0 ETH | 0.00000531 | ||||
| Send | 24552294 | 47 hrs ago | IN | 0.00021707 ETH | 0.00001027 | ||||
| Migrate | 24552290 | 47 hrs ago | IN | 0 ETH | 0.00000322 | ||||
| Send | 24551425 | 2 days ago | IN | 0.00023877 ETH | 0.00007883 | ||||
| Migrate | 24548357 | 2 days ago | IN | 0 ETH | 0.00002045 | ||||
| Migrate | 24547293 | 2 days ago | IN | 0 ETH | 0.00000751 | ||||
| Migrate | 24546944 | 2 days ago | IN | 0 ETH | 0.0000187 | ||||
| Migrate | 24546539 | 2 days ago | IN | 0 ETH | 0.00000614 | ||||
| Migrate | 24544618 | 3 days ago | IN | 0 ETH | 0.00000629 | ||||
| Send | 24542417 | 3 days ago | IN | 0.00021707 ETH | 0.00017257 | ||||
| Migrate | 24542411 | 3 days ago | IN | 0 ETH | 0.00003574 | ||||
| Migrate | 24541962 | 3 days ago | IN | 0 ETH | 0.00003147 | ||||
| Migrate | 24540228 | 3 days ago | IN | 0 ETH | 0.00000637 | ||||
| Send | 24540217 | 3 days ago | IN | 0.00002705 ETH | 0.00001027 | ||||
| Send | 24538579 | 3 days ago | IN | 0.00021707 ETH | 0.00046515 | ||||
| Migrate | 24538566 | 3 days ago | IN | 0 ETH | 0.00010385 | ||||
| Send | 24538472 | 3 days ago | IN | 0.00021707 ETH | 0.00046807 | ||||
| Migrate | 24538460 | 3 days ago | IN | 0 ETH | 0.00010401 | ||||
| Send | 24538287 | 3 days ago | IN | 0.00021707 ETH | 0.00046622 | ||||
| Send | 24538264 | 3 days ago | IN | 0.00021707 ETH | 0.00046527 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| Send | 24558123 | 27 hrs ago | 0.00021707 ETH | ||||
| Send | 24552294 | 47 hrs ago | 0.00021707 ETH | ||||
| Send | 24551425 | 2 days ago | 0.00023877 ETH | ||||
| Send | 24542417 | 3 days ago | 0.00021707 ETH | ||||
| Send | 24540217 | 3 days ago | 0.00002705 ETH | ||||
| Send | 24538579 | 3 days ago | 0.00021707 ETH | ||||
| Send | 24538472 | 3 days ago | 0.00021707 ETH | ||||
| Send | 24538287 | 3 days ago | 0.00021707 ETH | ||||
| Send | 24538264 | 3 days ago | 0.00021707 ETH | ||||
| Send | 24535956 | 4 days ago | 0.00021707 ETH | ||||
| Send | 24534923 | 4 days ago | 0.00021707 ETH | ||||
| Send | 24526112 | 5 days ago | 0.00002843 ETH | ||||
| Send | 24526053 | 5 days ago | 0.00004227 ETH | ||||
| Send | 24505380 | 8 days ago | 0.00021707 ETH | ||||
| Send | 24504575 | 8 days ago | 0.00025496 ETH | ||||
| Send | 24504556 | 8 days ago | 0.00023877 ETH | ||||
| Send | 24443771 | 17 days ago | 0.00002567 ETH | ||||
| Send | 24443190 | 17 days ago | 0.00004201 ETH | ||||
| Send | 24438405 | 17 days ago | 0.00002642 ETH | ||||
| Send | 24438166 | 17 days ago | 0.00021707 ETH | ||||
| Send | 24438140 | 17 days ago | 0.00002642 ETH | ||||
| Send | 24438029 | 17 days ago | 0.00023877 ETH | ||||
| Send | 24437925 | 17 days ago | 0.00023877 ETH | ||||
| Send | 24437470 | 17 days ago | 0.00002805 ETH | ||||
| Send | 24437405 | 17 days ago | 0.0000309 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
ABR0Migration
Compiler Version
v0.8.22+commit.4fc1097e
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { OFT } from "@layerzerolabs/oft-evm/contracts/OFT.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
contract ABR0Migration is OFT {
IERC20 public oldTokenAddress;
constructor(
string memory _name,
string memory _symbol,
address _lzEndpoint,
address _delegate,
IERC20 _oldTokenAddress
) OFT(_name, _symbol, _lzEndpoint, _delegate) Ownable(_delegate) {
oldTokenAddress = _oldTokenAddress;
}
function migrate(uint256 _amount) public {
oldTokenAddress.transferFrom(msg.sender, address(this), _amount);
_mint(msg.sender, _amount);
}
}// 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);
error AmountSDOverflowed(uint256 amountSD);
// 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 the fee breakdown and settings data for an OFT. Unused in the default implementation.
* @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 { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
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 the fee breakdown and settings data for an OFT. Unused in the default implementation.
* @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 = IERC20(this.token()).totalSupply(); // 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.
*
* @dev Reverts if the _amountLD in shared decimals overflows uint64.
* @dev eg. uint(2**64 + 123) with a conversion rate of 1 wraps around 2**64 to uint(123).
*/
function _toSD(uint256 _amountLD) internal view virtual returns (uint64 amountSD) {
uint256 _amountSD = _amountLD / decimalConversionRate;
if (_amountSD > type(uint64).max) revert AmountSDOverflowed(_amountSD);
return uint64(_amountSD);
}
/**
* @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.4.0) (interfaces/draft-IERC6093.sol)
pragma solidity >=0.8.4;
/**
* @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.4.0) (interfaces/IERC1363.sol)
pragma solidity >=0.6.2;
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.4.0) (interfaces/IERC165.sol)
pragma solidity >=0.4.16;
import {IERC165} from "../utils/introspection/IERC165.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)
pragma solidity >=0.4.16;
import {IERC20} from "../token/ERC20/IERC20.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.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}.
*
* Both 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;
}
/// @inheritdoc IERC20
function totalSupply() public view virtual returns (uint256) {
return _totalSupply;
}
/// @inheritdoc IERC20
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;
}
/// @inheritdoc IERC20
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.4.0) (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity >=0.6.2;
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.4.0) (token/ERC20/IERC20.sol)
pragma solidity >=0.4.16;
/**
* @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.3.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC1363} from "../../../interfaces/IERC1363.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 Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {
return _callOptionalReturnBool(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {
return _callOptionalReturnBool(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.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.4.0) (utils/introspection/IERC165.sol)
pragma solidity >=0.4.16;
/**
* @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);
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_lzEndpoint","type":"address"},{"internalType":"address","name":"_delegate","type":"address"},{"internalType":"contract IERC20","name":"_oldTokenAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"amountSD","type":"uint256"}],"name":"AmountSDOverflowed","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[],"name":"InvalidDelegate","type":"error"},{"inputs":[],"name":"InvalidEndpointCall","type":"error"},{"inputs":[],"name":"InvalidLocalDecimals","type":"error"},{"inputs":[{"internalType":"bytes","name":"options","type":"bytes"}],"name":"InvalidOptions","type":"error"},{"inputs":[],"name":"LzTokenUnavailable","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"NoPeer","type":"error"},{"inputs":[{"internalType":"uint256","name":"msgValue","type":"uint256"}],"name":"NotEnoughNative","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"OnlyEndpoint","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"}],"name":"OnlyPeer","type":"error"},{"inputs":[],"name":"OnlySelf","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[{"internalType":"bytes","name":"result","type":"bytes"}],"name":"SimulationResult","type":"error"},{"inputs":[{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"uint256","name":"minAmountLD","type":"uint256"}],"name":"SlippageExceeded","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","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":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"approvalRequired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"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":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"msgInspector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"oldTokenAddress","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"peers","outputs":[{"internalType":"bytes32","name":"peer","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"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":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60c06040523480156200001157600080fd5b50604051620038a2380380620038a28339810160408190526200003491620002f0565b84848484838360128484818181818e6001600160a01b0381166200007257604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b6200007d81620001ba565b506001600160a01b038083166080528116620000ac57604051632d618d8160e21b815260040160405180910390fd5b60805160405163ca5eb5e160e01b81526001600160a01b0383811660048301529091169063ca5eb5e190602401600060405180830381600087803b158015620000f457600080fd5b505af115801562000109573d6000803e3d6000fd5b5050505050505050620001216200020a60201b60201c565b60ff168360ff16101562000148576040516301e9714b60e41b815260040160405180910390fd5b62000155600684620003b2565b6200016290600a620004d1565b60a052506008915062000178905083826200057a565b5060096200018782826200057a565b5050600a80546001600160a01b0319166001600160a01b0397909716969096179095555062000646975050505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600690565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200023757600080fd5b81516001600160401b03808211156200025457620002546200020f565b604051601f8301601f19908116603f011681019082821181831017156200027f576200027f6200020f565b81604052838152602092508660208588010111156200029d57600080fd5b600091505b83821015620002c15785820183015181830184015290820190620002a2565b6000602085830101528094505050505092915050565b6001600160a01b0381168114620002ed57600080fd5b50565b600080600080600060a086880312156200030957600080fd5b85516001600160401b03808211156200032157600080fd5b6200032f89838a0162000225565b965060208801519150808211156200034657600080fd5b50620003558882890162000225565b94505060408601516200036881620002d7565b60608701519093506200037b81620002d7565b60808701519092506200038e81620002d7565b809150509295509295909350565b634e487b7160e01b600052601160045260246000fd5b60ff8281168282160390811115620003ce57620003ce6200039c565b92915050565b600181815b8085111562000415578160001904821115620003f957620003f96200039c565b808516156200040757918102915b93841c9390800290620003d9565b509250929050565b6000826200042e57506001620003ce565b816200043d57506000620003ce565b8160018114620004565760028114620004615762000481565b6001915050620003ce565b60ff8411156200047557620004756200039c565b50506001821b620003ce565b5060208310610133831016604e8410600b8410161715620004a6575081810a620003ce565b620004b28383620003d4565b8060001904821115620004c957620004c96200039c565b029392505050565b6000620004e260ff8416836200041d565b9392505050565b600181811c90821680620004fe57607f821691505b6020821081036200051f57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000575576000816000526020600020601f850160051c81016020861015620005505750805b601f850160051c820191505b8181101562000571578281556001016200055c565b5050505b505050565b81516001600160401b038111156200059657620005966200020f565b620005ae81620005a78454620004e9565b8462000525565b602080601f831160018114620005e65760008415620005cd5750858301515b600019600386901b1c1916600185901b17855562000571565b600085815260208120601f198616915b828110156200061757888601518255948401946001909101908401620005f6565b5085821015620006365787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a0516131f0620006b26000396000818161065401528181611bb301528181611c280152611e2d01526000818161051301528181610aa30152818161117c015281816113f00152818161175b01528181611f520152818161208c015261214301526131f06000f3fe6080604052600436106102675760003560e01c80637d25a05e11610144578063bc70b354116100b6578063d42438851161007a578063d42438851461079e578063d8542d51146107be578063dd62ed3e146107de578063f2fde38b14610824578063fc0c546a14610497578063ff7bd03d1461084457600080fd5b8063bc70b35414610717578063bd815db014610737578063c7c7f5b31461074a578063ca5eb5e11461076b578063d045a0dc1461078b57600080fd5b8063963efcaa11610108578063963efcaa146106425780639f68b96414610676578063a9059cbb1461068a578063b731ea0a146106aa578063b98bd070146106ca578063bb0b6a53146106ea57600080fd5b80637d25a05e146105a057806382413eac146105db578063857749b0146105fb5780638da5cb5b1461060f57806395d89b411461062d57600080fd5b8063313ce567116101dd5780635535d461116101a15780635535d461146104aa5780635a0dfe4d146104ca5780635e280f11146105015780636fc1b31e1461053557806370a0823114610555578063715018a61461058b57600080fd5b8063313ce567146104085780633400288b1461042a5780633b6f743b1461044a578063454b06081461047757806352ae28791461049757600080fd5b8063134d4f251161022f578063134d4f2514610343578063156a0d0f1461036b57806317442b701461039257806318160ddd146103b45780631f5e1334146103d357806323b872dd146103e857600080fd5b806306fdde031461026c578063095ea7b3146102975780630d35b415146102c7578063111ecdad146102f657806313137d651461032e575b600080fd5b34801561027857600080fd5b50610281610864565b60405161028e91906122bb565b60405180910390f35b3480156102a357600080fd5b506102b76102b23660046122e3565b6108f6565b604051901515815260200161028e565b3480156102d357600080fd5b506102e76102e2366004612327565b610910565b60405161028e9392919061235b565b34801561030257600080fd5b50600454610316906001600160a01b031681565b6040516001600160a01b03909116815260200161028e565b61034161033c36600461244e565b610aa1565b005b34801561034f57600080fd5b50610358600281565b60405161ffff909116815260200161028e565b34801561037757600080fd5b506040805162b9270b60e21b8152600160208201520161028e565b34801561039e57600080fd5b506040805160018152600260208201520161028e565b3480156103c057600080fd5b506007545b60405190815260200161028e565b3480156103df57600080fd5b50610358600181565b3480156103f457600080fd5b506102b76104033660046124ed565b610b61565b34801561041457600080fd5b5060125b60405160ff909116815260200161028e565b34801561043657600080fd5b50610341610445366004612547565b610b87565b34801561045657600080fd5b5061046a610465366004612571565b610b9d565b60405161028e91906125c2565b34801561048357600080fd5b506103416104923660046125d9565b610c04565b3480156104a357600080fd5b5030610316565b3480156104b657600080fd5b506102816104c5366004612604565b610c8d565b3480156104d657600080fd5b506102b76104e5366004612547565b63ffffffff919091166000908152600160205260409020541490565b34801561050d57600080fd5b506103167f000000000000000000000000000000000000000000000000000000000000000081565b34801561054157600080fd5b50610341610550366004612637565b610d32565b34801561056157600080fd5b506103c5610570366004612637565b6001600160a01b031660009081526005602052604090205490565b34801561059757600080fd5b50610341610d8f565b3480156105ac57600080fd5b506105c36105bb366004612547565b600092915050565b6040516001600160401b03909116815260200161028e565b3480156105e757600080fd5b506102b76105f6366004612654565b610da3565b34801561060757600080fd5b506006610418565b34801561061b57600080fd5b506000546001600160a01b0316610316565b34801561063957600080fd5b50610281610db8565b34801561064e57600080fd5b506103c57f000000000000000000000000000000000000000000000000000000000000000081565b34801561068257600080fd5b5060006102b7565b34801561069657600080fd5b506102b76106a53660046122e3565b610dc7565b3480156106b657600080fd5b50600254610316906001600160a01b031681565b3480156106d657600080fd5b506103416106e53660046126fe565b610dd5565b3480156106f657600080fd5b506103c561070536600461273f565b60016020526000908152604090205481565b34801561072357600080fd5b5061028161073236600461275a565b610def565b6103416107453660046126fe565b610f97565b61075d6107583660046127ba565b611121565b60405161028e929190612827565b34801561077757600080fd5b50610341610786366004612637565b611155565b61034161079936600461244e565b6111db565b3480156107aa57600080fd5b506103416107b9366004612637565b61120a565b3480156107ca57600080fd5b50600a54610316906001600160a01b031681565b3480156107ea57600080fd5b506103c56107f9366004612879565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205490565b34801561083057600080fd5b5061034161083f366004612637565b611260565b34801561085057600080fd5b506102b761085f3660046128a7565b61129b565b606060088054610873906128c3565b80601f016020809104026020016040519081016040528092919081815260200182805461089f906128c3565b80156108ec5780601f106108c1576101008083540402835291602001916108ec565b820191906000526020600020905b8154815290600101906020018083116108cf57829003601f168201915b5050505050905090565b6000336109048185856112d1565b60019150505b92915050565b60408051808201909152600080825260208201526060610943604051806040016040528060008152602001600081525090565b600080306001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610984573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a891906128f7565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109e5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a099190612914565b60408051808201825284815260208082018490528251600080825291810190935290975091925090610a5e565b604080518082019091526000815260606020820152815260200190600190039081610a365790505b509350600080610a83604089013560608a0135610a7e60208c018c61273f565b6112e3565b60408051808201909152918252602082015296989597505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163314610af1576040516391ac5e4f60e01b81523360048201526024015b60405180910390fd5b60208701803590610b0b90610b06908a61273f565b61131f565b14610b4957610b1d602088018861273f565b60405163309afaf360e21b815263ffffffff909116600482015260208801356024820152604401610ae8565b610b588787878787878761135b565b50505050505050565b600033610b6f8582856114c2565b610b7a858585611541565b60019150505b9392505050565b610b8f6115a0565b610b9982826115cd565b5050565b60408051808201909152600080825260208201526000610bcd60408501356060860135610a7e602088018861273f565b915050600080610bdd8684611622565b9092509050610bfa610bf2602088018861273f565b838388611745565b9695505050505050565b600a546040516323b872dd60e01b8152336004820152306024820152604481018390526001600160a01b03909116906323b872dd906064016020604051808303816000875af1158015610c5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7f9190612943565b50610c8a3382611826565b50565b600360209081526000928352604080842090915290825290208054610cb1906128c3565b80601f0160208091040260200160405190810160405280929190818152602001828054610cdd906128c3565b8015610d2a5780601f10610cff57610100808354040283529160200191610d2a565b820191906000526020600020905b815481529060010190602001808311610d0d57829003601f168201915b505050505081565b610d3a6115a0565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527ff0be4f1e87349231d80c36b33f9e8639658eeaf474014dee15a3e6a4d4414197906020015b60405180910390a150565b610d976115a0565b610da1600061185c565b565b6001600160a01b03811630145b949350505050565b606060098054610873906128c3565b600033610904818585611541565b610ddd6115a0565b610b99610dea8284612a01565b6118ac565b63ffffffff8416600090815260036020908152604080832061ffff87168452909152812080546060929190610e23906128c3565b80601f0160208091040260200160405190810160405280929190818152602001828054610e4f906128c3565b8015610e9c5780601f10610e7157610100808354040283529160200191610e9c565b820191906000526020600020905b815481529060010190602001808311610e7f57829003601f168201915b505050505090508051600003610eec5783838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929450610db09350505050565b6000839003610efc579050610db0565b60028310610f7a57610f4384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506119b392505050565b80610f518460028188612b16565b604051602001610f6393929190612b40565b604051602081830303815290604052915050610db0565b8383604051639a6d49cd60e01b8152600401610ae8929190612b91565b60005b818110156110a05736838383818110610fb557610fb5612ba5565b9050602002810190610fc79190612bbb565b9050610ffa610fd9602083018361273f565b602083013563ffffffff919091166000908152600160205260409020541490565b6110045750611098565b3063d045a0dc60c08301358360a0810135611023610100830183612bdc565b611034610100890160e08a01612637565b6110426101208a018a612bdc565b6040518963ffffffff1660e01b81526004016110649796959493929190612c37565b6000604051808303818588803b15801561107d57600080fd5b505af1158015611091573d6000803e3d6000fd5b5050505050505b600101610f9a565b50336001600160a01b0316638e9e70996040518163ffffffff1660e01b8152600401600060405180830381865afa1580156110df573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526111079190810190612cbd565b604051638351eea760e01b8152600401610ae891906122bb565b611129612224565b60408051808201909152600080825260208201526111488585856119df565b915091505b935093915050565b61115d6115a0565b60405163ca5eb5e160e01b81526001600160a01b0382811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063ca5eb5e190602401600060405180830381600087803b1580156111c057600080fd5b505af11580156111d4573d6000803e3d6000fd5b5050505050565b3330146111fb5760405163029a949d60e31b815260040160405180910390fd5b610b5887878787878787610b49565b6112126115a0565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527fd48d879cef83a1c0bdda516f27b13ddb1b3f8bbac1c9e1511bb2a659c242776090602001610d84565b6112686115a0565b6001600160a01b03811661129257604051631e4fbdf760e01b815260006004820152602401610ae8565b610c8a8161185c565b60006020820180359060019083906112b3908661273f565b63ffffffff1681526020810191909152604001600020541492915050565b6112de8383836001611ada565b505050565b6000806112ef85611baf565b91508190508381101561114d576040516371c4efed60e01b81526004810182905260248101859052604401610ae8565b63ffffffff81166000908152600160205260408120548061090a5760405163f6ff4fb760e01b815263ffffffff84166004820152602401610ae8565b600061136d61136a8787611be6565b90565b90506000611399826113876113828a8a611bfe565b611c21565b61139460208d018d61273f565b611c56565b905060288611156114605760006113d66113b960608c0160408d01612d2a565b6113c660208d018d61273f565b846113d18c8c611c7e565b611cc9565b604051633e5ac80960e11b81529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690637cb590129061142c9086908d906000908790600401612d47565b600060405180830381600087803b15801561144657600080fd5b505af115801561145a573d6000803e3d6000fd5b50505050505b6001600160a01b038216887fefed6d3500546b29533b128a29e3a94d70788727f0507505ac12eaf2e578fd9c61149960208d018d61273f565b6040805163ffffffff9092168252602082018690520160405180910390a3505050505050505050565b6001600160a01b0383811660009081526006602090815260408083209386168352929052205460001981101561153b578181101561152c57604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610ae8565b61153b84848484036000611ada565b50505050565b6001600160a01b03831661156b57604051634b637e8f60e11b815260006004820152602401610ae8565b6001600160a01b0382166115955760405163ec442f0560e01b815260006004820152602401610ae8565b6112de838383611cfb565b6000546001600160a01b03163314610da15760405163118cdaa760e01b8152336004820152602401610ae8565b63ffffffff8216600081815260016020908152604091829020849055815192835282018390527f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b910160405180910390a15050565b606080600061167f856020013561163886611e25565b61164560a0890189612bdc565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e7f92505050565b9093509050600081611692576001611695565b60025b90506116b56116a7602088018861273f565b8261073260808a018a612bdc565b6004549093506001600160a01b0316801561173b5760405163043a78eb60e01b81526001600160a01b0382169063043a78eb906116f89088908890600401612d78565b602060405180830381865afa158015611715573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117399190612943565b505b5050509250929050565b60408051808201909152600080825260208201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ddc28c586040518060a001604052808863ffffffff1681526020016117a88961131f565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b81526004016117dd929190612d9d565b6040805180830381865afa1580156117f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181d9190612e46565b95945050505050565b6001600160a01b0382166118505760405163ec442f0560e01b815260006004820152602401610ae8565b610b9960008383611cfb565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60005b8151811015611983576118de8282815181106118cd576118cd612ba5565b6020026020010151604001516119b3565b8181815181106118f0576118f0612ba5565b6020026020010151604001516003600084848151811061191257611912612ba5565b60200260200101516000015163ffffffff1663ffffffff168152602001908152602001600020600084848151811061194c5761194c612ba5565b60200260200101516020015161ffff1661ffff168152602001908152602001600020908161197a9190612eb2565b506001016118af565b507fbe4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b67481604051610d849190612f71565b600281015161ffff8116600314610b995781604051639a6d49cd60e01b8152600401610ae891906122bb565b6119e7612224565b6040805180820190915260008082526020820152600080611a1e33604089013560608a0135611a1960208c018c61273f565b611ef9565b91509150600080611a2f8984611622565b9092509050611a5b611a4460208b018b61273f565b8383611a55368d90038d018d612ffc565b8b611f1f565b60408051808201909152858152602080820186905282519298509096503391907f85496b760a4b7f8d66384b9df21b381f5d1b1e79f229a47aaf4c232edc2fe59a90611aa9908d018d61273f565b6040805163ffffffff909216825260208201899052810187905260600160405180910390a350505050935093915050565b6001600160a01b038416611b045760405163e602df0560e01b815260006004820152602401610ae8565b6001600160a01b038316611b2e57604051634a1406b160e11b815260006004820152602401610ae8565b6001600160a01b038085166000908152600660209081526040808320938716835292905220829055801561153b57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051611ba191815260200190565b60405180910390a350505050565b60007f0000000000000000000000000000000000000000000000000000000000000000611bdc8184613044565b61090a9190613066565b6000611bf56020828486612b16565b610b809161307d565b6000611c0e602860208486612b16565b611c179161309b565b60c01c9392505050565b600061090a7f00000000000000000000000000000000000000000000000000000000000000006001600160401b038416613066565b60006001600160a01b038416611c6c5761dead93505b611c768484611826565b509092915050565b6060611c8d8260288186612b16565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929695505050505050565b606084848484604051602001611ce294939291906130cb565b6040516020818303038152906040529050949350505050565b6001600160a01b038316611d26578060076000828254611d1b919061311a565b90915550611d989050565b6001600160a01b03831660009081526005602052604090205481811015611d795760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610ae8565b6001600160a01b03841660009081526005602052604090209082900390555b6001600160a01b038216611db457600780548290039055611dd3565b6001600160a01b03821660009081526005602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611e1891815260200190565b60405180910390a3505050565b600080611e527f000000000000000000000000000000000000000000000000000000000000000084613044565b90506001600160401b0381111561090a5760405163e2ce941360e01b815260048101829052602401610ae8565b8051606090151580611ec8578484604051602001611eb492919091825260c01b6001600160c01b031916602082015260280190565b604051602081830303815290604052611eef565b84843385604051602001611edf949392919061312d565b6040516020818303038152906040525b9150935093915050565b600080611f078585856112e3565b9092509050611f16868361202a565b94509492505050565b611f27612224565b6000611f368460000151612060565b602085015190915015611f5057611f508460200151612088565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632637a450826040518060a001604052808b63ffffffff168152602001611fa08c61131f565b81526020018a815260200189815260200160008960200151111515815250866040518463ffffffff1660e01b8152600401611fdc929190612d9d565b60806040518083038185885af1158015611ffa573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061201f9190613170565b979650505050505050565b6001600160a01b03821661205457604051634b637e8f60e11b815260006004820152602401610ae8565b610b9982600083611cfb565b6000813414612084576040516304fb820960e51b8152346004820152602401610ae8565b5090565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061210c91906128f7565b90506001600160a01b038116612135576040516329b99a9560e11b815260040160405180910390fd5b6040805133602482018190527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0381811660448501526064808501889052855180860390910181526084909401909452602080840180516001600160e01b03166323b872dd60e01b1781528451610b9996881695899361153b93889360009283929091839182885af1806121d6576040513d6000823e3d81fd5b50506000513d915081156121ee5780600114156121fb565b6001600160a01b0384163b155b1561153b57604051635274afe760e01b81526001600160a01b0385166004820152602401610ae8565b60405180606001604052806000801916815260200160006001600160401b03168152602001612266604051806040016040528060008152602001600081525090565b905290565b60005b8381101561228657818101518382015260200161226e565b50506000910152565b600081518084526122a781602086016020860161226b565b601f01601f19169290920160200192915050565b602081526000610b80602083018461228f565b6001600160a01b0381168114610c8a57600080fd5b600080604083850312156122f657600080fd5b8235612301816122ce565b946020939093013593505050565b600060e0828403121561232157600080fd5b50919050565b60006020828403121561233957600080fd5b81356001600160401b0381111561234f57600080fd5b610db08482850161230f565b8351815260208085015190820152600060a08201604060a0604085015281865180845260c08601915060c08160051b8701019350602080890160005b838110156123d65788870360bf190185528151805188528301518388018790526123c38789018261228f565b9750509382019390820190600101612397565b50508751606088015250505060208501516080850152509050610db0565b60006060828403121561232157600080fd5b60008083601f84011261241857600080fd5b5081356001600160401b0381111561242f57600080fd5b60208301915083602082850101111561244757600080fd5b9250929050565b600080600080600080600060e0888a03121561246957600080fd5b61247389896123f4565b96506060880135955060808801356001600160401b038082111561249657600080fd5b6124a28b838c01612406565b909750955060a08a013591506124b7826122ce565b90935060c089013590808211156124cd57600080fd5b506124da8a828b01612406565b989b979a50959850939692959293505050565b60008060006060848603121561250257600080fd5b833561250d816122ce565b9250602084013561251d816122ce565b929592945050506040919091013590565b803563ffffffff8116811461254257600080fd5b919050565b6000806040838503121561255a57600080fd5b6123018361252e565b8015158114610c8a57600080fd5b6000806040838503121561258457600080fd5b82356001600160401b0381111561259a57600080fd5b6125a68582860161230f565b92505060208301356125b781612563565b809150509250929050565b81518152602080830151908201526040810161090a565b6000602082840312156125eb57600080fd5b5035919050565b803561ffff8116811461254257600080fd5b6000806040838503121561261757600080fd5b6126208361252e565b915061262e602084016125f2565b90509250929050565b60006020828403121561264957600080fd5b8135610b80816122ce565b60008060008060a0858703121561266a57600080fd5b61267486866123f4565b935060608501356001600160401b0381111561268f57600080fd5b61269b87828801612406565b90945092505060808501356126af816122ce565b939692955090935050565b60008083601f8401126126cc57600080fd5b5081356001600160401b038111156126e357600080fd5b6020830191508360208260051b850101111561244757600080fd5b6000806020838503121561271157600080fd5b82356001600160401b0381111561272757600080fd5b612733858286016126ba565b90969095509350505050565b60006020828403121561275157600080fd5b610b808261252e565b6000806000806060858703121561277057600080fd5b6127798561252e565b9350612787602086016125f2565b925060408501356001600160401b038111156127a257600080fd5b6127ae87828801612406565b95989497509550505050565b600080600083850360808112156127d057600080fd5b84356001600160401b038111156127e657600080fd5b6127f28782880161230f565b9450506040601f198201121561280757600080fd5b50602084019150606084013561281c816122ce565b809150509250925092565b600060c082019050835182526001600160401b0360208501511660208301526040840151612862604084018280518252602090810151910152565b5082516080830152602083015160a0830152610b80565b6000806040838503121561288c57600080fd5b8235612897816122ce565b915060208301356125b7816122ce565b6000606082840312156128b957600080fd5b610b8083836123f4565b600181811c908216806128d757607f821691505b60208210810361232157634e487b7160e01b600052602260045260246000fd5b60006020828403121561290957600080fd5b8151610b80816122ce565b60006020828403121561292657600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561295557600080fd5b8151610b8081612563565b604051606081016001600160401b03811182821017156129825761298261292d565b60405290565b604080519081016001600160401b03811182821017156129825761298261292d565b604051601f8201601f191681016001600160401b03811182821017156129d2576129d261292d565b604052919050565b60006001600160401b038211156129f3576129f361292d565b50601f01601f191660200190565b60006001600160401b0380841115612a1b57612a1b61292d565b8360051b6020612a2c8183016129aa565b868152918501918181019036841115612a4457600080fd5b865b84811015612b0a57803586811115612a5e5760008081fd5b88016060368290031215612a725760008081fd5b612a7a612960565b612a838261252e565b8152612a908683016125f2565b8682015260408083013589811115612aa85760008081fd5b929092019136601f840112612abd5760008081fd5b8235612ad0612acb826129da565b6129aa565b8181523689838701011115612ae55760008081fd5b818986018a830137600091810189019190915290820152845250918301918301612a46565b50979650505050505050565b60008085851115612b2657600080fd5b83861115612b3357600080fd5b5050820193919092039150565b60008451612b5281846020890161226b565b8201838582376000930192835250909392505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b602081526000610db0602083018486612b68565b634e487b7160e01b600052603260045260246000fd5b6000823561013e19833603018112612bd257600080fd5b9190910192915050565b6000808335601e19843603018112612bf357600080fd5b8301803591506001600160401b03821115612c0d57600080fd5b60200191503681900382131561244757600080fd5b6001600160401b0381168114610c8a57600080fd5b63ffffffff612c458961252e565b1681526020880135602082015260006040890135612c6281612c22565b6001600160401b03811660408401525087606083015260e06080830152612c8d60e083018789612b68565b6001600160a01b03861660a084015282810360c0840152612caf818587612b68565b9a9950505050505050505050565b600060208284031215612ccf57600080fd5b81516001600160401b03811115612ce557600080fd5b8201601f81018413612cf657600080fd5b8051612d04612acb826129da565b818152856020838501011115612d1957600080fd5b61181d82602083016020860161226b565b600060208284031215612d3c57600080fd5b8135610b8081612c22565b60018060a01b038516815283602082015261ffff83166040820152608060608201526000610bfa608083018461228f565b604081526000612d8b604083018561228f565b828103602084015261181d818561228f565b6040815263ffffffff8351166040820152602083015160608201526000604084015160a06080840152612dd360e084018261228f565b90506060850151603f198483030160a0850152612df0828261228f565b60809690960151151560c08501525050506001600160a01b039190911660209091015290565b600060408284031215612e2857600080fd5b612e30612988565b9050815181526020820151602082015292915050565b600060408284031215612e5857600080fd5b610b808383612e16565b601f8211156112de576000816000526020600020601f850160051c81016020861015612e8b5750805b601f850160051c820191505b81811015612eaa57828155600101612e97565b505050505050565b81516001600160401b03811115612ecb57612ecb61292d565b612edf81612ed984546128c3565b84612e62565b602080601f831160018114612f145760008415612efc5750858301515b600019600386901b1c1916600185901b178555612eaa565b600085815260208120601f198616915b82811015612f4357888601518255948401946001909101908401612f24565b5085821015612f615787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b83811015612fee57888303603f190185528151805163ffffffff1684528781015161ffff16888501528601516060878501819052612fda8186018361228f565b968901969450505090860190600101612f9a565b509098975050505050505050565b60006040828403121561300e57600080fd5b613016612988565b82358152602083013560208201528091505092915050565b634e487b7160e01b600052601160045260246000fd5b60008261306157634e487b7160e01b600052601260045260246000fd5b500490565b808202811582820484141761090a5761090a61302e565b8035602083101561090a57600019602084900360031b1b1692915050565b6001600160c01b031981358181169160088510156130c35780818660080360031b1b83161692505b505092915050565b6001600160401b0360c01b8560c01b16815263ffffffff60e01b8460e01b16600882015282600c8201526000825161310a81602c85016020870161226b565b91909101602c0195945050505050565b8082018082111561090a5761090a61302e565b8481526001600160401b0360c01b8460c01b1660208201528260288201526000825161316081604885016020870161226b565b9190910160480195945050505050565b60006080828403121561318257600080fd5b61318a612960565b82518152602083015161319c81612c22565b60208201526131ae8460408501612e16565b6040820152939250505056fea2646970667358221220c97ac570e782e4bd78ea6115c982379c92c33ffa85c7286cb83aa4d58cf7f54164736f6c6343000816003300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000001a44076050125825900e736c501f859c50fe728c000000000000000000000000646c7089bfeca23c2278b3848dae78d7b5d8b74d000000000000000000000000a11bd36801d8fa4448f0ac4ea7a62e3634ce8c7c000000000000000000000000000000000000000000000000000000000000000e416c6c627269646765205a65726f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044142523000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106102675760003560e01c80637d25a05e11610144578063bc70b354116100b6578063d42438851161007a578063d42438851461079e578063d8542d51146107be578063dd62ed3e146107de578063f2fde38b14610824578063fc0c546a14610497578063ff7bd03d1461084457600080fd5b8063bc70b35414610717578063bd815db014610737578063c7c7f5b31461074a578063ca5eb5e11461076b578063d045a0dc1461078b57600080fd5b8063963efcaa11610108578063963efcaa146106425780639f68b96414610676578063a9059cbb1461068a578063b731ea0a146106aa578063b98bd070146106ca578063bb0b6a53146106ea57600080fd5b80637d25a05e146105a057806382413eac146105db578063857749b0146105fb5780638da5cb5b1461060f57806395d89b411461062d57600080fd5b8063313ce567116101dd5780635535d461116101a15780635535d461146104aa5780635a0dfe4d146104ca5780635e280f11146105015780636fc1b31e1461053557806370a0823114610555578063715018a61461058b57600080fd5b8063313ce567146104085780633400288b1461042a5780633b6f743b1461044a578063454b06081461047757806352ae28791461049757600080fd5b8063134d4f251161022f578063134d4f2514610343578063156a0d0f1461036b57806317442b701461039257806318160ddd146103b45780631f5e1334146103d357806323b872dd146103e857600080fd5b806306fdde031461026c578063095ea7b3146102975780630d35b415146102c7578063111ecdad146102f657806313137d651461032e575b600080fd5b34801561027857600080fd5b50610281610864565b60405161028e91906122bb565b60405180910390f35b3480156102a357600080fd5b506102b76102b23660046122e3565b6108f6565b604051901515815260200161028e565b3480156102d357600080fd5b506102e76102e2366004612327565b610910565b60405161028e9392919061235b565b34801561030257600080fd5b50600454610316906001600160a01b031681565b6040516001600160a01b03909116815260200161028e565b61034161033c36600461244e565b610aa1565b005b34801561034f57600080fd5b50610358600281565b60405161ffff909116815260200161028e565b34801561037757600080fd5b506040805162b9270b60e21b8152600160208201520161028e565b34801561039e57600080fd5b506040805160018152600260208201520161028e565b3480156103c057600080fd5b506007545b60405190815260200161028e565b3480156103df57600080fd5b50610358600181565b3480156103f457600080fd5b506102b76104033660046124ed565b610b61565b34801561041457600080fd5b5060125b60405160ff909116815260200161028e565b34801561043657600080fd5b50610341610445366004612547565b610b87565b34801561045657600080fd5b5061046a610465366004612571565b610b9d565b60405161028e91906125c2565b34801561048357600080fd5b506103416104923660046125d9565b610c04565b3480156104a357600080fd5b5030610316565b3480156104b657600080fd5b506102816104c5366004612604565b610c8d565b3480156104d657600080fd5b506102b76104e5366004612547565b63ffffffff919091166000908152600160205260409020541490565b34801561050d57600080fd5b506103167f0000000000000000000000001a44076050125825900e736c501f859c50fe728c81565b34801561054157600080fd5b50610341610550366004612637565b610d32565b34801561056157600080fd5b506103c5610570366004612637565b6001600160a01b031660009081526005602052604090205490565b34801561059757600080fd5b50610341610d8f565b3480156105ac57600080fd5b506105c36105bb366004612547565b600092915050565b6040516001600160401b03909116815260200161028e565b3480156105e757600080fd5b506102b76105f6366004612654565b610da3565b34801561060757600080fd5b506006610418565b34801561061b57600080fd5b506000546001600160a01b0316610316565b34801561063957600080fd5b50610281610db8565b34801561064e57600080fd5b506103c57f000000000000000000000000000000000000000000000000000000e8d4a5100081565b34801561068257600080fd5b5060006102b7565b34801561069657600080fd5b506102b76106a53660046122e3565b610dc7565b3480156106b657600080fd5b50600254610316906001600160a01b031681565b3480156106d657600080fd5b506103416106e53660046126fe565b610dd5565b3480156106f657600080fd5b506103c561070536600461273f565b60016020526000908152604090205481565b34801561072357600080fd5b5061028161073236600461275a565b610def565b6103416107453660046126fe565b610f97565b61075d6107583660046127ba565b611121565b60405161028e929190612827565b34801561077757600080fd5b50610341610786366004612637565b611155565b61034161079936600461244e565b6111db565b3480156107aa57600080fd5b506103416107b9366004612637565b61120a565b3480156107ca57600080fd5b50600a54610316906001600160a01b031681565b3480156107ea57600080fd5b506103c56107f9366004612879565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205490565b34801561083057600080fd5b5061034161083f366004612637565b611260565b34801561085057600080fd5b506102b761085f3660046128a7565b61129b565b606060088054610873906128c3565b80601f016020809104026020016040519081016040528092919081815260200182805461089f906128c3565b80156108ec5780601f106108c1576101008083540402835291602001916108ec565b820191906000526020600020905b8154815290600101906020018083116108cf57829003601f168201915b5050505050905090565b6000336109048185856112d1565b60019150505b92915050565b60408051808201909152600080825260208201526060610943604051806040016040528060008152602001600081525090565b600080306001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610984573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a891906128f7565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109e5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a099190612914565b60408051808201825284815260208082018490528251600080825291810190935290975091925090610a5e565b604080518082019091526000815260606020820152815260200190600190039081610a365790505b509350600080610a83604089013560608a0135610a7e60208c018c61273f565b6112e3565b60408051808201909152918252602082015296989597505050505050565b7f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b03163314610af1576040516391ac5e4f60e01b81523360048201526024015b60405180910390fd5b60208701803590610b0b90610b06908a61273f565b61131f565b14610b4957610b1d602088018861273f565b60405163309afaf360e21b815263ffffffff909116600482015260208801356024820152604401610ae8565b610b588787878787878761135b565b50505050505050565b600033610b6f8582856114c2565b610b7a858585611541565b60019150505b9392505050565b610b8f6115a0565b610b9982826115cd565b5050565b60408051808201909152600080825260208201526000610bcd60408501356060860135610a7e602088018861273f565b915050600080610bdd8684611622565b9092509050610bfa610bf2602088018861273f565b838388611745565b9695505050505050565b600a546040516323b872dd60e01b8152336004820152306024820152604481018390526001600160a01b03909116906323b872dd906064016020604051808303816000875af1158015610c5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7f9190612943565b50610c8a3382611826565b50565b600360209081526000928352604080842090915290825290208054610cb1906128c3565b80601f0160208091040260200160405190810160405280929190818152602001828054610cdd906128c3565b8015610d2a5780601f10610cff57610100808354040283529160200191610d2a565b820191906000526020600020905b815481529060010190602001808311610d0d57829003601f168201915b505050505081565b610d3a6115a0565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527ff0be4f1e87349231d80c36b33f9e8639658eeaf474014dee15a3e6a4d4414197906020015b60405180910390a150565b610d976115a0565b610da1600061185c565b565b6001600160a01b03811630145b949350505050565b606060098054610873906128c3565b600033610904818585611541565b610ddd6115a0565b610b99610dea8284612a01565b6118ac565b63ffffffff8416600090815260036020908152604080832061ffff87168452909152812080546060929190610e23906128c3565b80601f0160208091040260200160405190810160405280929190818152602001828054610e4f906128c3565b8015610e9c5780601f10610e7157610100808354040283529160200191610e9c565b820191906000526020600020905b815481529060010190602001808311610e7f57829003601f168201915b505050505090508051600003610eec5783838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929450610db09350505050565b6000839003610efc579050610db0565b60028310610f7a57610f4384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506119b392505050565b80610f518460028188612b16565b604051602001610f6393929190612b40565b604051602081830303815290604052915050610db0565b8383604051639a6d49cd60e01b8152600401610ae8929190612b91565b60005b818110156110a05736838383818110610fb557610fb5612ba5565b9050602002810190610fc79190612bbb565b9050610ffa610fd9602083018361273f565b602083013563ffffffff919091166000908152600160205260409020541490565b6110045750611098565b3063d045a0dc60c08301358360a0810135611023610100830183612bdc565b611034610100890160e08a01612637565b6110426101208a018a612bdc565b6040518963ffffffff1660e01b81526004016110649796959493929190612c37565b6000604051808303818588803b15801561107d57600080fd5b505af1158015611091573d6000803e3d6000fd5b5050505050505b600101610f9a565b50336001600160a01b0316638e9e70996040518163ffffffff1660e01b8152600401600060405180830381865afa1580156110df573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526111079190810190612cbd565b604051638351eea760e01b8152600401610ae891906122bb565b611129612224565b60408051808201909152600080825260208201526111488585856119df565b915091505b935093915050565b61115d6115a0565b60405163ca5eb5e160e01b81526001600160a01b0382811660048301527f0000000000000000000000001a44076050125825900e736c501f859c50fe728c169063ca5eb5e190602401600060405180830381600087803b1580156111c057600080fd5b505af11580156111d4573d6000803e3d6000fd5b5050505050565b3330146111fb5760405163029a949d60e31b815260040160405180910390fd5b610b5887878787878787610b49565b6112126115a0565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527fd48d879cef83a1c0bdda516f27b13ddb1b3f8bbac1c9e1511bb2a659c242776090602001610d84565b6112686115a0565b6001600160a01b03811661129257604051631e4fbdf760e01b815260006004820152602401610ae8565b610c8a8161185c565b60006020820180359060019083906112b3908661273f565b63ffffffff1681526020810191909152604001600020541492915050565b6112de8383836001611ada565b505050565b6000806112ef85611baf565b91508190508381101561114d576040516371c4efed60e01b81526004810182905260248101859052604401610ae8565b63ffffffff81166000908152600160205260408120548061090a5760405163f6ff4fb760e01b815263ffffffff84166004820152602401610ae8565b600061136d61136a8787611be6565b90565b90506000611399826113876113828a8a611bfe565b611c21565b61139460208d018d61273f565b611c56565b905060288611156114605760006113d66113b960608c0160408d01612d2a565b6113c660208d018d61273f565b846113d18c8c611c7e565b611cc9565b604051633e5ac80960e11b81529091506001600160a01b037f0000000000000000000000001a44076050125825900e736c501f859c50fe728c1690637cb590129061142c9086908d906000908790600401612d47565b600060405180830381600087803b15801561144657600080fd5b505af115801561145a573d6000803e3d6000fd5b50505050505b6001600160a01b038216887fefed6d3500546b29533b128a29e3a94d70788727f0507505ac12eaf2e578fd9c61149960208d018d61273f565b6040805163ffffffff9092168252602082018690520160405180910390a3505050505050505050565b6001600160a01b0383811660009081526006602090815260408083209386168352929052205460001981101561153b578181101561152c57604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610ae8565b61153b84848484036000611ada565b50505050565b6001600160a01b03831661156b57604051634b637e8f60e11b815260006004820152602401610ae8565b6001600160a01b0382166115955760405163ec442f0560e01b815260006004820152602401610ae8565b6112de838383611cfb565b6000546001600160a01b03163314610da15760405163118cdaa760e01b8152336004820152602401610ae8565b63ffffffff8216600081815260016020908152604091829020849055815192835282018390527f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b910160405180910390a15050565b606080600061167f856020013561163886611e25565b61164560a0890189612bdc565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e7f92505050565b9093509050600081611692576001611695565b60025b90506116b56116a7602088018861273f565b8261073260808a018a612bdc565b6004549093506001600160a01b0316801561173b5760405163043a78eb60e01b81526001600160a01b0382169063043a78eb906116f89088908890600401612d78565b602060405180830381865afa158015611715573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117399190612943565b505b5050509250929050565b60408051808201909152600080825260208201527f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b031663ddc28c586040518060a001604052808863ffffffff1681526020016117a88961131f565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b81526004016117dd929190612d9d565b6040805180830381865afa1580156117f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181d9190612e46565b95945050505050565b6001600160a01b0382166118505760405163ec442f0560e01b815260006004820152602401610ae8565b610b9960008383611cfb565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60005b8151811015611983576118de8282815181106118cd576118cd612ba5565b6020026020010151604001516119b3565b8181815181106118f0576118f0612ba5565b6020026020010151604001516003600084848151811061191257611912612ba5565b60200260200101516000015163ffffffff1663ffffffff168152602001908152602001600020600084848151811061194c5761194c612ba5565b60200260200101516020015161ffff1661ffff168152602001908152602001600020908161197a9190612eb2565b506001016118af565b507fbe4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b67481604051610d849190612f71565b600281015161ffff8116600314610b995781604051639a6d49cd60e01b8152600401610ae891906122bb565b6119e7612224565b6040805180820190915260008082526020820152600080611a1e33604089013560608a0135611a1960208c018c61273f565b611ef9565b91509150600080611a2f8984611622565b9092509050611a5b611a4460208b018b61273f565b8383611a55368d90038d018d612ffc565b8b611f1f565b60408051808201909152858152602080820186905282519298509096503391907f85496b760a4b7f8d66384b9df21b381f5d1b1e79f229a47aaf4c232edc2fe59a90611aa9908d018d61273f565b6040805163ffffffff909216825260208201899052810187905260600160405180910390a350505050935093915050565b6001600160a01b038416611b045760405163e602df0560e01b815260006004820152602401610ae8565b6001600160a01b038316611b2e57604051634a1406b160e11b815260006004820152602401610ae8565b6001600160a01b038085166000908152600660209081526040808320938716835292905220829055801561153b57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051611ba191815260200190565b60405180910390a350505050565b60007f000000000000000000000000000000000000000000000000000000e8d4a51000611bdc8184613044565b61090a9190613066565b6000611bf56020828486612b16565b610b809161307d565b6000611c0e602860208486612b16565b611c179161309b565b60c01c9392505050565b600061090a7f000000000000000000000000000000000000000000000000000000e8d4a510006001600160401b038416613066565b60006001600160a01b038416611c6c5761dead93505b611c768484611826565b509092915050565b6060611c8d8260288186612b16565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929695505050505050565b606084848484604051602001611ce294939291906130cb565b6040516020818303038152906040529050949350505050565b6001600160a01b038316611d26578060076000828254611d1b919061311a565b90915550611d989050565b6001600160a01b03831660009081526005602052604090205481811015611d795760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610ae8565b6001600160a01b03841660009081526005602052604090209082900390555b6001600160a01b038216611db457600780548290039055611dd3565b6001600160a01b03821660009081526005602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611e1891815260200190565b60405180910390a3505050565b600080611e527f000000000000000000000000000000000000000000000000000000e8d4a5100084613044565b90506001600160401b0381111561090a5760405163e2ce941360e01b815260048101829052602401610ae8565b8051606090151580611ec8578484604051602001611eb492919091825260c01b6001600160c01b031916602082015260280190565b604051602081830303815290604052611eef565b84843385604051602001611edf949392919061312d565b6040516020818303038152906040525b9150935093915050565b600080611f078585856112e3565b9092509050611f16868361202a565b94509492505050565b611f27612224565b6000611f368460000151612060565b602085015190915015611f5057611f508460200151612088565b7f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b0316632637a450826040518060a001604052808b63ffffffff168152602001611fa08c61131f565b81526020018a815260200189815260200160008960200151111515815250866040518463ffffffff1660e01b8152600401611fdc929190612d9d565b60806040518083038185885af1158015611ffa573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061201f9190613170565b979650505050505050565b6001600160a01b03821661205457604051634b637e8f60e11b815260006004820152602401610ae8565b610b9982600083611cfb565b6000813414612084576040516304fb820960e51b8152346004820152602401610ae8565b5090565b60007f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b031663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061210c91906128f7565b90506001600160a01b038116612135576040516329b99a9560e11b815260040160405180910390fd5b6040805133602482018190527f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b0381811660448501526064808501889052855180860390910181526084909401909452602080840180516001600160e01b03166323b872dd60e01b1781528451610b9996881695899361153b93889360009283929091839182885af1806121d6576040513d6000823e3d81fd5b50506000513d915081156121ee5780600114156121fb565b6001600160a01b0384163b155b1561153b57604051635274afe760e01b81526001600160a01b0385166004820152602401610ae8565b60405180606001604052806000801916815260200160006001600160401b03168152602001612266604051806040016040528060008152602001600081525090565b905290565b60005b8381101561228657818101518382015260200161226e565b50506000910152565b600081518084526122a781602086016020860161226b565b601f01601f19169290920160200192915050565b602081526000610b80602083018461228f565b6001600160a01b0381168114610c8a57600080fd5b600080604083850312156122f657600080fd5b8235612301816122ce565b946020939093013593505050565b600060e0828403121561232157600080fd5b50919050565b60006020828403121561233957600080fd5b81356001600160401b0381111561234f57600080fd5b610db08482850161230f565b8351815260208085015190820152600060a08201604060a0604085015281865180845260c08601915060c08160051b8701019350602080890160005b838110156123d65788870360bf190185528151805188528301518388018790526123c38789018261228f565b9750509382019390820190600101612397565b50508751606088015250505060208501516080850152509050610db0565b60006060828403121561232157600080fd5b60008083601f84011261241857600080fd5b5081356001600160401b0381111561242f57600080fd5b60208301915083602082850101111561244757600080fd5b9250929050565b600080600080600080600060e0888a03121561246957600080fd5b61247389896123f4565b96506060880135955060808801356001600160401b038082111561249657600080fd5b6124a28b838c01612406565b909750955060a08a013591506124b7826122ce565b90935060c089013590808211156124cd57600080fd5b506124da8a828b01612406565b989b979a50959850939692959293505050565b60008060006060848603121561250257600080fd5b833561250d816122ce565b9250602084013561251d816122ce565b929592945050506040919091013590565b803563ffffffff8116811461254257600080fd5b919050565b6000806040838503121561255a57600080fd5b6123018361252e565b8015158114610c8a57600080fd5b6000806040838503121561258457600080fd5b82356001600160401b0381111561259a57600080fd5b6125a68582860161230f565b92505060208301356125b781612563565b809150509250929050565b81518152602080830151908201526040810161090a565b6000602082840312156125eb57600080fd5b5035919050565b803561ffff8116811461254257600080fd5b6000806040838503121561261757600080fd5b6126208361252e565b915061262e602084016125f2565b90509250929050565b60006020828403121561264957600080fd5b8135610b80816122ce565b60008060008060a0858703121561266a57600080fd5b61267486866123f4565b935060608501356001600160401b0381111561268f57600080fd5b61269b87828801612406565b90945092505060808501356126af816122ce565b939692955090935050565b60008083601f8401126126cc57600080fd5b5081356001600160401b038111156126e357600080fd5b6020830191508360208260051b850101111561244757600080fd5b6000806020838503121561271157600080fd5b82356001600160401b0381111561272757600080fd5b612733858286016126ba565b90969095509350505050565b60006020828403121561275157600080fd5b610b808261252e565b6000806000806060858703121561277057600080fd5b6127798561252e565b9350612787602086016125f2565b925060408501356001600160401b038111156127a257600080fd5b6127ae87828801612406565b95989497509550505050565b600080600083850360808112156127d057600080fd5b84356001600160401b038111156127e657600080fd5b6127f28782880161230f565b9450506040601f198201121561280757600080fd5b50602084019150606084013561281c816122ce565b809150509250925092565b600060c082019050835182526001600160401b0360208501511660208301526040840151612862604084018280518252602090810151910152565b5082516080830152602083015160a0830152610b80565b6000806040838503121561288c57600080fd5b8235612897816122ce565b915060208301356125b7816122ce565b6000606082840312156128b957600080fd5b610b8083836123f4565b600181811c908216806128d757607f821691505b60208210810361232157634e487b7160e01b600052602260045260246000fd5b60006020828403121561290957600080fd5b8151610b80816122ce565b60006020828403121561292657600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561295557600080fd5b8151610b8081612563565b604051606081016001600160401b03811182821017156129825761298261292d565b60405290565b604080519081016001600160401b03811182821017156129825761298261292d565b604051601f8201601f191681016001600160401b03811182821017156129d2576129d261292d565b604052919050565b60006001600160401b038211156129f3576129f361292d565b50601f01601f191660200190565b60006001600160401b0380841115612a1b57612a1b61292d565b8360051b6020612a2c8183016129aa565b868152918501918181019036841115612a4457600080fd5b865b84811015612b0a57803586811115612a5e5760008081fd5b88016060368290031215612a725760008081fd5b612a7a612960565b612a838261252e565b8152612a908683016125f2565b8682015260408083013589811115612aa85760008081fd5b929092019136601f840112612abd5760008081fd5b8235612ad0612acb826129da565b6129aa565b8181523689838701011115612ae55760008081fd5b818986018a830137600091810189019190915290820152845250918301918301612a46565b50979650505050505050565b60008085851115612b2657600080fd5b83861115612b3357600080fd5b5050820193919092039150565b60008451612b5281846020890161226b565b8201838582376000930192835250909392505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b602081526000610db0602083018486612b68565b634e487b7160e01b600052603260045260246000fd5b6000823561013e19833603018112612bd257600080fd5b9190910192915050565b6000808335601e19843603018112612bf357600080fd5b8301803591506001600160401b03821115612c0d57600080fd5b60200191503681900382131561244757600080fd5b6001600160401b0381168114610c8a57600080fd5b63ffffffff612c458961252e565b1681526020880135602082015260006040890135612c6281612c22565b6001600160401b03811660408401525087606083015260e06080830152612c8d60e083018789612b68565b6001600160a01b03861660a084015282810360c0840152612caf818587612b68565b9a9950505050505050505050565b600060208284031215612ccf57600080fd5b81516001600160401b03811115612ce557600080fd5b8201601f81018413612cf657600080fd5b8051612d04612acb826129da565b818152856020838501011115612d1957600080fd5b61181d82602083016020860161226b565b600060208284031215612d3c57600080fd5b8135610b8081612c22565b60018060a01b038516815283602082015261ffff83166040820152608060608201526000610bfa608083018461228f565b604081526000612d8b604083018561228f565b828103602084015261181d818561228f565b6040815263ffffffff8351166040820152602083015160608201526000604084015160a06080840152612dd360e084018261228f565b90506060850151603f198483030160a0850152612df0828261228f565b60809690960151151560c08501525050506001600160a01b039190911660209091015290565b600060408284031215612e2857600080fd5b612e30612988565b9050815181526020820151602082015292915050565b600060408284031215612e5857600080fd5b610b808383612e16565b601f8211156112de576000816000526020600020601f850160051c81016020861015612e8b5750805b601f850160051c820191505b81811015612eaa57828155600101612e97565b505050505050565b81516001600160401b03811115612ecb57612ecb61292d565b612edf81612ed984546128c3565b84612e62565b602080601f831160018114612f145760008415612efc5750858301515b600019600386901b1c1916600185901b178555612eaa565b600085815260208120601f198616915b82811015612f4357888601518255948401946001909101908401612f24565b5085821015612f615787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b83811015612fee57888303603f190185528151805163ffffffff1684528781015161ffff16888501528601516060878501819052612fda8186018361228f565b968901969450505090860190600101612f9a565b509098975050505050505050565b60006040828403121561300e57600080fd5b613016612988565b82358152602083013560208201528091505092915050565b634e487b7160e01b600052601160045260246000fd5b60008261306157634e487b7160e01b600052601260045260246000fd5b500490565b808202811582820484141761090a5761090a61302e565b8035602083101561090a57600019602084900360031b1b1692915050565b6001600160c01b031981358181169160088510156130c35780818660080360031b1b83161692505b505092915050565b6001600160401b0360c01b8560c01b16815263ffffffff60e01b8460e01b16600882015282600c8201526000825161310a81602c85016020870161226b565b91909101602c0195945050505050565b8082018082111561090a5761090a61302e565b8481526001600160401b0360c01b8460c01b1660208201528260288201526000825161316081604885016020870161226b565b9190910160480195945050505050565b60006080828403121561318257600080fd5b61318a612960565b82518152602083015161319c81612c22565b60208201526131ae8460408501612e16565b6040820152939250505056fea2646970667358221220c97ac570e782e4bd78ea6115c982379c92c33ffa85c7286cb83aa4d58cf7f54164736f6c63430008160033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000001a44076050125825900e736c501f859c50fe728c000000000000000000000000646c7089bfeca23c2278b3848dae78d7b5d8b74d000000000000000000000000a11bd36801d8fa4448f0ac4ea7a62e3634ce8c7c000000000000000000000000000000000000000000000000000000000000000e416c6c627269646765205a65726f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044142523000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _name (string): Allbridge Zero
Arg [1] : _symbol (string): ABR0
Arg [2] : _lzEndpoint (address): 0x1a44076050125825900e736c501f859c50fE728c
Arg [3] : _delegate (address): 0x646c7089bfEca23C2278b3848daE78d7b5d8B74d
Arg [4] : _oldTokenAddress (address): 0xa11bD36801d8fa4448F0ac4ea7A62e3634cE8C7C
-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [2] : 0000000000000000000000001a44076050125825900e736c501f859c50fe728c
Arg [3] : 000000000000000000000000646c7089bfeca23c2278b3848dae78d7b5d8b74d
Arg [4] : 000000000000000000000000a11bd36801d8fa4448f0ac4ea7a62e3634ce8c7c
Arg [5] : 000000000000000000000000000000000000000000000000000000000000000e
Arg [6] : 416c6c627269646765205a65726f000000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [8] : 4142523000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
266:519:39:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1760:89:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3902:186;;;;;;;;;;-1:-1:-1;3902:186:33;;;;;:::i;:::-;;:::i;:::-;;;1391:14:40;;1384:22;1366:41;;1354:2;1339:18;3902:186:33;1226:187:40;5176:1276:24;;;;;;;;;;-1:-1:-1;5176:1276:24;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;2330:27::-;;;;;;;;;;-1:-1:-1;2330:27:24;;;;-1:-1:-1;;;;;2330:27:24;;;;;;-1:-1:-1;;;;;3605:32:40;;;3587:51;;3575:2;3560:18;2330:27:24;3441:203:40;4368:708:12;;;;;;:::i;:::-;;:::i;:::-;;2204:40:24;;;;;;;;;;;;2243:1;2204:40;;;;;5385:6:40;5373:19;;;5355:38;;5343:2;5328:18;2204:40:24;5211:188:40;3475:140:24;;;;;;;;;;-1:-1:-1;3475:140:24;;;-1:-1:-1;;;5574:52:40;;3606:1:24;5657:2:40;5642:18;;5635:59;5547:18;3475:140:24;5404:296:40;1287:235:10;;;;;;;;;;-1:-1:-1;1287:235:10;;;843:1:13;5912:34:40;;678:1:12;5977:2:40;5962:18;;5955:43;5848:18;1287:235:10;5705:299:40;2803:97:33;;;;;;;;;;-1:-1:-1;2881:12:33;;2803:97;;;6155:25:40;;;6143:2;6128:18;2803:97:33;6009:177:40;2167:31:24;;;;;;;;;;;;2197:1;2167:31;;4680:244:33;;;;;;;;;;-1:-1:-1;4680:244:33;;;;;:::i;:::-;;:::i;2688:82::-;;;;;;;;;;-1:-1:-1;2761:2:33;2688:82;;;6824:4:40;6812:17;;;6794:36;;6782:2;6767:18;2688:82:33;6652:184:40;1724:108:11;;;;;;;;;;-1:-1:-1;1724:108:11;;;;;:::i;:::-;;:::i;6903:774:24:-;;;;;;;;;;-1:-1:-1;6903:774:24;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;625:158:39:-;;;;;;;;;;-1:-1:-1;625:158:39;;;;;:::i;:::-;;:::i;875:93:19:-;;;;;;;;;;-1:-1:-1;956:4:19;875:93;;538::18;;;;;;;;;;-1:-1:-1;538:93:18;;;;;:::i;:::-;;:::i;16151:132:24:-;;;;;;;;;;-1:-1:-1;16151:132:24;;;;;:::i;:::-;16256:11;;;;;16233:4;16256:11;;;:5;:11;;;;;;:20;;16151:132;446:46:11;;;;;;;;;;;;;;;4657:163:24;;;;;;;;;;-1:-1:-1;4657:163:24;;;;;:::i;:::-;;:::i;2933:116:33:-;;;;;;;;;;-1:-1:-1;2933:116:33;;;;;:::i;:::-;-1:-1:-1;;;;;3024:18:33;2998:7;3024:18;;;:9;:18;;;;;;;2933:116;2293:101:28;;;;;;;;;;;;;:::i;3507:128:12:-;;;;;;;;;;-1:-1:-1;3507:128:12;;;;;:::i;:::-;3596:12;3507:128;;;;;;;;-1:-1:-1;;;;;9624:31:40;;;9606:50;;9594:2;9579:18;3507:128:12;9462:200:40;2013:216:12;;;;;;;;;;-1:-1:-1;2013:216:12;;;;;:::i;:::-;;:::i;4222:87:24:-;;;;;;;;;;-1:-1:-1;4301:1:24;4222:87;;1638:85:28;;;;;;;;;;-1:-1:-1;1684:7:28;1710:6;-1:-1:-1;;;;;1710:6:28;1638:85;;1962:93:33;;;;;;;;;;;;;:::i;1861:46:24:-;;;;;;;;;;;;;;;1460:94:23;;;;;;;;;;-1:-1:-1;1519:4:23;1460:94;;3244:178:33;;;;;;;;;;-1:-1:-1;3244:178:33;;;;;:::i;:::-;;:::i;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;8365:290:24:-;;;;;;:::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;302:29:39:-;;;;;;;;;;-1:-1:-1;302:29:39;;;;-1:-1:-1;;;;;302:29:39;;;3455:140:33;;;;;;;;;;-1:-1:-1;3455:140:33;;;;;:::i;:::-;-1:-1:-1;;;;;3561:18:33;;;3535:7;3561:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;3455:140;2543:215:28;;;;;;;;;;-1:-1:-1;2543:215:28;;;;;:::i;:::-;;:::i;2771:149:12:-;;;;;;;;;;-1:-1:-1;2771:149:12;;;;;:::i;:::-;;:::i;1760:89:33:-;1805:13;1837:5;1830:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1760:89;:::o;3902:186::-;3975:4;735:10:37;4029:31:33;735:10:37;4045:7:33;4054:5;4029:8;:31::i;:::-;4077:4;4070:11;;;3902:186;;;;;:::o;5176:1276:24:-;-1:-1:-1;;;;;;;;;;;;;;;;;5328:35:24;5365:28;-1:-1:-1;;;;;;;;;;;;;;;;;;;5365:28:24;5409:19;5483;5512:4;-1:-1:-1;;;;;5512:10:24;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;5505:32:24;;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5601;;;;;;;;;;;;;;;;;;5752:21;;-1:-1:-1;5752:21:24;;;;;;;;;5601:34;;-1:-1:-1;5601:34:24;;-1:-1:-1;5752:21:24;;;;-1:-1:-1;;;;;;;;;;;;;;;;;5752:21:24;;;;;;;;;;;;;;;-1:-1:-1;5736:37:24;-1:-1:-1;6210:20:24;;6260:120;6284:19;;;;6317:22;;;;6353:17;;;;6284:10;6353:17;:::i;:::-;6260:10;:120::i;:::-;6403:42;;;;;;;;;;;;;;;;5176:1276;;;;-1:-1:-1;;;;;;5176:1276:24: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;;;3587:51:40;3560: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;;15974:10:40;15962:23;;;4896:40:12;;;15944:42:40;4921:14:12;;;;16002:18:40;;;15995:34;15917:18;;4896:40:12;15772:263:40;4833:103:12;5010:59;5021:7;5030:5;5037:8;;5047:9;5058:10;;5010;:59::i;:::-;4368:708;;;;;;;:::o;4680:244:33:-;4767:4;735:10:37;4823:37:33;4839:4;735:10:37;4854:5:33;4823:15;:37::i;:::-;4870:26;4880:4;4886:2;4890:5;4870:9;:26::i;:::-;4913:4;4906:11;;;4680:244;;;;;;:::o;1724:108:11:-;1531:13:28;:11;:13::i;:::-;1804:21:11::1;1813:4;1819:5;1804:8;:21::i;:::-;1724:108:::0;;:::o;6903:774:24:-;-1:-1:-1;;;;;;;;;;;;;;;;;7237:24:24;7265:74;7276:19;;;;7297:22;;;;7321:17;;;;7276:10;7321:17;:::i;7265:74::-;7234:105;;;7428:20;7450;7474:49;7494:10;7506:16;7474:19;:49::i;:::-;7427:96;;-1:-1:-1;7427:96:24;-1:-1:-1;7612:58:24;7619:17;;;;:10;:17;:::i;:::-;7638:7;7647;7656:13;7612:6;:58::i;:::-;7605:65;6903:774;-1:-1:-1;;;;;;6903:774:24:o;625:158:39:-;676:15;;:64;;-1:-1:-1;;;676:64:39;;705:10;676:64;;;16280:34:40;725:4:39;16330:18:40;;;16323:43;16382:18;;;16375:34;;;-1:-1:-1;;;;;676:15:39;;;;:28;;16215:18:40;;676:64:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;750:26;756:10;768:7;750:5;:26::i;:::-;625:158;:::o;538:93:18:-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;4657:163:24:-;1531:13:28;:11;:13::i;:::-;4740:12:24::1;:28:::0;;-1:-1:-1;;;;;;4740:28:24::1;-1:-1:-1::0;;;;;4740:28:24;::::1;::::0;;::::1;::::0;;;4783:30:::1;::::0;3587:51:40;;;4783:30:24::1;::::0;3575:2:40;3560:18;4783:30:24::1;;;;;;;;4657:163:::0;:::o;2293:101:28:-;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;1962:93:33:-;2009:13;2041:7;2034:14;;;;;:::i;3244:178::-;3313:4;735:10:37;3367:27:33;735:10:37;3384:2:33;3388:5;3367:9;:27::i;1391:156:18:-;1531:13:28;: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;;;;16256:11:24;;;;;16233:4;16256:11;;;:5;:11;;;;;;:20;;16151: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;8365:290:24:-;8526:34;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;8609:39:24;8615:10;8627:4;8633:14;8609:5;:39::i;:::-;8602:46;;;;8365:290;;;;;;;:::o;3252:105:11:-;1531:13:28;:11;:13::i;:::-;3319:31:11::1;::::0;-1:-1:-1;;;3319:31:11;;-1:-1:-1;;;;;3605:32:40;;;3319:31:11::1;::::0;::::1;3587:51:40::0;3319:8:11::1;:20;::::0;::::1;::::0;3560:18:40;;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:28;: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;3587:51:40;;;1210:22:19::1;::::0;3575:2:40;3560:18;1210:22:19::1;3441:203:40::0;2543:215:28;1531:13;:11;:13::i;:::-;-1:-1:-1;;;;;2627:22:28;::::1;2623:91;;2672:31;::::0;-1:-1:-1;;;2672:31:28;;2700:1:::1;2672:31;::::0;::::1;3587:51:40::0;3560:18;;2672:31:28::1;3441:203:40::0;2623:91:28::1;2723:28;2742:8;2723:18;:28::i;2771:149:12:-:0;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;8630:128:33:-;8714:37;8723:5;8730:7;8739:5;8746:4;8714:8;:37::i;:::-;8630:128;;;:::o;18463:668:24:-;18605:20;18627:24;18801:22;18813:9;18801:11;:22::i;:::-;18786:37;;18949:12;18930:31;;19031:12;19012:16;:31;19008:117;;;19066:48;;-1:-1:-1;;;19066:48:24;;;;;24067:25:40;;;24108:18;;;24101:34;;;24040:18;;19066:48:24;23893:248:40;2718:196:11;2822:11;;;2788:7;2822:11;;;:5;:11;;;;;;;2843:43;;2874:12;;-1:-1:-1;;;2874:12:11;;24320:10:40;24308:23;;2874:12:11;;;24290:42:40;24263:18;;2874:12:11;24146:192:40;12944:1806:24;13421:17;13441:36;:17;:8;;:15;:17::i;:::-;2891:2:27;2780:123;13441:36:24;13421:56;;13610:24;13637:62;13645:9;13656:26;13662:19;:8;;:17;:19::i;:::-;13656:5;:26::i;:::-;13684:14;;;;:7;:14;:::i;:::-;13637:7;:62::i;:::-;13610:89;-1:-1:-1;243:2:27;-1:-1:-1;;13710:955:24;;;13814:23;13840:175;13883:13;;;;;;;;:::i;:::-;13914:14;;;;:7;:14;:::i;:::-;13946:16;13980:21;:8;;:19;:21::i;:::-;13840:25;:175::i;:::-;14562:92;;-1:-1:-1;;;14562:92:24;;13814:201;;-1:-1:-1;;;;;;14562:8:24;:20;;;;:92;;14583:9;;14594:5;;14601:1;;13814:201;;14562:92;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13737:928;13710:955;-1:-1:-1;;;;;14680:63:24;;14692:5;14680:63;14699:14;;;;:7;:14;:::i;:::-;14680:63;;;15974:10:40;15962:23;;;15944:42;;16017:2;16002:18;;15995:34;;;15917:18;14680:63:24;;;;;;;13247:1503;;12944:1806;;;;;;;:::o;10319:476:33:-;-1:-1:-1;;;;;3561:18:33;;;10418:24;3561:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;-1:-1:-1;;10484:36:33;;10480:309;;;10559:5;10540:16;:24;10536:130;;;10591:60;;-1:-1:-1;;;10591:60:33;;-1:-1:-1;;;;;25565:32:40;;10591:60:33;;;25547:51:40;25614:18;;;25607:34;;;25657:18;;;25650:34;;;25520:18;;10591:60:33;25345:345:40;10536:130:33;10707:57;10716:5;10723:7;10751:5;10732:16;:24;10758:5;10707:8;:57::i;:::-;10408:387;10319:476;;;:::o;5297:300::-;-1:-1:-1;;;;;5380:18:33;;5376:86;;5421:30;;-1:-1:-1;;;5421:30:33;;5448:1;5421:30;;;3587:51:40;3560:18;;5421:30:33;3441:203:40;5376:86:33;-1:-1:-1;;;;;5475:16:33;;5471:86;;5514:32;;-1:-1:-1;;;5514:32:33;;5543:1;5514:32;;;3587:51:40;3560:18;;5514:32:33;3441:203:40;5471:86:33;5566:24;5574:4;5580:2;5584:5;5566:7;:24::i;1796:162:28:-;1684:7;1710:6;-1:-1:-1;;;;;1710:6:28;735:10:37;1855:23:28;1851:101;;1901:40;;-1:-1:-1;;;1901:40:28;;735:10:37;1901:40:28;;;3587:51:40;3560:18;;1901:40:28;3441:203:40;2286:134:11;2359:11;;;;;;;:5;:11;;;;;;;;;:19;;;2393:20;;15944:42:40;;;16002:18;;15995:34;;;2393:20:11;;15917:18:40;2393:20:11;;;;;;;2286:134;;:::o;10990:1436:24:-;11122:20;11144;11176:15;11347:324;11379:10;:13;;;11406:16;11412:9;11406:5;:16::i;:::-;11640:21;;;;:10;:21;:::i;:::-;11347:324;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11347:18:24;;-1:-1:-1;;;11347:324:24:i;:::-;11323:348;;-1:-1:-1;11323:348:24;-1:-1:-1;11751:14:24;11323:348;11768:33;;2197:1;11768:33;;;2243:1;11768:33;11751:50;-1:-1:-1;11923:67:24;11938:17;;;;:10;:17;:::i;:::-;11957:7;11966:23;;;;:10;:23;:::i;11923:67::-;12248:12;;11913:77;;-1:-1:-1;;;;;;12248:12:24;12340:23;;12336:83;;12365:54;;-1:-1:-1;;;12365:54:24;;-1:-1:-1;;;;;12365:36:24;;;;;:54;;12402:7;;12411;;12365:54;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;12336:83;11166:1260;;;10990: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;7362:208:33:-;-1:-1:-1;;;;;7432:21:33;;7428:91;;7476:32;;-1:-1:-1;;;7476:32:33;;7505:1;7476:32;;;3587:51:40;3560:18;;7476:32:33;3441:203:40;7428:91:33;7528:35;7544:1;7548:7;7557:5;7528:7;:35::i;2912:187:28:-;2985:16;3004:6;;-1:-1:-1;;;;;3020:17:28;;;-1:-1:-1;;;;;;3020:17:28;;;;;;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;9363:1333:24:-;9517:34;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;9915:20:24;;9965:140;9985:10;10009:19;;;;10042:22;;;;10078:17;;;;10009:10;10078:17;:::i;:::-;9965:6;:140::i;:::-;9914:191;;;;10194:20;10216;10240:49;10260:10;10272:16;10240:19;:49::i;:::-;10193:96;;-1:-1:-1;10193:96:24;-1:-1:-1;10412:66:24;10420:17;;;;:10;:17;:::i;:::-;10439:7;10448;10412:66;;;;;;;10457:4;10412:66;:::i;:::-;10463:14;10412:7;:66::i;:::-;10544:42;;;;;;;;;;;;;;;;;;;10610:15;;10399:79;;-1:-1:-1;10544:42:24;;-1:-1:-1;10646:10:24;;10610:15;10602:87;;10627:17;;;;:10;:17;:::i;:::-;10602:87;;;31461:10:40;31449:23;;;31431:42;;31504:2;31489:18;;31482:34;;;31532:18;;31525:34;;;31419:2;31404:18;10602:87:24;;;;;;;9583:1113;;;;9363:1333;;;;;;:::o;9605:432:33:-;-1:-1:-1;;;;;9717:19:33;;9713:89;;9759:32;;-1:-1:-1;;;9759:32:33;;9788:1;9759:32;;;3587:51:40;3560:18;;9759:32:33;3441:203:40;9713:89:33;-1:-1:-1;;;;;9815:21:33;;9811:90;;9859:31;;-1:-1:-1;;;9859:31:33;;9887:1;9859:31;;;3587:51:40;3560:18;;9859:31:33;3441:203:40;9811:90:33;-1:-1:-1;;;;;9910:18:33;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;:35;;;9955:76;;;;10005:7;-1:-1:-1;;;;;9989:31:33;9998:5;-1:-1:-1;;;;;9989:31:33;;10014:5;9989:31;;;;6155:25:40;;6143:2;6128:18;;6009:177;9989:31:33;;;;;;;;9605:432;;;;:::o;16677:172:24:-;16748:16;16821:21;16784:33;16821:21;16784:9;:33;:::i;:::-;16783:59;;;;:::i;1573:123:27:-;1633:7;1667:21;188:2;1633:7;1667:4;;:21;:::i;:::-;1659:30;;;:::i;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:27:o;17073:139:24:-;17137:16;17172:33;17184:21;-1:-1:-1;;;;;17172:33:24;;;:::i;2939:462:23:-;3073:24;-1:-1:-1;;;;;3113:19:23;;3109:46;;3148:6;3134:21;;3109:46;3251:21;3257:3;3262:9;3251:5;:21::i;:::-;-1:-1:-1;3385:9:23;;2939:462;-1:-1:-1;;2939:462:23:o;2186:130:27:-;2250:12;2281:28;:4;243:2;2281:4;;:28;:::i;:::-;2274:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2274:35:27;;2186:130;-1:-1:-1;;;;;;2186:130:27:o;640:284:26:-;824:17;877:6;885:7;894:9;905:11;860:57;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;853:64;;640:284;;;;;;:::o;5912:1107:33:-;-1:-1:-1;;;;;6001:18:33;;5997:540;;6153:5;6137:12;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;5997:540:33;;-1:-1:-1;5997:540:33;;-1:-1:-1;;;;;6211:15:33;;6189:19;6211:15;;;:9;:15;;;;;;6244:19;;;6240:115;;;6290:50;;-1:-1:-1;;;6290:50:33;;-1:-1:-1;;;;;25565:32:40;;6290:50:33;;;25547:51:40;25614:18;;;25607:34;;;25657:18;;;25650:34;;;25520:18;;6290:50:33;25345:345:40;6240:115:33;-1:-1:-1;;;;;6475:15:33;;;;;;:9;:15;;;;;6493:19;;;;6475:37;;5997:540;-1:-1:-1;;;;;6551:16:33;;6547:425;;6714:12;:21;;;;;;;6547:425;;;-1:-1:-1;;;;;6925:13:33;;;;;;:9;:13;;;;;:22;;;;;;6547:425;7002:2;-1:-1:-1;;;;;6987:25:33;6996:4;-1:-1:-1;;;;;6987:25:33;;7006:5;6987:25;;;;6155::40;;6143:2;6128:18;;6009:177;6987:25:33;;;;;;;;5912:1107;;;:::o;17612:266:24:-;17677:15;;17724:33;17736:21;17724:9;:33;:::i;:::-;17704:53;-1:-1:-1;;;;;;17771:28:24;;17767:70;;;17808:29;;-1:-1:-1;;;17808:29:24;;;;;6155:25:40;;;6128:18;;17808:29:24;6009:177:40;598:506:27;791:18;;732:17;;791:22;;;934:163;;1074:7;1083:13;1057:40;;;;;;;;33551:19:40;;;33626:3;33604:16;-1:-1:-1;;;;;;33600:51:40;33595:2;33586:12;;33579:73;33677:2;33668:12;;33396:290;1057:40:27;;;;;;;;;;;;;934:163;;;976:7;985:13;1017:10;1030:11;959:83;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;934:163;927:170;;598:506;;;;;;:::o;2037:567:23:-;2198:20;2220:24;2291:44;2302:9;2313:12;2327:7;2291:10;:44::i;:::-;2256:79;;-1:-1:-1;2256:79:23;-1:-1:-1;2571:26:23;2577:5;2256:79;2571:5;:26::i;:::-;2037:567;;;;;;;:::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;7888:206:33:-;-1:-1:-1;;;;;7958:21:33;;7954:89;;8002:30;;-1:-1:-1;;;8002:30:33;;8029:1;8002:30;;;3587:51:40;3560:18;;8002:30:33;3441:203:40;7954:89:33;8052:35;8060:7;8077:1;8081:5;8052:7;:35::i;4650:191:13:-;4716:17;4762:10;4749:9;:23;4745:62;;4781:26;;-1:-1:-1;;;4781:26:13;;4797:9;4781:26;;;6155:25:40;6128:18;;4781:26:13;6009:177:40;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;1745:53:36;;;5578:10:13;1745:53:36;;;16280:34:40;;;5598:8:13;-1:-1:-1;;;;;16350:15:40;;;16330:18;;;16323:43;16382:18;;;;16375:34;;;1745:53:36;;;;;;;;;;16215:18:40;;;;1745:53:36;;;;;;;;;-1:-1:-1;;;;;1745:53:36;-1:-1:-1;;;1745:53:36;;;8600:11;;5545:76:13;;:32;;;5609:11;;1718:81:36;;5545:32:13;;-1:-1:-1;;;;1745:53:36;;-1:-1:-1;;;5545:32:13;8566:5:36;8561:60;8673:7;8663:176;;8717:4;8711:11;8762:16;8759:1;8754:3;8739:40;8808:16;8803:3;8796:29;8663:176;-1:-1:-1;;8916:1:36;8910:8;8866:16;;-1:-1:-1;8942:15:36;;:68;;8994:11;9009:1;8994:16;;8942:68;;;-1:-1:-1;;;;;8960:26:36;;;:31;8942:68;8938:146;;;9033:40;;-1:-1:-1;;;9033:40:36;;-1:-1:-1;;;;;3605:32:40;;9033:40:36;;;3587:51:40;3560:18;;9033:40:36;3441:203:40;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:250:40:-;99:1;109:113;123:6;120:1;117:13;109:113;;;199:11;;;193:18;180:11;;;173:39;145:2;138:10;109:113;;;-1:-1:-1;;256:1:40;238:16;;231:27;14:250::o;269:271::-;311:3;349:5;343:12;376:6;371:3;364:19;392:76;461:6;454:4;449:3;445:14;438:4;431:5;427:16;392:76;:::i;:::-;522:2;501:15;-1:-1:-1;;497:29:40;488:39;;;;529:4;484:50;;269:271;-1:-1:-1;;269:271:40:o;545:220::-;694:2;683:9;676:21;657:4;714:45;755:2;744:9;740:18;732:6;714:45;:::i;770:131::-;-1:-1:-1;;;;;845:31:40;;835:42;;825:70;;891:1;888;881:12;906:315;974:6;982;1035:2;1023:9;1014:7;1010:23;1006:32;1003:52;;;1051:1;1048;1041:12;1003:52;1090:9;1077:23;1109:31;1134:5;1109:31;:::i;:::-;1159:5;1211:2;1196:18;;;;1183:32;;-1:-1:-1;;;906:315:40:o;1418:158::-;1480:5;1525:3;1516:6;1511:3;1507:16;1503:26;1500:46;;;1542:1;1539;1532:12;1500:46;-1:-1:-1;1564:6:40;1418:158;-1:-1:-1;1418:158:40:o;1581:360::-;1669:6;1722:2;1710:9;1701:7;1697:23;1693:32;1690:52;;;1738:1;1735;1728:12;1690:52;1778:9;1765:23;-1:-1:-1;;;;;1803:6:40;1800:30;1797:50;;;1843:1;1840;1833:12;1797:50;1866:69;1927:7;1918:6;1907:9;1903:22;1866:69;:::i;2100:1336::-;2020:12;;2008:25;;2082:4;2071:16;;;2065:23;2049:14;;;2042:47;2466:4;2514:3;2499:19;;2591:2;2629:3;2624:2;2613:9;2609:18;2602:31;2653:6;2688;2682:13;2719:6;2711;2704:22;2757:3;2746:9;2742:19;2735:26;;2820:3;2810:6;2807:1;2803:14;2792:9;2788:30;2784:40;2770:54;;2843:4;2882;2874:6;2870:17;2905:1;2915:429;2929:6;2926:1;2923:13;2915:429;;;2994:22;;;-1:-1:-1;;2990:37:40;2978:50;;3051:13;;3092:9;;3077:25;;3141:11;;3135:18;3173:15;;;3166:27;;;3216:48;3248:15;;;3135:18;3216:48;:::i;:::-;3206:58;-1:-1:-1;;3322:12:40;;;;3287:15;;;;2951:1;2944:9;2915:429;;;-1:-1:-1;;2020:12:40;;3426:2;3411:18;;2008:25;-1:-1:-1;;;2082:4:40;2071:16;;2065:23;2049:14;;;2042:47;-1:-1:-1;3361:6:40;-1:-1:-1;3376:54:40;1946:149;3649:154;3708:5;3753:2;3744:6;3739:3;3735:16;3731:25;3728:45;;;3769:1;3766;3759:12;3808:347;3859:8;3869:6;3923:3;3916:4;3908:6;3904:17;3900:27;3890:55;;3941:1;3938;3931:12;3890:55;-1:-1:-1;3964:20:40;;-1:-1:-1;;;;;3996:30:40;;3993:50;;;4039:1;4036;4029:12;3993:50;4076:4;4068:6;4064:17;4052:29;;4128:3;4121:4;4112:6;4104;4100:19;4096:30;4093:39;4090:59;;;4145:1;4142;4135:12;4090:59;3808:347;;;;;:::o;4160:1046::-;4301:6;4309;4317;4325;4333;4341;4349;4402:3;4390:9;4381:7;4377:23;4373:33;4370:53;;;4419:1;4416;4409:12;4370:53;4442;4487:7;4476:9;4442:53;:::i;:::-;4432:63;;4542:2;4531:9;4527:18;4514:32;4504:42;;4597:3;4586:9;4582:19;4569:33;-1:-1:-1;;;;;4662:2:40;4654:6;4651:14;4648:34;;;4678:1;4675;4668:12;4648:34;4717:58;4767:7;4758:6;4747:9;4743:22;4717:58;:::i;:::-;4794:8;;-1:-1:-1;4691:84:40;-1:-1:-1;4879:3:40;4864:19;;4851:33;;-1:-1:-1;4893:31:40;4851:33;4893:31;:::i;:::-;4943:5;;-1:-1:-1;5001:3:40;4986:19;;4973:33;;5018:16;;;5015:36;;;5047:1;5044;5037:12;5015:36;;5086:60;5138:7;5127:8;5116:9;5112:24;5086:60;:::i;:::-;4160:1046;;;;-1:-1:-1;4160:1046:40;;-1:-1:-1;4160:1046:40;;;;5060:86;;-1:-1:-1;;;4160:1046:40:o;6191:456::-;6268:6;6276;6284;6337:2;6325:9;6316:7;6312:23;6308:32;6305:52;;;6353:1;6350;6343:12;6305:52;6392:9;6379:23;6411:31;6436:5;6411:31;:::i;:::-;6461:5;-1:-1:-1;6518:2:40;6503:18;;6490:32;6531:33;6490:32;6531:33;:::i;:::-;6191:456;;6583:7;;-1:-1:-1;;;6637:2:40;6622:18;;;;6609:32;;6191:456::o;6841:163::-;6908:20;;6968:10;6957:22;;6947:33;;6937:61;;6994:1;6991;6984:12;6937:61;6841:163;;;:::o;7009:252::-;7076:6;7084;7137:2;7125:9;7116:7;7112:23;7108:32;7105:52;;;7153:1;7150;7143:12;7105:52;7176:28;7194:9;7176:28;:::i;7266:118::-;7352:5;7345:13;7338:21;7331:5;7328:32;7318:60;;7374:1;7371;7364:12;7389:489;7483:6;7491;7544:2;7532:9;7523:7;7519:23;7515:32;7512:52;;;7560:1;7557;7550:12;7512:52;7600:9;7587:23;-1:-1:-1;;;;;7625:6:40;7622:30;7619:50;;;7665:1;7662;7655:12;7619:50;7688:69;7749:7;7740:6;7729:9;7725:22;7688:69;:::i;:::-;7678:79;;;7807:2;7796:9;7792:18;7779:32;7820:28;7842:5;7820:28;:::i;:::-;7867:5;7857:15;;;7389:489;;;;;:::o;7883:253::-;2020:12;;2008:25;;2082:4;2071:16;;;2065:23;2049:14;;;2042:47;8073:2;8058:18;;8085:45;1946:149;8141:180;8200:6;8253:2;8241:9;8232:7;8228:23;8224:32;8221:52;;;8269:1;8266;8259:12;8221:52;-1:-1:-1;8292:23:40;;8141:180;-1:-1:-1;8141:180:40:o;8326:159::-;8393:20;;8453:6;8442:18;;8432:29;;8422:57;;8475:1;8472;8465:12;8490:256;8556:6;8564;8617:2;8605:9;8596:7;8592:23;8588:32;8585:52;;;8633:1;8630;8623:12;8585:52;8656:28;8674:9;8656:28;:::i;:::-;8646:38;;8703:37;8736:2;8725:9;8721:18;8703:37;:::i;:::-;8693:47;;8490:256;;;;;:::o;9210:247::-;9269:6;9322:2;9310:9;9301:7;9297:23;9293:32;9290:52;;;9338:1;9335;9328:12;9290:52;9377:9;9364:23;9396:31;9421:5;9396:31;:::i;9667:668::-;9779:6;9787;9795;9803;9856:3;9844:9;9835:7;9831:23;9827:33;9824:53;;;9873:1;9870;9863:12;9824:53;9896;9941:7;9930:9;9896:53;:::i;:::-;9886:63;;10000:2;9989:9;9985:18;9972:32;-1:-1:-1;;;;;10019:6:40;10016:30;10013:50;;;10059:1;10056;10049:12;10013:50;10098:58;10148:7;10139:6;10128:9;10124:22;10098:58;:::i;:::-;10175:8;;-1:-1:-1;10072:84:40;-1:-1:-1;;10260:3:40;10245:19;;10232:33;10274:31;10232:33;10274:31;:::i;:::-;9667:668;;;;-1:-1:-1;9667:668:40;;-1:-1:-1;;9667:668:40:o;10340:395::-;10431:8;10441:6;10495:3;10488:4;10480:6;10476:17;10472:27;10462:55;;10513:1;10510;10503:12;10462:55;-1:-1:-1;10536:20:40;;-1:-1:-1;;;;;10568:30:40;;10565:50;;;10611:1;10608;10601:12;10565:50;10648:4;10640:6;10636:17;10624:29;;10708:3;10701:4;10691:6;10688:1;10684:14;10676:6;10672:27;10668:38;10665:47;10662:67;;;10725:1;10722;10715:12;10740:504;10865:6;10873;10926:2;10914:9;10905:7;10901:23;10897:32;10894:52;;;10942:1;10939;10932:12;10894:52;10982:9;10969:23;-1:-1:-1;;;;;11007:6:40;11004:30;11001:50;;;11047:1;11044;11037:12;11001:50;11086:98;11176:7;11167:6;11156:9;11152:22;11086:98;:::i;:::-;11203:8;;11060:124;;-1:-1:-1;10740:504:40;-1:-1:-1;;;;10740:504:40:o;11249:184::-;11307:6;11360:2;11348:9;11339:7;11335:23;11331:32;11328:52;;;11376:1;11373;11366:12;11328:52;11399:28;11417:9;11399:28;:::i;11620:553::-;11706:6;11714;11722;11730;11783:2;11771:9;11762:7;11758:23;11754:32;11751:52;;;11799:1;11796;11789:12;11751:52;11822:28;11840:9;11822:28;:::i;:::-;11812:38;;11869:37;11902:2;11891:9;11887:18;11869:37;:::i;:::-;11859:47;;11957:2;11946:9;11942:18;11929:32;-1:-1:-1;;;;;11976:6:40;11973:30;11970:50;;;12016:1;12013;12006:12;11970:50;12055:58;12105:7;12096:6;12085:9;12081:22;12055:58;:::i;:::-;11620:553;;;;-1:-1:-1;12132:8:40;-1:-1:-1;;;;11620:553:40:o;12681:655::-;12817:6;12825;12833;12877:9;12868:7;12864:23;12907:3;12903:2;12899:12;12896:32;;;12924:1;12921;12914:12;12896:32;12964:9;12951:23;-1:-1:-1;;;;;12989:6:40;12986:30;12983:50;;;13029:1;13026;13019:12;12983:50;13052:69;13113:7;13104:6;13093:9;13089:22;13052:69;:::i;:::-;13042:79;-1:-1:-1;;13155:2:40;-1:-1:-1;;13137:16:40;;13133:25;13130:45;;;13171:1;13168;13161:12;13130:45;;13209:2;13198:9;13194:18;13184:28;;13262:2;13251:9;13247:18;13234:32;13275:31;13300:5;13275:31;:::i;:::-;13325:5;13315:15;;;12681:655;;;;;:::o;13341:609::-;13581:4;13623:3;13612:9;13608:19;13600:27;;13660:6;13654:13;13643:9;13636:32;-1:-1:-1;;;;;13728:4:40;13720:6;13716:17;13710:24;13706:49;13699:4;13688:9;13684:20;13677:79;13803:4;13795:6;13791:17;13785:24;13818:62;13874:4;13863:9;13859:20;13845:12;2020;;2008:25;;2082:4;2071:16;;;2065:23;2049:14;;2042:47;1946:149;13818:62;-1:-1:-1;2020:12:40;;13939:3;13924:19;;2008:25;2082:4;2071:16;;2065:23;2049:14;;;2042:47;13889:55;1946:149;14178:388;14246:6;14254;14307:2;14295:9;14286:7;14282:23;14278:32;14275:52;;;14323:1;14320;14313:12;14275:52;14362:9;14349:23;14381:31;14406:5;14381:31;:::i;:::-;14431:5;-1:-1:-1;14488:2:40;14473:18;;14460:32;14501:33;14460:32;14501:33;:::i;14571:234::-;14654:6;14707:2;14695:9;14686:7;14682:23;14678:32;14675:52;;;14723:1;14720;14713:12;14675:52;14746:53;14791:7;14780:9;14746:53;:::i;14810:380::-;14889:1;14885:12;;;;14932;;;14953:61;;15007:4;14999:6;14995:17;14985:27;;14953:61;15060:2;15052:6;15049:14;15029:18;15026:38;15023:161;;15106:10;15101:3;15097:20;15094:1;15087:31;15141:4;15138:1;15131:15;15169:4;15166:1;15159:15;15195:251;15265:6;15318:2;15306:9;15297:7;15293:23;15289:32;15286:52;;;15334:1;15331;15324:12;15286:52;15366:9;15360:16;15385:31;15410:5;15385:31;:::i;15451:184::-;15521:6;15574:2;15562:9;15553:7;15549:23;15545:32;15542:52;;;15590:1;15587;15580:12;15542:52;-1:-1:-1;15613:16:40;;15451:184;-1:-1:-1;15451:184:40:o;15640:127::-;15701:10;15696:3;15692:20;15689:1;15682:31;15732:4;15729:1;15722:15;15756:4;15753:1;15746:15;16420:245;16487:6;16540:2;16528:9;16519:7;16515:23;16511:32;16508:52;;;16556:1;16553;16546:12;16508:52;16588:9;16582:16;16607:28;16629:5;16607:28;:::i;16670:253::-;16742:2;16736:9;16784:4;16772:17;;-1:-1:-1;;;;;16804:34:40;;16840:22;;;16801:62;16798:88;;;16866:18;;:::i;:::-;16902:2;16895:22;16670:253;:::o;16928:257::-;17000:4;16994:11;;;17032:17;;-1:-1:-1;;;;;17064:34:40;;17100:22;;;17061:62;17058:88;;;17126:18;;:::i;17190:275::-;17261:2;17255:9;17326:2;17307:13;;-1:-1:-1;;17303:27:40;17291:40;;-1:-1:-1;;;;;17346:34:40;;17382:22;;;17343:62;17340:88;;;17408:18;;:::i;:::-;17444:2;17437:22;17190:275;;-1:-1:-1;17190:275:40:o;17470:186::-;17518:4;-1:-1:-1;;;;;17543:6:40;17540:30;17537:56;;;17573:18;;:::i;:::-;-1:-1:-1;17639:2:40;17618:15;-1:-1:-1;;17614:29:40;17645:4;17610:40;;17470:186::o;17661:2117::-;17853:9;-1:-1:-1;;;;;17928:2:40;17920:6;17917:14;17914:40;;;17934:18;;:::i;:::-;17980:6;17977:1;17973:14;18006:4;18030:28;18054:2;18050;18046:11;18030:28;:::i;:::-;18092:19;;;18162:14;;;;18127:12;;;;18199:14;18188:26;;18185:46;;;18227:1;18224;18217:12;18185:46;18251:5;18265:1480;18281:6;18276:3;18273:15;18265:1480;;;18367:3;18354:17;18403:2;18390:11;18387:19;18384:109;;;18447:1;18476:2;18472;18465:14;18384:109;18516:23;;18584:4;18563:14;18559:23;;;18555:34;18552:124;;;18630:1;18659:2;18655;18648:14;18552:124;18704:22;;:::i;:::-;18755:21;18773:2;18755:21;:::i;:::-;18746:7;18739:38;18815:30;18841:2;18837;18833:11;18815:30;:::i;:::-;18810:2;18801:7;18797:16;18790:56;18869:2;18919;18915;18911:11;18898:25;18950:2;18942:6;18939:14;18936:104;;;18994:1;19023:2;19019;19012:14;18936:104;19063:15;;;;;19120:14;19113:4;19105:13;;19101:34;19091:135;;19178:1;19208:3;19203;19196:16;19091:135;19263:2;19250:16;19292:49;19308:32;19336:3;19308:32;:::i;:::-;19292:49;:::i;:::-;19368:3;19361:5;19354:18;19414:14;19409:2;19403:3;19399:2;19395:12;19391:21;19388:41;19385:134;;;19471:1;19501:3;19496;19489:16;19385:134;19574:3;19569:2;19565;19561:11;19556:2;19549:5;19545:14;19532:46;19624:1;19602:15;;;19598:24;;19591:35;;;;19646:16;;;19639:31;19683:20;;-1:-1:-1;19723:12:40;;;;18298;;18265:1480;;;-1:-1:-1;19767:5:40;17661:2117;-1:-1:-1;;;;;;;17661:2117:40:o;19783:331::-;19888:9;19899;19941:8;19929:10;19926:24;19923:44;;;19963:1;19960;19953:12;19923:44;19992:6;19982:8;19979:20;19976:40;;;20012:1;20009;20002:12;19976:40;-1:-1:-1;;20038:23:40;;;20083:25;;;;;-1:-1:-1;19783:331:40:o;20119:476::-;20310:3;20348:6;20342:13;20364:66;20423:6;20418:3;20411:4;20403:6;20399:17;20364:66;:::i;:::-;20452:16;;20505:6;20497;20452:16;20477:35;20569:1;20531:18;;20558:13;;;-1:-1:-1;20531:18:40;;20119:476;-1:-1:-1;;;20119:476:40:o;20600:266::-;20688:6;20683:3;20676:19;20740:6;20733:5;20726:4;20721:3;20717:14;20704:43;-1:-1:-1;20792:1:40;20767:16;;;20785:4;20763:27;;;20756:38;;;;20848:2;20827:15;;;-1:-1:-1;;20823:29:40;20814:39;;;20810:50;;20600:266::o;20871:244::-;21028:2;21017:9;21010:21;20991:4;21048:61;21105:2;21094:9;21090:18;21082:6;21074;21048:61;:::i;21120:127::-;21181:10;21176:3;21172:20;21169:1;21162:31;21212:4;21209:1;21202:15;21236:4;21233:1;21226:15;21252:331;21351:4;21409:11;21396:25;21503:3;21499:8;21488;21472:14;21468:29;21464:44;21444:18;21440:69;21430:97;;21523:1;21520;21513:12;21430:97;21544:33;;;;;21252:331;-1:-1:-1;;21252:331:40:o;21588:521::-;21665:4;21671:6;21731:11;21718:25;21825:2;21821:7;21810:8;21794:14;21790:29;21786:43;21766:18;21762:68;21752:96;;21844:1;21841;21834:12;21752:96;21871:33;;21923:20;;;-1:-1:-1;;;;;;21955:30:40;;21952:50;;;21998:1;21995;21988:12;21952:50;22031:4;22019:17;;-1:-1:-1;22062:14:40;22058:27;;;22048:38;;22045:58;;;22099:1;22096;22089:12;22114:129;-1:-1:-1;;;;;22192:5:40;22188:30;22181:5;22178:41;22168:69;;22233:1;22230;22223:12;22248:988;22622:10;22595:25;22613:6;22595:25;:::i;:::-;22591:42;22580:9;22573:61;22697:4;22689:6;22685:17;22672:31;22665:4;22654:9;22650:20;22643:61;22554:4;22751;22743:6;22739:17;22726:31;22766:30;22790:5;22766:30;:::i;:::-;-1:-1:-1;;;;;22838:5:40;22834:30;22827:4;22816:9;22812:20;22805:60;;22901:6;22896:2;22885:9;22881:18;22874:34;22945:3;22939;22928:9;22924:19;22917:32;22972:62;23029:3;23018:9;23014:19;23006:6;22998;22972:62;:::i;:::-;-1:-1:-1;;;;;23071:32:40;;23091:3;23050:19;;23043:61;23141:22;;;23135:3;23120:19;;23113:51;23181:49;23145:6;23215;23207;23181:49;:::i;:::-;23173:57;22248:988;-1:-1:-1;;;;;;;;;;22248:988:40:o;23241:647::-;23320:6;23373:2;23361:9;23352:7;23348:23;23344:32;23341:52;;;23389:1;23386;23379:12;23341:52;23422:9;23416:16;-1:-1:-1;;;;;23447:6:40;23444:30;23441:50;;;23487:1;23484;23477:12;23441:50;23510:22;;23563:4;23555:13;;23551:27;-1:-1:-1;23541:55:40;;23592:1;23589;23582:12;23541:55;23621:2;23615:9;23646:48;23662:31;23690:2;23662:31;:::i;23646:48::-;23717:2;23710:5;23703:17;23757:7;23752:2;23747;23743;23739:11;23735:20;23732:33;23729:53;;;23778:1;23775;23768:12;23729:53;23791:67;23855:2;23850;23843:5;23839:14;23834:2;23830;23826:11;23791:67;:::i;24343:245::-;24401:6;24454:2;24442:9;24433:7;24429:23;24425:32;24422:52;;;24470:1;24467;24460:12;24422:52;24509:9;24496:23;24528:30;24552:5;24528:30;:::i;24593:479::-;24860:1;24856;24851:3;24847:11;24843:19;24835:6;24831:32;24820:9;24813:51;24900:6;24895:2;24884:9;24880:18;24873:34;24955:6;24947;24943:19;24938:2;24927:9;24923:18;24916:47;24999:3;24994:2;24983:9;24979:18;24972:31;24794:4;25020:46;25061:3;25050:9;25046:19;25038:6;25020:46;:::i;25695:379::-;25888:2;25877:9;25870:21;25851:4;25914:45;25955:2;25944:9;25940:18;25932:6;25914:45;:::i;:::-;26007:9;25999:6;25995:22;25990:2;25979:9;25975:18;25968:50;26035:33;26061:6;26053;26035:33;:::i;26079:887::-;26298:2;26287:9;26280:21;26356:10;26347:6;26341:13;26337:30;26332:2;26321:9;26317:18;26310:58;26422:4;26414:6;26410:17;26404:24;26399:2;26388:9;26384:18;26377:52;26261:4;26476:2;26468:6;26464:15;26458:22;26517:4;26511:3;26500:9;26496:19;26489:33;26545:52;26592:3;26581:9;26577:19;26563:12;26545:52;:::i;:::-;26531:66;;26646:2;26638:6;26634:15;26628:22;26720:2;26716:7;26704:9;26696:6;26692:22;26688:36;26681:4;26670:9;26666:20;26659:66;26748:41;26782:6;26766:14;26748:41;:::i;:::-;26858:3;26846:16;;;;26840:23;26833:31;26826:39;26820:3;26805:19;;26798:68;-1:-1:-1;;;;;;;;26927:32:40;;;;26920:4;26905:20;;;26898:62;26734:55;26079:887::o;26971:284::-;27041:5;27089:4;27077:9;27072:3;27068:19;27064:30;27061:50;;;27107:1;27104;27097:12;27061:50;27129:22;;:::i;:::-;27120:31;;27180:9;27174:16;27167:5;27160:31;27244:2;27233:9;27229:18;27223:25;27218:2;27211:5;27207:14;27200:49;26971:284;;;;:::o;27260:257::-;27358:6;27411:2;27399:9;27390:7;27386:23;27382:32;27379:52;;;27427:1;27424;27417:12;27379:52;27450:61;27503:7;27492:9;27450:61;:::i;27647:542::-;27748:2;27743:3;27740:11;27737:446;;;27784:1;27808:5;27805:1;27798:16;27852:4;27849:1;27839:18;27922:2;27910:10;27906:19;27903:1;27899:27;27893:4;27889:38;27958:4;27946:10;27943:20;27940:47;;;-1:-1:-1;27981:4:40;27940:47;28036:2;28031:3;28027:12;28024:1;28020:20;28014:4;28010:31;28000:41;;28091:82;28109:2;28102:5;28099:13;28091:82;;;28154:17;;;28135:1;28124:13;28091:82;;;28095:3;;;27647:542;;;:::o;28365:1341::-;28489:3;28483:10;-1:-1:-1;;;;;28508:6:40;28505:30;28502:56;;;28538:18;;:::i;:::-;28567:96;28656:6;28616:38;28648:4;28642:11;28616:38;:::i;:::-;28610:4;28567:96;:::i;:::-;28718:4;;28775:2;28764:14;;28792:1;28787:662;;;;29493:1;29510:6;29507:89;;;-1:-1:-1;29562:19:40;;;29556:26;29507:89;-1:-1:-1;;28322:1:40;28318:11;;;28314:24;28310:29;28300:40;28346:1;28342:11;;;28297:57;29609:81;;28757:943;;28787:662;27594:1;27587:14;;;27631:4;27618:18;;-1:-1:-1;;28823:20:40;;;28940:236;28954:7;28951:1;28948:14;28940:236;;;29043:19;;;29037:26;29022:42;;29135:27;;;;29103:1;29091:14;;;;28970:19;;28940:236;;;28944:3;29204:6;29195:7;29192:19;29189:201;;;29265:19;;;29259:26;-1:-1:-1;;29348:1:40;29344:14;;;29360:3;29340:24;29336:37;29332:42;29317:58;29302:74;;29189:201;-1:-1:-1;;;;;29436:1:40;29420:14;;;29416:22;29403:36;;-1:-1:-1;28365:1341:40:o;29711:1164::-;29927:4;29956:2;29996;29985:9;29981:18;30026:2;30015:9;30008:21;30049:6;30084;30078:13;30115:6;30107;30100:22;30141:2;30131:12;;30174:2;30163:9;30159:18;30152:25;;30236:2;30226:6;30223:1;30219:14;30208:9;30204:30;30200:39;30274:2;30266:6;30262:15;30295:1;30305:541;30319:6;30316:1;30313:13;30305:541;;;30384:22;;;-1:-1:-1;;30380:36:40;30368:49;;30440:13;;30512:9;;30523:10;30508:26;30493:42;;30582:11;;;30576:18;30596:6;30572:31;30555:15;;;30548:56;30643:11;;30637:18;30476:4;30675:15;;;30668:27;;;30718:48;30750:15;;;30637:18;30718:48;:::i;:::-;30824:12;;;;30708:58;-1:-1:-1;;;30789:15:40;;;;30341:1;30334:9;30305:541;;;-1:-1:-1;30863:6:40;;29711:1164;-1:-1:-1;;;;;;;;29711:1164:40:o;30880:346::-;30967:6;31020:2;31008:9;30999:7;30995:23;30991:32;30988:52;;;31036:1;31033;31026:12;30988:52;31062:22;;:::i;:::-;31120:9;31107:23;31100:5;31093:38;31191:2;31180:9;31176:18;31163:32;31158:2;31151:5;31147:14;31140:56;31215:5;31205:15;;;30880:346;;;;:::o;31570:127::-;31631:10;31626:3;31622:20;31619:1;31612:31;31662:4;31659:1;31652:15;31686:4;31683:1;31676:15;31702:217;31742:1;31768;31758:132;;31812:10;31807:3;31803:20;31800:1;31793:31;31847:4;31844:1;31837:15;31875:4;31872:1;31865:15;31758:132;-1:-1:-1;31904:9:40;;31702:217::o;31924:168::-;31997:9;;;32028;;32045:15;;;32039:22;;32025:37;32015:71;;32066:18;;:::i;32097:255::-;32217:19;;32256:2;32248:11;;32245:101;;;-1:-1:-1;;32317:2:40;32313:12;;;32310:1;32306:20;32302:33;32291:45;32097:255;;;;:::o;32357:331::-;-1:-1:-1;;;;;;32477:19:40;;32561:11;;;;32592:1;32584:10;;32581:101;;;32669:2;32663;32656:3;32653:1;32649:11;32646:1;32642:19;32638:28;32634:2;32630:37;32626:46;32617:55;;32581:101;;;32357:331;;;;:::o;32693:568::-;-1:-1:-1;;;;;32958:3:40;32954:28;32945:6;32940:3;32936:16;32932:51;32927:3;32920:64;33044:10;33039:3;33035:20;33026:6;33021:3;33017:16;33013:43;33009:1;33004:3;33000:11;32993:64;33087:6;33082:2;33077:3;33073:12;33066:28;32902:3;33123:6;33117:13;33139:75;33207:6;33202:2;33197:3;33193:12;33186:4;33178:6;33174:17;33139:75;:::i;:::-;33234:16;;;;33252:2;33230:25;;32693:568;-1:-1:-1;;;;;32693:568:40:o;33266:125::-;33331:9;;;33352:10;;;33349:36;;;33365:18;;:::i;33691:532::-;33932:6;33927:3;33920:19;-1:-1:-1;;;;;33995:3:40;33991:28;33982:6;33977:3;33973:16;33969:51;33964:2;33959:3;33955:12;33948:73;34051:6;34046:2;34041:3;34037:12;34030:28;33902:3;34087:6;34081:13;34103:73;34169:6;34164:2;34159:3;34155:12;34150:2;34142:6;34138:15;34103:73;:::i;:::-;34196:16;;;;34214:2;34192:25;;33691:532;-1:-1:-1;;;;;33691:532:40:o;34228:523::-;34330:6;34383:3;34371:9;34362:7;34358:23;34354:33;34351:53;;;34400:1;34397;34390:12;34351:53;34426:22;;:::i;:::-;34477:9;34471:16;34464:5;34457:31;34533:2;34522:9;34518:18;34512:25;34546:32;34570:7;34546:32;:::i;:::-;34605:2;34594:14;;34587:31;34650:70;34712:7;34707:2;34692:18;;34650:70;:::i;:::-;34645:2;34634:14;;34627:94;34638:5;34228:523;-1:-1:-1;;;34228:523:40:o
Swarm Source
ipfs://c97ac570e782e4bd78ea6115c982379c92c33ffa85c7286cb83aa4d58cf7f541
Loading...
Loading
Loading...
Loading
Net Worth in USD
$222,590.59
Net Worth in ETH
112.355868
Token Allocations
ABR
100.00%
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ETH | 100.00% | $0.054791 | 4,062,533.3154 | $222,590.59 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.