Source Code
Latest 25 from a total of 569 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Send | 24542819 | 3 days ago | IN | 0.00002973 ETH | 0.00005728 | ||||
| Send | 24522396 | 6 days ago | IN | 0.00003755 ETH | 0.00003123 | ||||
| Send | 24506337 | 8 days ago | IN | 0.00003755 ETH | 0.00003547 | ||||
| Send | 24495912 | 10 days ago | IN | 0.00003132 ETH | 0.00002301 | ||||
| Send | 24476145 | 12 days ago | IN | 0.0000343 ETH | 0.00000904 | ||||
| Send | 24475852 | 12 days ago | IN | 0.0000343 ETH | 0.00001163 | ||||
| Send | 24474170 | 13 days ago | IN | 0.00003132 ETH | 0.00002524 | ||||
| Send | 24474106 | 13 days ago | IN | 0.00003445 ETH | 0.00057162 | ||||
| Send | 24434542 | 18 days ago | IN | 0.00003175 ETH | 0.00010399 | ||||
| Send | 24434527 | 18 days ago | IN | 0.0000382 ETH | 0.00012213 | ||||
| Send | 24434514 | 18 days ago | IN | 0.0000382 ETH | 0.00013195 | ||||
| Send | 24394949 | 24 days ago | IN | 0.00004015 ETH | 0.00018124 | ||||
| Send | 24394932 | 24 days ago | IN | 0.00004015 ETH | 0.00017773 | ||||
| Send | 24394917 | 24 days ago | IN | 0.00004015 ETH | 0.00017073 | ||||
| Send | 24393689 | 24 days ago | IN | 0.00004015 ETH | 0.00069339 | ||||
| Send | 24382915 | 25 days ago | IN | 0.00026071 ETH | 0.00007103 | ||||
| Send | 24379496 | 26 days ago | IN | 0.00003384 ETH | 0.00008466 | ||||
| Send | 24314125 | 35 days ago | IN | 0.00025961 ETH | 0.00009851 | ||||
| Send | 24303765 | 37 days ago | IN | 0.00002478 ETH | 0.0000384 | ||||
| Send | 24303708 | 37 days ago | IN | 0.00002478 ETH | 0.00003758 | ||||
| Send | 24274748 | 41 days ago | IN | 0.00002118 ETH | 0.00002249 | ||||
| Send | 24270458 | 41 days ago | IN | 0.00002118 ETH | 0.00001959 | ||||
| Send | 24185325 | 53 days ago | IN | 0.00002118 ETH | 0.00001794 | ||||
| Send | 24177113 | 54 days ago | IN | 0.00002118 ETH | 0.00006398 | ||||
| Send | 24127435 | 61 days ago | IN | 0.0000222 ETH | 0.0000207 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| Send | 24542819 | 3 days ago | 0.00002973 ETH | ||||
| Send | 24522396 | 6 days ago | 0.00003755 ETH | ||||
| Send | 24506337 | 8 days ago | 0.00003755 ETH | ||||
| Send | 24495912 | 10 days ago | 0.00003132 ETH | ||||
| Send | 24476145 | 12 days ago | 0.0000343 ETH | ||||
| Send | 24475852 | 12 days ago | 0.0000343 ETH | ||||
| Send | 24474170 | 13 days ago | 0.00003132 ETH | ||||
| Send | 24474106 | 13 days ago | 0.00003445 ETH | ||||
| Send | 24434542 | 18 days ago | 0.00003175 ETH | ||||
| Send | 24434527 | 18 days ago | 0.0000382 ETH | ||||
| Send | 24434514 | 18 days ago | 0.0000382 ETH | ||||
| Send | 24394949 | 24 days ago | 0.00004015 ETH | ||||
| Send | 24394932 | 24 days ago | 0.00004015 ETH | ||||
| Send | 24394917 | 24 days ago | 0.00004015 ETH | ||||
| Send | 24393689 | 24 days ago | 0.00004015 ETH | ||||
| Send | 24382915 | 25 days ago | 0.00026071 ETH | ||||
| Send | 24379496 | 26 days ago | 0.00003384 ETH | ||||
| Send | 24314125 | 35 days ago | 0.00025961 ETH | ||||
| Send | 24303765 | 37 days ago | 0.00002478 ETH | ||||
| Send | 24303708 | 37 days ago | 0.00002478 ETH | ||||
| Send | 24274748 | 41 days ago | 0.00002118 ETH | ||||
| Send | 24270458 | 41 days ago | 0.00002118 ETH | ||||
| Send | 24185325 | 53 days ago | 0.00002118 ETH | ||||
| Send | 24177113 | 54 days ago | 0.00002118 ETH | ||||
| Send | 24127435 | 61 days ago | 0.0000222 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
OFTAdapterImplementation
Compiler Version
v0.8.28+commit.7893614a
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2025-03-16
*/
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 ^0.8.20;
// ../node_modules/@layerzerolabs/oapp-evm/contracts/oapp/interfaces/IOAppMsgInspector.sol
/**
* @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);
}
// ../node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessageLibManager.sol
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);
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessagingChannel.sol
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);
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessagingComposer.sol
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;
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessagingContext.sol
interface IMessagingContext {
function isSendingMessage() external view returns (bool);
function getSendContext() external view returns (uint32 dstEid, address sender);
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@layerzerolabs/lz-evm-protocol-v2/contracts/libs/AddressCast.sol
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));
}
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@layerzerolabs/oapp-evm/contracts/oapp/interfaces/IOAppOptionsType3.sol
/**
* @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);
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@layerzerolabs/oapp-evm/contracts/precrime/interfaces/IPreCrime.sol
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);
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@layerzerolabs/oft-evm/contracts/libs/OFTComposeMsgCodec.sol
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)));
}
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@layerzerolabs/oft-evm/contracts/libs/OFTMsgCodec.sol
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)));
}
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*
* CAUTION: See Security Considerations above.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@openzeppelin/contracts/utils/Address.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error AddressInsufficientBalance(address account);
/**
* @dev There's no code at `target` (it is not a contract).
*/
error AddressEmptyCode(address target);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedInnerCall();
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert AddressInsufficientBalance(address(this));
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert FailedInnerCall();
}
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason or custom error, it is bubbled
* up by this function (like regular Solidity function calls). However, if
* the call reverted with no returned reason, this function reverts with a
* {FailedInnerCall} error.
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert AddressInsufficientBalance(address(this));
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
* was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
* unsuccessful call.
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
// only check if target is a contract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
/**
* @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
* revert reason or with a default {FailedInnerCall} error.
*/
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
/**
* @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
*/
function _revert(bytes memory returndata) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert FailedInnerCall();
}
}
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@openzeppelin/contracts/utils/Context.sol
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
/**
* @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;
}
}
// ../node_modules/@openzeppelin/contracts/access/Ownable.sol
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.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);
}
}
// ../node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessageLib.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);
}
// ../node_modules/@layerzerolabs/oapp-evm/contracts/oapp/libs/OAppOptionsType3.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);
}
}
// ../node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
/**
* @dev An operation with an ERC20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data);
if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;
}
}
// ../node_modules/@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol
struct MessagingParams_0 {
uint32 dstEid;
bytes32 receiver;
bytes message;
bytes options;
bool payInLzToken;
}
struct MessagingReceipt_0 {
bytes32 guid;
uint64 nonce;
MessagingFee_0 fee;
}
struct MessagingFee_0 {
uint256 nativeFee;
uint256 lzTokenFee;
}
struct Origin_0 {
uint32 srcEid;
bytes32 sender;
uint64 nonce;
}
interface ILayerZeroEndpointV2_0 is IMessageLibManager, IMessagingComposer, IMessagingChannel, IMessagingContext {
event PacketSent(bytes encodedPayload, bytes options, address sendLibrary);
event PacketVerified(Origin_0 origin, address receiver, bytes32 payloadHash);
event PacketDelivered(Origin_0 origin, address receiver);
event LzReceiveAlert(
address indexed receiver,
address indexed executor,
Origin_0 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_0 calldata _params, address _sender) external view returns (MessagingFee_0 memory);
function send(
MessagingParams_0 calldata _params,
address _refundAddress
) external payable returns (MessagingReceipt_0 memory);
function verify(Origin_0 calldata _origin, address _receiver, bytes32 _payloadHash) external;
function verifiable(Origin_0 calldata _origin, address _receiver) external view returns (bool);
function initializable(Origin_0 calldata _origin, address _receiver) external view returns (bool);
function lzReceive(
Origin_0 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_0 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;
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol
struct MessagingParams_1 {
uint32 dstEid;
bytes32 receiver;
bytes message;
bytes options;
bool payInLzToken;
}
struct MessagingReceipt_1 {
bytes32 guid;
uint64 nonce;
MessagingFee_1 fee;
}
struct MessagingFee_1 {
uint256 nativeFee;
uint256 lzTokenFee;
}
struct Origin_1 {
uint32 srcEid;
bytes32 sender;
uint64 nonce;
}
interface ILayerZeroEndpointV2_1 is IMessageLibManager, IMessagingComposer, IMessagingChannel, IMessagingContext {
event PacketSent(bytes encodedPayload, bytes options, address sendLibrary);
event PacketVerified(Origin_1 origin, address receiver, bytes32 payloadHash);
event PacketDelivered(Origin_1 origin, address receiver);
event LzReceiveAlert(
address indexed receiver,
address indexed executor,
Origin_1 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_1 calldata _params, address _sender) external view returns (MessagingFee_1 memory);
function send(
MessagingParams_1 calldata _params,
address _refundAddress
) external payable returns (MessagingReceipt_1 memory);
function verify(Origin_1 calldata _origin, address _receiver, bytes32 _payloadHash) external;
function verifiable(Origin_1 calldata _origin, address _receiver) external view returns (bool);
function initializable(Origin_1 calldata _origin, address _receiver) external view returns (bool);
function lzReceive(
Origin_1 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_1 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;
}
// ../node_modules/@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroReceiver.sol
interface ILayerZeroReceiver {
function allowInitializePath(Origin_0 calldata _origin) external view returns (bool);
function nextNonce(uint32 _eid, bytes32 _sender) external view returns (uint64);
function lzReceive(
Origin_0 calldata _origin,
bytes32 _guid,
bytes calldata _message,
address _executor,
bytes calldata _extraData
) external payable;
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@layerzerolabs/oapp-evm/contracts/oapp/interfaces/IOAppCore.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_0 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;
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@layerzerolabs/oapp-evm/contracts/oapp/interfaces/IOAppReceiver.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_0 calldata _origin,
bytes calldata _message,
address _sender
) external view returns (bool isSender);
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ISendLib.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_1 memory, bytes memory encodedPacket);
function quote(
Packet calldata _packet,
bytes calldata _options,
bool _payInLzToken
) external view returns (MessagingFee_1 memory);
function setTreasury(address _treasury) external;
function withdrawFee(address _to, uint256 _amount) external;
function withdrawLzTokenFee(address _lzToken, address _to, uint256 _amount) external;
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@layerzerolabs/oapp-evm/contracts/oapp/OAppCore.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_0 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_0(_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);
}
}
// ../node_modules/@layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/libs/PacketV1Codec.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));
}
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@layerzerolabs/oapp-evm/contracts/precrime/libs/Packet.sol
/**
* @title InboundPacket
* @dev Structure representing an inbound packet received by the contract.
*/
struct InboundPacket {
Origin_0 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_0(_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];
}
}
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@layerzerolabs/oapp-evm/contracts/oapp/OAppReceiver.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_0 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_0 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_0 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_0 calldata _origin,
bytes32 _guid,
bytes calldata _message,
address _executor,
bytes calldata _extraData
) internal virtual;
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@layerzerolabs/oapp-evm/contracts/precrime/interfaces/IOAppPreCrimeSimulator.sol
// @dev Import the Origin so it's exposed to OAppPreCrimeSimulator implementers.
// solhint-disable-next-line no-unused-import
/**
* @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);
}
// ../node_modules/@layerzerolabs/oapp-evm/contracts/oapp/OAppSender.sol
/**
* @title OAppSender
* @dev Abstract contract implementing the OAppSender functionality for sending messages to a LayerZero endpoint.
*/
abstract contract OAppSender_0 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_0 memory fee) {
return
endpoint.quote(
MessagingParams_0(_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_0 memory _fee,
address _refundAddress
) internal virtual returns (MessagingReceipt_0 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_0(_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);
}
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@layerzerolabs/oapp-evm/contracts/oapp/OAppSender.sol
/**
* @title OAppSender
* @dev Abstract contract implementing the OAppSender functionality for sending messages to a LayerZero endpoint.
*/
abstract contract OAppSender_1 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_0 memory fee) {
return
endpoint.quote(
MessagingParams_0(_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_0 memory _fee,
address _refundAddress
) internal virtual returns (MessagingReceipt_0 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_0(_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);
}
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@layerzerolabs/oft-evm/contracts/interfaces/IOFT.sol
/**
* @dev Struct representing token parameters for the OFT send() operation.
*/
struct SendParam {
uint32 dstEid; // Destination endpoint ID.
bytes32 to; // Recipient address.
uint256 amountLD; // Amount to send in local decimals.
uint256 minAmountLD; // Minimum amount to send in local decimals.
bytes extraOptions; // Additional options supplied by the caller to be used in the LayerZero message.
bytes composeMsg; // The composed message for the send() operation.
bytes oftCmd; // The OFT command to be executed, unused in default OFT implementations.
}
/**
* @dev Struct representing OFT limit information.
* @dev These amounts can change dynamically and are up the specific oft implementation.
*/
struct OFTLimit {
uint256 minAmountLD; // Minimum amount in local decimals that can be sent to the recipient.
uint256 maxAmountLD; // Maximum amount in local decimals that can be sent to the recipient.
}
/**
* @dev Struct representing OFT receipt information.
*/
struct OFTReceipt {
uint256 amountSentLD; // Amount of tokens ACTUALLY debited from the sender in local decimals.
// @dev In non-default implementations, the amountReceivedLD COULD differ from this value.
uint256 amountReceivedLD; // Amount of tokens to be received on the remote side.
}
/**
* @dev Struct representing OFT fee details.
* @dev Future proof mechanism to provide a standardized way to communicate fees to things like a UI.
*/
struct OFTFeeDetail {
int256 feeAmountLD; // Amount of the fee in local decimals.
string description; // Description of the fee.
}
/**
* @title IOFT
* @dev Interface for the OftChain (OFT) token.
* @dev Does not inherit ERC20 to accommodate usage by OFTAdapter as well.
* @dev This specific interface ID is '0x02e49c2c'.
*/
interface IOFT {
// Custom error messages
error InvalidLocalDecimals();
error SlippageExceeded(uint256 amountLD, uint256 minAmountLD);
// Events
event OFTSent(
bytes32 indexed guid, // GUID of the OFT message.
uint32 dstEid, // Destination Endpoint ID.
address indexed fromAddress, // Address of the sender on the src chain.
uint256 amountSentLD, // Amount of tokens sent in local decimals.
uint256 amountReceivedLD // Amount of tokens received in local decimals.
);
event OFTReceived(
bytes32 indexed guid, // GUID of the OFT message.
uint32 srcEid, // Source Endpoint ID.
address indexed toAddress, // Address of the recipient on the dst chain.
uint256 amountReceivedLD // Amount of tokens received in local decimals.
);
/**
* @notice Retrieves interfaceID and the version of the OFT.
* @return interfaceId The interface ID.
* @return version The version.
*
* @dev interfaceId: This specific interface ID is '0x02e49c2c'.
* @dev version: Indicates a cross-chain compatible msg encoding with other OFTs.
* @dev If a new feature is added to the OFT cross-chain msg encoding, the version will be incremented.
* ie. localOFT version(x,1) CAN send messages to remoteOFT version(x,1)
*/
function oftVersion() external view returns (bytes4 interfaceId, uint64 version);
/**
* @notice Retrieves the address of the token associated with the OFT.
* @return token The address of the ERC20 token implementation.
*/
function token() external view returns (address);
/**
* @notice Indicates whether the OFT contract requires approval of the 'token()' to send.
* @return requiresApproval Needs approval of the underlying token implementation.
*
* @dev Allows things like wallet implementers to determine integration requirements,
* without understanding the underlying token implementation.
*/
function approvalRequired() external view returns (bool);
/**
* @notice Retrieves the shared decimals of the OFT.
* @return sharedDecimals The shared decimals of the OFT.
*/
function sharedDecimals() external view returns (uint8);
/**
* @notice Provides a quote for OFT-related operations.
* @param _sendParam The parameters for the send operation.
* @return limit The OFT limit information.
* @return oftFeeDetails The details of OFT fees.
* @return receipt The OFT receipt information.
*/
function quoteOFT(
SendParam calldata _sendParam
) external view returns (OFTLimit memory, OFTFeeDetail[] memory oftFeeDetails, OFTReceipt memory);
/**
* @notice Provides a quote for the send() operation.
* @param _sendParam The parameters for the send() operation.
* @param _payInLzToken Flag indicating whether the caller is paying in the LZ token.
* @return fee The calculated LayerZero messaging fee from the send() operation.
*
* @dev MessagingFee: LayerZero msg fee
* - nativeFee: The native fee.
* - lzTokenFee: The lzToken fee.
*/
function quoteSend(SendParam calldata _sendParam, bool _payInLzToken) external view returns (MessagingFee_0 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_0 calldata _fee,
address _refundAddress
) external payable returns (MessagingReceipt_0 memory, OFTReceipt memory);
}
// ../node_modules/@layerzerolabs/oapp-evm/contracts/precrime/OAppPreCrimeSimulator.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_0 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_0 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);
}
// ../node_modules/@layerzerolabs/oapp-evm/contracts/oapp/OApp.sol
// @dev Import the 'MessagingFee' and 'MessagingReceipt' so it's exposed to OApp implementers
// solhint-disable-next-line no-unused-import
// @dev Import the 'Origin' so it's exposed to OApp implementers
// solhint-disable-next-line no-unused-import
/**
* @title OApp
* @dev Abstract contract serving as the base for OApp implementation, combining OAppSender and OAppReceiver functionality.
*/
abstract contract OApp is OAppSender_0, 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_0, OAppReceiver)
returns (uint64 senderVersion, uint64 receiverVersion)
{
return (SENDER_VERSION, RECEIVER_VERSION);
}
}
// /Users/benhaslam/ambient/oft_tools/node_modules/@layerzerolabs/oft-evm/contracts/OFTCore.sol
/**
* @title OFTCore
* @dev Abstract contract for the OftChain (OFT) token.
*/
abstract contract OFTCore is IOFT, OApp, OAppPreCrimeSimulator, OAppOptionsType3 {
using OFTMsgCodec for bytes;
using OFTMsgCodec for bytes32;
// @notice Provides a conversion rate when swapping between denominations of SD and LD
// - shareDecimals == SD == shared Decimals
// - localDecimals == LD == local decimals
// @dev Considers that tokens have different decimal amounts on various chains.
// @dev eg.
// For a token
// - locally with 4 decimals --> 1.2345 => uint(12345)
// - remotely with 2 decimals --> 1.23 => uint(123)
// - The conversion rate would be 10 ** (4 - 2) = 100
// @dev If you want to send 1.2345 -> (uint 12345), you CANNOT represent that value on the remote,
// you can only display 1.23 -> uint(123).
// @dev To preserve the dust that would otherwise be lost on that conversion,
// we need to unify a denomination that can be represented on ALL chains inside of the OFT mesh
uint256 public immutable decimalConversionRate;
// @notice Msg types that are used to identify the various OFT operations.
// @dev This can be extended in child contracts for non-default oft operations
// @dev These values are used in things like combineOptions() in OAppOptionsType3.sol.
uint16 public constant SEND = 1;
uint16 public constant SEND_AND_CALL = 2;
// Address of an optional contract to inspect both 'message' and 'options'
address public msgInspector;
event MsgInspectorSet(address inspector);
/**
* @dev Constructor.
* @param _localDecimals The decimals of the token on the local chain (this chain).
* @param _endpoint The address of the LayerZero endpoint.
* @param _delegate The delegate capable of making OApp configurations inside of the endpoint.
*/
constructor(uint8 _localDecimals, address _endpoint, address _delegate) OApp(_endpoint, _delegate) {
if (_localDecimals < sharedDecimals()) revert InvalidLocalDecimals();
decimalConversionRate = 10 ** (_localDecimals - sharedDecimals());
}
/**
* @notice Retrieves interfaceID and the version of the OFT.
* @return interfaceId The interface ID.
* @return version The version.
*
* @dev interfaceId: This specific interface ID is '0x02e49c2c'.
* @dev version: Indicates a cross-chain compatible msg encoding with other OFTs.
* @dev If a new feature is added to the OFT cross-chain msg encoding, the version will be incremented.
* ie. localOFT version(x,1) CAN send messages to remoteOFT version(x,1)
*/
function oftVersion() external pure virtual returns (bytes4 interfaceId, uint64 version) {
return (type(IOFT).interfaceId, 1);
}
/**
* @dev Retrieves the shared decimals of the OFT.
* @return The shared decimals of the OFT.
*
* @dev Sets an implicit cap on the amount of tokens, over uint64.max() will need some sort of outbound cap / totalSupply cap
* Lowest common decimal denominator between chains.
* Defaults to 6 decimal places to provide up to 18,446,744,073,709.551615 units (max uint64).
* For tokens exceeding this totalSupply(), they will need to override the sharedDecimals function with something smaller.
* ie. 4 sharedDecimals would be 1,844,674,407,370,955.1615
*/
function sharedDecimals() public view virtual returns (uint8) {
return 6;
}
/**
* @dev Sets the message inspector address for the OFT.
* @param _msgInspector The address of the message inspector.
*
* @dev This is an optional contract that can be used to inspect both 'message' and 'options'.
* @dev Set it to address(0) to disable it, or set it to a contract address to enable it.
*/
function setMsgInspector(address _msgInspector) public virtual onlyOwner {
msgInspector = _msgInspector;
emit MsgInspectorSet(_msgInspector);
}
/**
* @notice Provides a quote for OFT-related operations.
* @param _sendParam The parameters for the send operation.
* @return oftLimit The OFT limit information.
* @return oftFeeDetails The details of OFT fees.
* @return oftReceipt The OFT receipt information.
*/
function quoteOFT(
SendParam calldata _sendParam
)
external
view
virtual
returns (OFTLimit memory oftLimit, OFTFeeDetail[] memory oftFeeDetails, OFTReceipt memory oftReceipt)
{
uint256 minAmountLD = 0; // Unused in the default implementation.
uint256 maxAmountLD = type(uint64).max; // Unused in the default implementation.
oftLimit = OFTLimit(minAmountLD, maxAmountLD);
// Unused in the default implementation; reserved for future complex fee details.
oftFeeDetails = new OFTFeeDetail[](0);
// @dev This is the same as the send() operation, but without the actual send.
// - amountSentLD is the amount in local decimals that would be sent from the sender.
// - amountReceivedLD is the amount in local decimals that will be credited to the recipient on the remote OFT instance.
// @dev The amountSentLD MIGHT not equal the amount the user actually receives. HOWEVER, the default does.
(uint256 amountSentLD, uint256 amountReceivedLD) = _debitView(
_sendParam.amountLD,
_sendParam.minAmountLD,
_sendParam.dstEid
);
oftReceipt = OFTReceipt(amountSentLD, amountReceivedLD);
}
/**
* @notice Provides a quote for the send() operation.
* @param _sendParam The parameters for the send() operation.
* @param _payInLzToken Flag indicating whether the caller is paying in the LZ token.
* @return msgFee The calculated LayerZero messaging fee from the send() operation.
*
* @dev MessagingFee: LayerZero msg fee
* - nativeFee: The native fee.
* - lzTokenFee: The lzToken fee.
*/
function quoteSend(
SendParam calldata _sendParam,
bool _payInLzToken
) external view virtual returns (MessagingFee_0 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_0 calldata _fee,
address _refundAddress
) external payable virtual returns (MessagingReceipt_0 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_0 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_0 calldata _origin,
bytes32 _guid,
bytes calldata _message,
address _executor,
bytes calldata _extraData
) internal virtual override {
_lzReceive(_origin, _guid, _message, _executor, _extraData);
}
/**
* @dev Check if the peer is considered 'trusted' by the OApp.
* @param _eid The endpoint ID to check.
* @param _peer The peer to check.
* @return Whether the peer passed is considered 'trusted' by the OApp.
*
* @dev Enables OAppPreCrimeSimulator to check whether a potential Inbound Packet is from a trusted source.
*/
function isPeer(uint32 _eid, bytes32 _peer) public view virtual override returns (bool) {
return peers[_eid] == _peer;
}
/**
* @dev Internal function to remove dust from the given local decimal amount.
* @param _amountLD The amount in local decimals.
* @return amountLD The amount after removing dust.
*
* @dev Prevents the loss of dust when moving amounts between chains with different decimals.
* @dev eg. uint(123) with a conversion rate of 100 becomes uint(100).
*/
function _removeDust(uint256 _amountLD) internal view virtual returns (uint256 amountLD) {
return (_amountLD / decimalConversionRate) * decimalConversionRate;
}
/**
* @dev Internal function to convert an amount from shared decimals into local decimals.
* @param _amountSD The amount in shared decimals.
* @return amountLD The amount in local decimals.
*/
function _toLD(uint64 _amountSD) internal view virtual returns (uint256 amountLD) {
return _amountSD * decimalConversionRate;
}
/**
* @dev Internal function to convert an amount from local decimals into shared decimals.
* @param _amountLD The amount in local decimals.
* @return amountSD The amount in shared decimals.
*/
function _toSD(uint256 _amountLD) internal view virtual returns (uint64 amountSD) {
return uint64(_amountLD / decimalConversionRate);
}
/**
* @dev Internal function to mock the amount mutation from a OFT debit() operation.
* @param _amountLD The amount to send in local decimals.
* @param _minAmountLD The minimum amount to send in local decimals.
* @dev _dstEid The destination endpoint ID.
* @return amountSentLD The amount sent, in local decimals.
* @return amountReceivedLD The amount to be received on the remote chain, in local decimals.
*
* @dev This is where things like fees would be calculated and deducted from the amount to be received on the remote.
*/
function _debitView(
uint256 _amountLD,
uint256 _minAmountLD,
uint32 /*_dstEid*/
) internal view virtual returns (uint256 amountSentLD, uint256 amountReceivedLD) {
// @dev Remove the dust so nothing is lost on the conversion between chains with different decimals for the token.
amountSentLD = _removeDust(_amountLD);
// @dev The amount to send is the same as amount received in the default implementation.
amountReceivedLD = amountSentLD;
// @dev Check for slippage.
if (amountReceivedLD < _minAmountLD) {
revert SlippageExceeded(amountReceivedLD, _minAmountLD);
}
}
/**
* @dev Internal function to perform a debit operation.
* @param _from The address to debit.
* @param _amountLD The amount to send in local decimals.
* @param _minAmountLD The minimum amount to send in local decimals.
* @param _dstEid The destination endpoint ID.
* @return amountSentLD The amount sent in local decimals.
* @return amountReceivedLD The amount received in local decimals on the remote.
*
* @dev Defined here but are intended to be overriden depending on the OFT implementation.
* @dev Depending on OFT implementation the _amountLD could differ from the amountReceivedLD.
*/
function _debit(
address _from,
uint256 _amountLD,
uint256 _minAmountLD,
uint32 _dstEid
) internal virtual returns (uint256 amountSentLD, uint256 amountReceivedLD);
/**
* @dev Internal function to perform a credit operation.
* @param _to The address to credit.
* @param _amountLD The amount to credit in local decimals.
* @param _srcEid The source endpoint ID.
* @return amountReceivedLD The amount ACTUALLY received in local decimals.
*
* @dev Defined here but are intended to be overriden depending on the OFT implementation.
* @dev Depending on OFT implementation the _amountLD could differ from the amountReceivedLD.
*/
function _credit(
address _to,
uint256 _amountLD,
uint32 _srcEid
) internal virtual returns (uint256 amountReceivedLD);
}
// ../node_modules/@layerzerolabs/oft-evm/contracts/OFTAdapter.sol
/**
* @title OFTAdapter Contract
* @dev OFTAdapter is a contract that adapts an ERC-20 token to the OFT functionality.
*
* @dev For existing ERC20 tokens, this can be used to convert the token to crosschain compatibility.
* @dev WARNING: ONLY 1 of these should exist for a given global mesh,
* unless you make a NON-default implementation of OFT and needs to be done very carefully.
* @dev WARNING: The default OFTAdapter implementation assumes LOSSLESS transfers, ie. 1 token in, 1 token out.
* IF the 'innerToken' applies something like a transfer fee, the default will NOT work...
* a pre/post balance check will need to be done to calculate the amountSentLD/amountReceivedLD.
*/
abstract contract OFTAdapter is OFTCore {
using SafeERC20 for IERC20;
IERC20 internal immutable innerToken;
/**
* @dev Constructor for the OFTAdapter contract.
* @param _token The address of the ERC-20 token to be adapted.
* @param _lzEndpoint The LayerZero endpoint address.
* @param _delegate The delegate capable of making OApp configurations inside of the endpoint.
*/
constructor(
address _token,
address _lzEndpoint,
address _delegate
) OFTCore(IERC20Metadata(_token).decimals(), _lzEndpoint, _delegate) {
innerToken = IERC20(_token);
}
/**
* @dev Retrieves the address of the underlying ERC20 implementation.
* @return The address of the adapted ERC-20 token.
*
* @dev In the case of OFTAdapter, address(this) and erc20 are NOT the same contract.
*/
function token() public view returns (address) {
return address(innerToken);
}
/**
* @notice Indicates whether the OFT contract requires approval of the 'token()' to send.
* @return requiresApproval Needs approval of the underlying token implementation.
*
* @dev In the case of default OFTAdapter, approval is required.
* @dev In non-default OFTAdapter contracts with something like mint and burn privileges, it would NOT need approval.
*/
function approvalRequired() external pure virtual returns (bool) {
return true;
}
/**
* @dev Locks tokens from the sender's specified balance in this contract.
* @param _from The address to debit from.
* @param _amountLD The amount of tokens to send in local decimals.
* @param _minAmountLD The minimum amount to send in local decimals.
* @param _dstEid The destination chain ID.
* @return amountSentLD The amount sent in local decimals.
* @return amountReceivedLD The amount received in local decimals on the remote.
*
* @dev msg.sender will need to approve this _amountLD of tokens to be locked inside of the contract.
* @dev WARNING: The default OFTAdapter implementation assumes LOSSLESS transfers, ie. 1 token in, 1 token out.
* IF the 'innerToken' applies something like a transfer fee, the default will NOT work...
* a pre/post balance check will need to be done to calculate the amountReceivedLD.
*/
function _debit(
address _from,
uint256 _amountLD,
uint256 _minAmountLD,
uint32 _dstEid
) internal virtual override returns (uint256 amountSentLD, uint256 amountReceivedLD) {
(amountSentLD, amountReceivedLD) = _debitView(_amountLD, _minAmountLD, _dstEid);
// @dev Lock tokens by moving them into this contract from the caller.
innerToken.safeTransferFrom(_from, address(this), amountSentLD);
}
/**
* @dev Credits tokens to the specified address.
* @param _to The address to credit the tokens to.
* @param _amountLD The amount of tokens to credit in local decimals.
* @dev _srcEid The source chain ID.
* @return amountReceivedLD The amount of tokens ACTUALLY received in local decimals.
*
* @dev WARNING: The default OFTAdapter implementation assumes LOSSLESS transfers, ie. 1 token in, 1 token out.
* IF the 'innerToken' applies something like a transfer fee, the default will NOT work...
* a pre/post balance check will need to be done to calculate the amountReceivedLD.
*/
function _credit(
address _to,
uint256 _amountLD,
uint32 /*_srcEid*/
) internal virtual override returns (uint256 amountReceivedLD) {
// @dev Unlock the tokens and transfer to the recipient.
innerToken.safeTransfer(_to, _amountLD);
// @dev In the case of NON-default OFTAdapter, the amountLD MIGHT not be == amountReceivedLD.
return _amountLD;
}
}
// src/OFTAdapterImplementation.sol
contract OFTAdapterImplementation is OFTAdapter {
/**
* @dev Constructor for the OFTAdapter contract.
* @param _token The token contract to adapt for cross-chain functionality
* @param _lzEndpoint The LayerZero endpoint address
* @param _delegate The delegate capable of making OApp configurations inside of the endpoint
*/
constructor(
address _token,
address _lzEndpoint,
address _delegate
) OFTAdapter(_token, _lzEndpoint, _delegate) Ownable(_delegate) {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_lzEndpoint","type":"address"},{"internalType":"address","name":"_delegate","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"InvalidDelegate","type":"error"},{"inputs":[],"name":"InvalidEndpointCall","type":"error"},{"inputs":[],"name":"InvalidLocalDecimals","type":"error"},{"inputs":[{"internalType":"bytes","name":"options","type":"bytes"}],"name":"InvalidOptions","type":"error"},{"inputs":[],"name":"LzTokenUnavailable","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"NoPeer","type":"error"},{"inputs":[{"internalType":"uint256","name":"msgValue","type":"uint256"}],"name":"NotEnoughNative","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"OnlyEndpoint","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"}],"name":"OnlyPeer","type":"error"},{"inputs":[],"name":"OnlySelf","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[{"internalType":"bytes","name":"result","type":"bytes"}],"name":"SimulationResult","type":"error"},{"inputs":[{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"uint256","name":"minAmountLD","type":"uint256"}],"name":"SlippageExceeded","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint16","name":"msgType","type":"uint16"},{"internalType":"bytes","name":"options","type":"bytes"}],"indexed":false,"internalType":"struct EnforcedOptionParam[]","name":"_enforcedOptions","type":"tuple[]"}],"name":"EnforcedOptionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"inspector","type":"address"}],"name":"MsgInspectorSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"guid","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"srcEid","type":"uint32"},{"indexed":true,"internalType":"address","name":"toAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountReceivedLD","type":"uint256"}],"name":"OFTReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"guid","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"dstEid","type":"uint32"},{"indexed":true,"internalType":"address","name":"fromAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountSentLD","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountReceivedLD","type":"uint256"}],"name":"OFTSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"eid","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"peer","type":"bytes32"}],"name":"PeerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"preCrimeAddress","type":"address"}],"name":"PreCrimeSet","type":"event"},{"inputs":[],"name":"SEND","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SEND_AND_CALL","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin_0","name":"origin","type":"tuple"}],"name":"allowInitializePath","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"approvalRequired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"uint16","name":"_msgType","type":"uint16"},{"internalType":"bytes","name":"_extraOptions","type":"bytes"}],"name":"combineOptions","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimalConversionRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endpoint","outputs":[{"internalType":"contract ILayerZeroEndpointV2_0","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_0","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_0","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_0","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_0","name":"_origin","type":"tuple"},{"internalType":"bytes32","name":"_guid","type":"bytes32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"address","name":"_executor","type":"address"},{"internalType":"bytes","name":"_extraData","type":"bytes"}],"name":"lzReceiveSimulate","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"msgInspector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"nextNonce","outputs":[{"internalType":"uint64","name":"nonce","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oApp","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oAppVersion","outputs":[{"internalType":"uint64","name":"senderVersion","type":"uint64"},{"internalType":"uint64","name":"receiverVersion","type":"uint64"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"oftVersion","outputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"},{"internalType":"uint64","name":"version","type":"uint64"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"peers","outputs":[{"internalType":"bytes32","name":"peer","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"preCrime","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"bytes32","name":"to","type":"bytes32"},{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"uint256","name":"minAmountLD","type":"uint256"},{"internalType":"bytes","name":"extraOptions","type":"bytes"},{"internalType":"bytes","name":"composeMsg","type":"bytes"},{"internalType":"bytes","name":"oftCmd","type":"bytes"}],"internalType":"struct SendParam","name":"_sendParam","type":"tuple"}],"name":"quoteOFT","outputs":[{"components":[{"internalType":"uint256","name":"minAmountLD","type":"uint256"},{"internalType":"uint256","name":"maxAmountLD","type":"uint256"}],"internalType":"struct OFTLimit","name":"oftLimit","type":"tuple"},{"components":[{"internalType":"int256","name":"feeAmountLD","type":"int256"},{"internalType":"string","name":"description","type":"string"}],"internalType":"struct OFTFeeDetail[]","name":"oftFeeDetails","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"amountSentLD","type":"uint256"},{"internalType":"uint256","name":"amountReceivedLD","type":"uint256"}],"internalType":"struct OFTReceipt","name":"oftReceipt","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"bytes32","name":"to","type":"bytes32"},{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"uint256","name":"minAmountLD","type":"uint256"},{"internalType":"bytes","name":"extraOptions","type":"bytes"},{"internalType":"bytes","name":"composeMsg","type":"bytes"},{"internalType":"bytes","name":"oftCmd","type":"bytes"}],"internalType":"struct SendParam","name":"_sendParam","type":"tuple"},{"internalType":"bool","name":"_payInLzToken","type":"bool"}],"name":"quoteSend","outputs":[{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee_0","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_0","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_0","name":"fee","type":"tuple"}],"internalType":"struct MessagingReceipt_0","name":"msgReceipt","type":"tuple"},{"components":[{"internalType":"uint256","name":"amountSentLD","type":"uint256"},{"internalType":"uint256","name":"amountReceivedLD","type":"uint256"}],"internalType":"struct OFTReceipt","name":"oftReceipt","type":"tuple"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_delegate","type":"address"}],"name":"setDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint16","name":"msgType","type":"uint16"},{"internalType":"bytes","name":"options","type":"bytes"}],"internalType":"struct EnforcedOptionParam[]","name":"_enforcedOptions","type":"tuple[]"}],"name":"setEnforcedOptions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_msgInspector","type":"address"}],"name":"setMsgInspector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"bytes32","name":"_peer","type":"bytes32"}],"name":"setPeer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_preCrime","type":"address"}],"name":"setPreCrime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sharedDecimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60e060405234801561001057600080fd5b50604051612f9d380380612f9d83398101604081905261002f9161023d565b828282826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610070573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100949190610280565b8282818181818a6001600160a01b0381166100c957604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b6100d2816101cc565b506001600160a01b03808316608052811661010057604051632d618d8160e21b815260040160405180910390fd5b60805160405163ca5eb5e160e01b81526001600160a01b0383811660048301529091169063ca5eb5e190602401600060405180830381600087803b15801561014757600080fd5b505af115801561015b573d6000803e3d6000fd5b505050505050505061017161021c60201b60201c565b60ff168360ff161015610197576040516301e9714b60e41b815260040160405180910390fd5b6101a26006846102c0565b6101ad90600a6103c6565b60a0525050506001600160a01b0390921660c052506103d59350505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600690565b80516001600160a01b038116811461023857600080fd5b919050565b60008060006060848603121561025257600080fd5b61025b84610221565b925061026960208501610221565b915061027760408501610221565b90509250925092565b60006020828403121561029257600080fd5b815160ff811681146102a357600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b60ff82811682821603908111156102d9576102d96102aa565b92915050565b6001815b600184111561031a578085048111156102fe576102fe6102aa565b600184161561030c57908102905b60019390931c9280026102e3565b935093915050565b600082610331575060016102d9565b8161033e575060006102d9565b8160018114610354576002811461035e5761037a565b60019150506102d9565b60ff84111561036f5761036f6102aa565b50506001821b6102d9565b5060208310610133831016604e8410600b841016171561039d575081810a6102d9565b6103aa60001984846102df565b80600019048211156103be576103be6102aa565b029392505050565b60006102a360ff841683610322565b60805160a05160c051612b4561045860003960008181610669015281816115be01526117b70152600081816104e2015281816116fe0152818161177a015261186a0152600081816103e40152818161078001528181610e56015281816110c30152818161135001528181611622015281816119a20152611a5b0152612b456000f3fe6080604052600436106101ee5760003560e01c806382413eac1161010d578063bc70b354116100a0578063d045a0dc1161006f578063d045a0dc14610607578063d42438851461061a578063f2fde38b1461063a578063fc0c546a1461065a578063ff7bd03d1461068d57600080fd5b8063bc70b35414610593578063bd815db0146105b3578063c7c7f5b3146105c6578063ca5eb5e1146105e757600080fd5b80639f68b964116100dc5780639f68b96414610512578063b731ea0a14610526578063b98bd07014610546578063bb0b6a531461056657600080fd5b806382413eac14610476578063857749b0146104965780638da5cb5b146104b2578063963efcaa146104d057600080fd5b80633b6f743b116101855780635e280f11116101545780635e280f11146103d25780636fc1b31e14610406578063715018a6146104265780637d25a05e1461043b57600080fd5b80633b6f743b1461031e57806352ae28791461034b5780635535d4611461035e5780635a0dfe4d1461038b57600080fd5b8063156a0d0f116101c1578063156a0d0f146102a057806317442b70146102c75780631f5e1334146102e95780633400288b146102fe57600080fd5b80630d35b415146101f3578063111ecdad1461022b57806313137d6514610263578063134d4f2514610278575b600080fd5b3480156101ff57600080fd5b5061021361020e366004611c7f565b6106ad565b60405161022293929190611d03565b60405180910390f35b34801561023757600080fd5b5060045461024b906001600160a01b031681565b6040516001600160a01b039091168152602001610222565b610276610271366004611e0f565b61077e565b005b34801561028457600080fd5b5061028d600281565b60405161ffff9091168152602001610222565b3480156102ac57600080fd5b506040805162b9270b60e21b81526001602082015201610222565b3480156102d357600080fd5b5060408051600181526002602082015201610222565b3480156102f557600080fd5b5061028d600181565b34801561030a57600080fd5b50610276610319366004611ec9565b61083e565b34801561032a57600080fd5b5061033e610339366004611f01565b610854565b6040516102229190611f52565b34801561035757600080fd5b503061024b565b34801561036a57600080fd5b5061037e610379366004611f7b565b6108bd565b6040516102229190611fae565b34801561039757600080fd5b506103c26103a6366004611ec9565b63ffffffff919091166000908152600160205260409020541490565b6040519015158152602001610222565b3480156103de57600080fd5b5061024b7f000000000000000000000000000000000000000000000000000000000000000081565b34801561041257600080fd5b50610276610421366004611fc1565b610962565b34801561043257600080fd5b506102766109bf565b34801561044757600080fd5b5061045e610456366004611ec9565b600092915050565b6040516001600160401b039091168152602001610222565b34801561048257600080fd5b506103c2610491366004611fde565b6109d3565b3480156104a257600080fd5b5060405160068152602001610222565b3480156104be57600080fd5b506000546001600160a01b031661024b565b3480156104dc57600080fd5b506105047f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610222565b34801561051e57600080fd5b5060016103c2565b34801561053257600080fd5b5060025461024b906001600160a01b031681565b34801561055257600080fd5b50610276610561366004612088565b6109e8565b34801561057257600080fd5b506105046105813660046120c9565b60016020526000908152604090205481565b34801561059f57600080fd5b5061037e6105ae3660046120e4565b610a02565b6102766105c1366004612088565b610baa565b6105d96105d4366004612144565b610d34565b6040516102229291906121b1565b3480156105f357600080fd5b50610276610602366004611fc1565b610e2f565b610276610615366004611e0f565b610eb5565b34801561062657600080fd5b50610276610635366004611fc1565b610ee4565b34801561064657600080fd5b50610276610655366004611fc1565b610f3a565b34801561066657600080fd5b507f000000000000000000000000000000000000000000000000000000000000000061024b565b34801561069957600080fd5b506103c26106a8366004612203565b610f78565b604080518082019091526000808252602082015260606106e0604051806040016040528060008152602001600081525090565b60408051808201825260008082526001600160401b0360208084018290528451838152908101909452919550918261073b565b6040805180820190915260008152606060208201528152602001906001900390816107135790505b509350600080610760604089013560608a013561075b60208c018c6120c9565b610fae565b60408051808201909152918252602082015296989597505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633146107ce576040516391ac5e4f60e01b81523360048201526024015b60405180910390fd5b602087018035906107e8906107e3908a6120c9565b610ff2565b14610826576107fa60208801886120c9565b60405163309afaf360e21b815263ffffffff9091166004820152602088013560248201526044016107c5565b6108358787878787878761102e565b50505050505050565b610846611195565b61085082826111c2565b5050565b604080518082019091526000808252602082015260006108846040850135606086013561075b60208801886120c9565b9150506000806108948684611217565b90925090506108b16108a960208801886120c9565b83838861133a565b93505050505b92915050565b6003602090815260009283526040808420909152908252902080546108e190612235565b80601f016020809104026020016040519081016040528092919081815260200182805461090d90612235565b801561095a5780601f1061092f5761010080835404028352916020019161095a565b820191906000526020600020905b81548152906001019060200180831161093d57829003601f168201915b505050505081565b61096a611195565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527ff0be4f1e87349231d80c36b33f9e8639658eeaf474014dee15a3e6a4d4414197906020015b60405180910390a150565b6109c7611195565b6109d1600061141b565b565b6001600160a01b03811630145b949350505050565b6109f0611195565b6108506109fd828461230a565b61146b565b63ffffffff8416600090815260036020908152604080832061ffff87168452909152812080546060929190610a3690612235565b80601f0160208091040260200160405190810160405280929190818152602001828054610a6290612235565b8015610aaf5780601f10610a8457610100808354040283529160200191610aaf565b820191906000526020600020905b815481529060010190602001808311610a9257829003601f168201915b505050505090508051600003610aff5783838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509294506109e09350505050565b6000839003610b0f5790506109e0565b60028310610b8d57610b5684848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061157292505050565b80610b648460028188612433565b604051602001610b769392919061245d565b6040516020818303038152906040529150506109e0565b8383604051639a6d49cd60e01b81526004016107c59291906124ae565b60005b81811015610cb35736838383818110610bc857610bc86124c2565b9050602002810190610bda91906124d8565b9050610c0d610bec60208301836120c9565b602083013563ffffffff919091166000908152600160205260409020541490565b610c175750610cab565b3063d045a0dc60c08301358360a0810135610c366101008301836124f9565b610c47610100890160e08a01611fc1565b610c556101208a018a6124f9565b6040518963ffffffff1660e01b8152600401610c779796959493929190612554565b6000604051808303818588803b158015610c9057600080fd5b505af1158015610ca4573d6000803e3d6000fd5b5050505050505b600101610bad565b50336001600160a01b0316638e9e70996040518163ffffffff1660e01b8152600401600060405180830381865afa158015610cf2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d1a91908101906125da565b604051638351eea760e01b81526004016107c59190611fae565b610d3c611c20565b6040805180820190915260008082526020820152600080610d7333604089013560608a0135610d6e60208c018c6120c9565b61159e565b91509150600080610d848984611217565b9092509050610db0610d9960208b018b6120c9565b8383610daa368d90038d018d612647565b8b6115ef565b60408051808201909152858152602080820186905282519298509096503391907f85496b760a4b7f8d66384b9df21b381f5d1b1e79f229a47aaf4c232edc2fe59a90610dfe908d018d6120c9565b6040805163ffffffff909216825260208201899052810187905260600160405180910390a350505050935093915050565b610e37611195565b60405163ca5eb5e160e01b81526001600160a01b0382811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063ca5eb5e190602401600060405180830381600087803b158015610e9a57600080fd5b505af1158015610eae573d6000803e3d6000fd5b5050505050565b333014610ed55760405163029a949d60e31b815260040160405180910390fd5b61083587878787878787610826565b610eec611195565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527fd48d879cef83a1c0bdda516f27b13ddb1b3f8bbac1c9e1511bb2a659c2427760906020016109b4565b610f42611195565b6001600160a01b038116610f6c57604051631e4fbdf760e01b8152600060048201526024016107c5565b610f758161141b565b50565b6000602082018035906001908390610f9090866120c9565b63ffffffff1681526020810191909152604001600020541492915050565b600080610fba856116fa565b915081905083811015610fea576040516371c4efed60e01b815260048101829052602481018590526044016107c5565b935093915050565b63ffffffff8116600090815260016020526040812054806108b75760405163f6ff4fb760e01b815263ffffffff841660048201526024016107c5565b600061104061103d8787611731565b90565b9050600061106c8261105a6110558a8a611750565b611773565b61106760208d018d6120c9565b6117a8565b905060288611156111335760006110a961108c60608c0160408d0161267a565b61109960208d018d6120c9565b846110a48c8c6117e6565b611831565b604051633e5ac80960e11b81529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690637cb59012906110ff9086908d906000908790600401612697565b600060405180830381600087803b15801561111957600080fd5b505af115801561112d573d6000803e3d6000fd5b50505050505b6001600160a01b038216887fefed6d3500546b29533b128a29e3a94d70788727f0507505ac12eaf2e578fd9c61116c60208d018d6120c9565b6040805163ffffffff9092168252602082018690520160405180910390a3505050505050505050565b6000546001600160a01b031633146109d15760405163118cdaa760e01b81523360048201526024016107c5565b63ffffffff8216600081815260016020908152604091829020849055815192835282018390527f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b910160405180910390a15050565b6060806000611274856020013561122d86611863565b61123a60a08901896124f9565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061188f92505050565b909350905060008161128757600161128a565b60025b90506112aa61129c60208801886120c9565b826105ae60808a018a6124f9565b6004549093506001600160a01b031680156113305760405163043a78eb60e01b81526001600160a01b0382169063043a78eb906112ed90889088906004016126c8565b602060405180830381865afa15801561130a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132e91906126ed565b505b5050509250929050565b60408051808201909152600080825260208201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ddc28c586040518060a001604052808863ffffffff16815260200161139d89610ff2565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b81526004016113d292919061270a565b6040805180830381865afa1580156113ee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141291906127b4565b95945050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60005b81518110156115425761149d82828151811061148c5761148c6124c2565b602002602001015160400151611572565b8181815181106114af576114af6124c2565b602002602001015160400151600360008484815181106114d1576114d16124c2565b60200260200101516000015163ffffffff1663ffffffff168152602001908152602001600020600084848151811061150b5761150b6124c2565b60200260200101516020015161ffff1661ffff16815260200190815260200160002090816115399190612817565b5060010161146e565b507fbe4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b674816040516109b491906128d5565b600281015161ffff81166003146108505781604051639a6d49cd60e01b81526004016107c59190611fae565b6000806115ac858585610fae565b90925090506115e66001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016873085611909565b94509492505050565b6115f7611c20565b60006116068460000151611976565b60208501519091501561162057611620846020015161199e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632637a450826040518060a001604052808b63ffffffff1681526020016116708c610ff2565b81526020018a815260200189815260200160008960200151111515815250866040518463ffffffff1660e01b81526004016116ac92919061270a565b60806040518083038185885af11580156116ca573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906116ef9190612965565b979650505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000061172781846129b1565b6108b791906129d3565b60006117406020828486612433565b611749916129f8565b9392505050565b6000611760602860208486612433565b61176991612a16565b60c01c9392505050565b60006108b77f00000000000000000000000000000000000000000000000000000000000000006001600160401b0384166129d3565b60006117de6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168585611a80565b509092915050565b60606117f58260288186612433565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929695505050505050565b60608484848460405160200161184a9493929190612a4e565b6040516020818303038152906040529050949350505050565b60006108b77f0000000000000000000000000000000000000000000000000000000000000000836129b1565b80516060901515806118d85784846040516020016118c492919091825260c01b6001600160c01b031916602082015260280190565b6040516020818303038152906040526118ff565b848433856040516020016118ef9493929190612a9d565b6040516020818303038152906040525b9150935093915050565b6040516001600160a01b0384811660248301528381166044830152606482018390526119709186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050611ab6565b50505050565b600081341461199a576040516304fb820960e51b81523460048201526024016107c5565b5090565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119fe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a229190612ae0565b90506001600160a01b038116611a4b576040516329b99a9560e11b815260040160405180910390fd5b6108506001600160a01b038216337f000000000000000000000000000000000000000000000000000000000000000085611909565b6040516001600160a01b03838116602483015260448201839052611ab191859182169063a9059cbb9060640161193e565b505050565b6000611acb6001600160a01b03841683611b19565b90508051600014158015611af0575080806020019051810190611aee91906126ed565b155b15611ab157604051635274afe760e01b81526001600160a01b03841660048201526024016107c5565b60606117498383600084600080856001600160a01b03168486604051611b3f9190612afd565b60006040518083038185875af1925050503d8060008114611b7c576040519150601f19603f3d011682016040523d82523d6000602084013e611b81565b606091505b5091509150611b91868383611b9b565b9695505050505050565b606082611bb057611bab82611bf7565b611749565b8151158015611bc757506001600160a01b0384163b155b15611bf057604051639996b31560e01b81526001600160a01b03851660048201526024016107c5565b5080611749565b805115611c075780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b60405180606001604052806000801916815260200160006001600160401b03168152602001611c62604051806040016040528060008152602001600081525090565b905290565b600060e08284031215611c7957600080fd5b50919050565b600060208284031215611c9157600080fd5b81356001600160401b03811115611ca757600080fd5b6109e084828501611c67565b60005b83811015611cce578181015183820152602001611cb6565b50506000910152565b60008151808452611cef816020860160208601611cb3565b601f01601f19169290920160200192915050565b8351815260208085015190820152600060a0820160a0604084015280855180835260c08501915060c08160051b86010192506020870160005b82811015611d845760bf198786030184528151805186526020810151905060406020870152611d6e6040870182611cd7565b9550506020938401939190910190600101611d3c565b50508551606086015250506020840151608084015290506109e0565b600060608284031215611c7957600080fd5b60008083601f840112611dc457600080fd5b5081356001600160401b03811115611ddb57600080fd5b602083019150836020828501011115611df357600080fd5b9250929050565b6001600160a01b0381168114610f7557600080fd5b600080600080600080600060e0888a031215611e2a57600080fd5b611e348989611da0565b96506060880135955060808801356001600160401b03811115611e5657600080fd5b611e628a828b01611db2565b90965094505060a0880135611e7681611dfa565b925060c08801356001600160401b03811115611e9157600080fd5b611e9d8a828b01611db2565b989b979a50959850939692959293505050565b803563ffffffff81168114611ec457600080fd5b919050565b60008060408385031215611edc57600080fd5b611ee583611eb0565b946020939093013593505050565b8015158114610f7557600080fd5b60008060408385031215611f1457600080fd5b82356001600160401b03811115611f2a57600080fd5b611f3685828601611c67565b9250506020830135611f4781611ef3565b809150509250929050565b8151815260208083015190820152604081016108b7565b803561ffff81168114611ec457600080fd5b60008060408385031215611f8e57600080fd5b611f9783611eb0565b9150611fa560208401611f69565b90509250929050565b6020815260006117496020830184611cd7565b600060208284031215611fd357600080fd5b813561174981611dfa565b60008060008060a08587031215611ff457600080fd5b611ffe8686611da0565b935060608501356001600160401b0381111561201957600080fd5b61202587828801611db2565b909450925050608085013561203981611dfa565b939692955090935050565b60008083601f84011261205657600080fd5b5081356001600160401b0381111561206d57600080fd5b6020830191508360208260051b8501011115611df357600080fd5b6000806020838503121561209b57600080fd5b82356001600160401b038111156120b157600080fd5b6120bd85828601612044565b90969095509350505050565b6000602082840312156120db57600080fd5b61174982611eb0565b600080600080606085870312156120fa57600080fd5b61210385611eb0565b935061211160208601611f69565b925060408501356001600160401b0381111561212c57600080fd5b61213887828801611db2565b95989497509550505050565b6000806000838503608081121561215a57600080fd5b84356001600160401b0381111561217057600080fd5b61217c87828801611c67565b9450506040601f198201121561219157600080fd5b5060208401915060608401356121a681611dfa565b809150509250925092565b600060c082019050835182526001600160401b03602085015116602083015260408401516121ec604084018280518252602090810151910152565b5082516080830152602083015160a0830152611749565b60006060828403121561221557600080fd5b6117498383611da0565b634e487b7160e01b600052604160045260246000fd5b600181811c9082168061224957607f821691505b602082108103611c7957634e487b7160e01b600052602260045260246000fd5b604051606081016001600160401b038111828210171561228b5761228b61221f565b60405290565b604080519081016001600160401b038111828210171561228b5761228b61221f565b604051601f8201601f191681016001600160401b03811182821017156122db576122db61221f565b604052919050565b60006001600160401b038211156122fc576122fc61221f565b50601f01601f191660200190565b60006001600160401b038311156123235761232361221f565b8260051b612333602082016122b3565b8481529083019060208101903683111561234c57600080fd5b845b838110156124295780356001600160401b0381111561236c57600080fd5b8601606036829003121561237f57600080fd5b612387612269565b61239082611eb0565b815261239e60208301611f69565b602082015260408201356001600160401b038111156123bc57600080fd5b919091019036601f8301126123d057600080fd5b81356123e36123de826122e3565b6122b3565b8181523660208386010111156123f857600080fd5b816020850160208301376000602083830101528060408401525050808552505060208301925060208101905061234e565b5095945050505050565b6000808585111561244357600080fd5b8386111561245057600080fd5b5050820193919092039150565b6000845161246f818460208901611cb3565b8201838582376000930192835250909392505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6020815260006109e0602083018486612485565b634e487b7160e01b600052603260045260246000fd5b6000823561013e198336030181126124ef57600080fd5b9190910192915050565b6000808335601e1984360301811261251057600080fd5b8301803591506001600160401b0382111561252a57600080fd5b602001915036819003821315611df357600080fd5b6001600160401b0381168114610f7557600080fd5b63ffffffff61256289611eb0565b168152602088810135908201526000604089013561257f8161253f565b6001600160401b03811660408401525087606083015260e060808301526125aa60e083018789612485565b6001600160a01b03861660a084015282810360c08401526125cc818587612485565b9a9950505050505050505050565b6000602082840312156125ec57600080fd5b81516001600160401b0381111561260257600080fd5b8201601f8101841361261357600080fd5b80516126216123de826122e3565b81815285602083850101111561263657600080fd5b611412826020830160208601611cb3565b6000604082840312801561265a57600080fd5b50612663612291565b823581526020928301359281019290925250919050565b60006020828403121561268c57600080fd5b81356117498161253f565b60018060a01b038516815283602082015261ffff83166040820152608060608201526000611b916080830184611cd7565b6040815260006126db6040830185611cd7565b82810360208401526114128185611cd7565b6000602082840312156126ff57600080fd5b815161174981611ef3565b6040815263ffffffff8351166040820152602083015160608201526000604084015160a0608084015261274060e0840182611cd7565b90506060850151603f198483030160a085015261275d8282611cd7565b60809690960151151560c08501525050506001600160a01b039190911660209091015290565b60006040828403121561279557600080fd5b61279d612291565b825181526020928301519281019290925250919050565b6000604082840312156127c657600080fd5b6117498383612783565b601f821115611ab157806000526020600020601f840160051c810160208510156127f75750805b601f840160051c820191505b81811015610eae5760008155600101612803565b81516001600160401b038111156128305761283061221f565b6128448161283e8454612235565b846127d0565b6020601f82116001811461287857600083156128605750848201515b600019600385901b1c1916600184901b178455610eae565b600084815260208120601f198516915b828110156128a85787850151825560209485019460019092019101612888565b50848210156128c65786840151600019600387901b60f8161c191681555b50505050600190811b01905550565b6000602082016020835280845180835260408501915060408160051b86010192506020860160005b8281101561295957603f19878603018452815163ffffffff815116865261ffff602082015116602087015260408101519050606060408701526129436060870182611cd7565b95505060209384019391909101906001016128fd565b50929695505050505050565b6000608082840312801561297857600080fd5b50612981612269565b8251815260208301516129938161253f565b60208201526129a58460408501612783565b60408201529392505050565b6000826129ce57634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176108b757634e487b7160e01b600052601160045260246000fd5b803560208310156108b757600019602084900360031b1b1692915050565b80356001600160c01b03198116906008841015612a47576001600160c01b0319600885900360031b81901b82161691505b5092915050565b6001600160401b0360c01b8560c01b16815263ffffffff60e01b8460e01b16600882015282600c82015260008251612a8d81602c850160208701611cb3565b91909101602c0195945050505050565b8481526001600160401b0360c01b8460c01b16602082015282602882015260008251612ad0816048850160208701611cb3565b9190910160480195945050505050565b600060208284031215612af257600080fd5b815161174981611dfa565b600082516124ef818460208701611cb356fea26469706673582212205c6f631f1c5a47785d55b30d150736973ffc94eed8f3b5c3c27743d9b517abeb64736f6c634300081c00330000000000000000000000004c1746a800d224393fe2470c70a35717ed4ea5f10000000000000000000000001a44076050125825900e736c501f859c50fe728c00000000000000000000000032269a597bd1ec70a1ae53bb88cedb479916c470
Deployed Bytecode
0x6080604052600436106101ee5760003560e01c806382413eac1161010d578063bc70b354116100a0578063d045a0dc1161006f578063d045a0dc14610607578063d42438851461061a578063f2fde38b1461063a578063fc0c546a1461065a578063ff7bd03d1461068d57600080fd5b8063bc70b35414610593578063bd815db0146105b3578063c7c7f5b3146105c6578063ca5eb5e1146105e757600080fd5b80639f68b964116100dc5780639f68b96414610512578063b731ea0a14610526578063b98bd07014610546578063bb0b6a531461056657600080fd5b806382413eac14610476578063857749b0146104965780638da5cb5b146104b2578063963efcaa146104d057600080fd5b80633b6f743b116101855780635e280f11116101545780635e280f11146103d25780636fc1b31e14610406578063715018a6146104265780637d25a05e1461043b57600080fd5b80633b6f743b1461031e57806352ae28791461034b5780635535d4611461035e5780635a0dfe4d1461038b57600080fd5b8063156a0d0f116101c1578063156a0d0f146102a057806317442b70146102c75780631f5e1334146102e95780633400288b146102fe57600080fd5b80630d35b415146101f3578063111ecdad1461022b57806313137d6514610263578063134d4f2514610278575b600080fd5b3480156101ff57600080fd5b5061021361020e366004611c7f565b6106ad565b60405161022293929190611d03565b60405180910390f35b34801561023757600080fd5b5060045461024b906001600160a01b031681565b6040516001600160a01b039091168152602001610222565b610276610271366004611e0f565b61077e565b005b34801561028457600080fd5b5061028d600281565b60405161ffff9091168152602001610222565b3480156102ac57600080fd5b506040805162b9270b60e21b81526001602082015201610222565b3480156102d357600080fd5b5060408051600181526002602082015201610222565b3480156102f557600080fd5b5061028d600181565b34801561030a57600080fd5b50610276610319366004611ec9565b61083e565b34801561032a57600080fd5b5061033e610339366004611f01565b610854565b6040516102229190611f52565b34801561035757600080fd5b503061024b565b34801561036a57600080fd5b5061037e610379366004611f7b565b6108bd565b6040516102229190611fae565b34801561039757600080fd5b506103c26103a6366004611ec9565b63ffffffff919091166000908152600160205260409020541490565b6040519015158152602001610222565b3480156103de57600080fd5b5061024b7f0000000000000000000000001a44076050125825900e736c501f859c50fe728c81565b34801561041257600080fd5b50610276610421366004611fc1565b610962565b34801561043257600080fd5b506102766109bf565b34801561044757600080fd5b5061045e610456366004611ec9565b600092915050565b6040516001600160401b039091168152602001610222565b34801561048257600080fd5b506103c2610491366004611fde565b6109d3565b3480156104a257600080fd5b5060405160068152602001610222565b3480156104be57600080fd5b506000546001600160a01b031661024b565b3480156104dc57600080fd5b506105047f000000000000000000000000000000000000000000000000000000e8d4a5100081565b604051908152602001610222565b34801561051e57600080fd5b5060016103c2565b34801561053257600080fd5b5060025461024b906001600160a01b031681565b34801561055257600080fd5b50610276610561366004612088565b6109e8565b34801561057257600080fd5b506105046105813660046120c9565b60016020526000908152604090205481565b34801561059f57600080fd5b5061037e6105ae3660046120e4565b610a02565b6102766105c1366004612088565b610baa565b6105d96105d4366004612144565b610d34565b6040516102229291906121b1565b3480156105f357600080fd5b50610276610602366004611fc1565b610e2f565b610276610615366004611e0f565b610eb5565b34801561062657600080fd5b50610276610635366004611fc1565b610ee4565b34801561064657600080fd5b50610276610655366004611fc1565b610f3a565b34801561066657600080fd5b507f0000000000000000000000004c1746a800d224393fe2470c70a35717ed4ea5f161024b565b34801561069957600080fd5b506103c26106a8366004612203565b610f78565b604080518082019091526000808252602082015260606106e0604051806040016040528060008152602001600081525090565b60408051808201825260008082526001600160401b0360208084018290528451838152908101909452919550918261073b565b6040805180820190915260008152606060208201528152602001906001900390816107135790505b509350600080610760604089013560608a013561075b60208c018c6120c9565b610fae565b60408051808201909152918252602082015296989597505050505050565b7f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b031633146107ce576040516391ac5e4f60e01b81523360048201526024015b60405180910390fd5b602087018035906107e8906107e3908a6120c9565b610ff2565b14610826576107fa60208801886120c9565b60405163309afaf360e21b815263ffffffff9091166004820152602088013560248201526044016107c5565b6108358787878787878761102e565b50505050505050565b610846611195565b61085082826111c2565b5050565b604080518082019091526000808252602082015260006108846040850135606086013561075b60208801886120c9565b9150506000806108948684611217565b90925090506108b16108a960208801886120c9565b83838861133a565b93505050505b92915050565b6003602090815260009283526040808420909152908252902080546108e190612235565b80601f016020809104026020016040519081016040528092919081815260200182805461090d90612235565b801561095a5780601f1061092f5761010080835404028352916020019161095a565b820191906000526020600020905b81548152906001019060200180831161093d57829003601f168201915b505050505081565b61096a611195565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527ff0be4f1e87349231d80c36b33f9e8639658eeaf474014dee15a3e6a4d4414197906020015b60405180910390a150565b6109c7611195565b6109d1600061141b565b565b6001600160a01b03811630145b949350505050565b6109f0611195565b6108506109fd828461230a565b61146b565b63ffffffff8416600090815260036020908152604080832061ffff87168452909152812080546060929190610a3690612235565b80601f0160208091040260200160405190810160405280929190818152602001828054610a6290612235565b8015610aaf5780601f10610a8457610100808354040283529160200191610aaf565b820191906000526020600020905b815481529060010190602001808311610a9257829003601f168201915b505050505090508051600003610aff5783838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509294506109e09350505050565b6000839003610b0f5790506109e0565b60028310610b8d57610b5684848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061157292505050565b80610b648460028188612433565b604051602001610b769392919061245d565b6040516020818303038152906040529150506109e0565b8383604051639a6d49cd60e01b81526004016107c59291906124ae565b60005b81811015610cb35736838383818110610bc857610bc86124c2565b9050602002810190610bda91906124d8565b9050610c0d610bec60208301836120c9565b602083013563ffffffff919091166000908152600160205260409020541490565b610c175750610cab565b3063d045a0dc60c08301358360a0810135610c366101008301836124f9565b610c47610100890160e08a01611fc1565b610c556101208a018a6124f9565b6040518963ffffffff1660e01b8152600401610c779796959493929190612554565b6000604051808303818588803b158015610c9057600080fd5b505af1158015610ca4573d6000803e3d6000fd5b5050505050505b600101610bad565b50336001600160a01b0316638e9e70996040518163ffffffff1660e01b8152600401600060405180830381865afa158015610cf2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d1a91908101906125da565b604051638351eea760e01b81526004016107c59190611fae565b610d3c611c20565b6040805180820190915260008082526020820152600080610d7333604089013560608a0135610d6e60208c018c6120c9565b61159e565b91509150600080610d848984611217565b9092509050610db0610d9960208b018b6120c9565b8383610daa368d90038d018d612647565b8b6115ef565b60408051808201909152858152602080820186905282519298509096503391907f85496b760a4b7f8d66384b9df21b381f5d1b1e79f229a47aaf4c232edc2fe59a90610dfe908d018d6120c9565b6040805163ffffffff909216825260208201899052810187905260600160405180910390a350505050935093915050565b610e37611195565b60405163ca5eb5e160e01b81526001600160a01b0382811660048301527f0000000000000000000000001a44076050125825900e736c501f859c50fe728c169063ca5eb5e190602401600060405180830381600087803b158015610e9a57600080fd5b505af1158015610eae573d6000803e3d6000fd5b5050505050565b333014610ed55760405163029a949d60e31b815260040160405180910390fd5b61083587878787878787610826565b610eec611195565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527fd48d879cef83a1c0bdda516f27b13ddb1b3f8bbac1c9e1511bb2a659c2427760906020016109b4565b610f42611195565b6001600160a01b038116610f6c57604051631e4fbdf760e01b8152600060048201526024016107c5565b610f758161141b565b50565b6000602082018035906001908390610f9090866120c9565b63ffffffff1681526020810191909152604001600020541492915050565b600080610fba856116fa565b915081905083811015610fea576040516371c4efed60e01b815260048101829052602481018590526044016107c5565b935093915050565b63ffffffff8116600090815260016020526040812054806108b75760405163f6ff4fb760e01b815263ffffffff841660048201526024016107c5565b600061104061103d8787611731565b90565b9050600061106c8261105a6110558a8a611750565b611773565b61106760208d018d6120c9565b6117a8565b905060288611156111335760006110a961108c60608c0160408d0161267a565b61109960208d018d6120c9565b846110a48c8c6117e6565b611831565b604051633e5ac80960e11b81529091506001600160a01b037f0000000000000000000000001a44076050125825900e736c501f859c50fe728c1690637cb59012906110ff9086908d906000908790600401612697565b600060405180830381600087803b15801561111957600080fd5b505af115801561112d573d6000803e3d6000fd5b50505050505b6001600160a01b038216887fefed6d3500546b29533b128a29e3a94d70788727f0507505ac12eaf2e578fd9c61116c60208d018d6120c9565b6040805163ffffffff9092168252602082018690520160405180910390a3505050505050505050565b6000546001600160a01b031633146109d15760405163118cdaa760e01b81523360048201526024016107c5565b63ffffffff8216600081815260016020908152604091829020849055815192835282018390527f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b910160405180910390a15050565b6060806000611274856020013561122d86611863565b61123a60a08901896124f9565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061188f92505050565b909350905060008161128757600161128a565b60025b90506112aa61129c60208801886120c9565b826105ae60808a018a6124f9565b6004549093506001600160a01b031680156113305760405163043a78eb60e01b81526001600160a01b0382169063043a78eb906112ed90889088906004016126c8565b602060405180830381865afa15801561130a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132e91906126ed565b505b5050509250929050565b60408051808201909152600080825260208201527f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b031663ddc28c586040518060a001604052808863ffffffff16815260200161139d89610ff2565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b81526004016113d292919061270a565b6040805180830381865afa1580156113ee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141291906127b4565b95945050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60005b81518110156115425761149d82828151811061148c5761148c6124c2565b602002602001015160400151611572565b8181815181106114af576114af6124c2565b602002602001015160400151600360008484815181106114d1576114d16124c2565b60200260200101516000015163ffffffff1663ffffffff168152602001908152602001600020600084848151811061150b5761150b6124c2565b60200260200101516020015161ffff1661ffff16815260200190815260200160002090816115399190612817565b5060010161146e565b507fbe4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b674816040516109b491906128d5565b600281015161ffff81166003146108505781604051639a6d49cd60e01b81526004016107c59190611fae565b6000806115ac858585610fae565b90925090506115e66001600160a01b037f0000000000000000000000004c1746a800d224393fe2470c70a35717ed4ea5f116873085611909565b94509492505050565b6115f7611c20565b60006116068460000151611976565b60208501519091501561162057611620846020015161199e565b7f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b0316632637a450826040518060a001604052808b63ffffffff1681526020016116708c610ff2565b81526020018a815260200189815260200160008960200151111515815250866040518463ffffffff1660e01b81526004016116ac92919061270a565b60806040518083038185885af11580156116ca573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906116ef9190612965565b979650505050505050565b60007f000000000000000000000000000000000000000000000000000000e8d4a5100061172781846129b1565b6108b791906129d3565b60006117406020828486612433565b611749916129f8565b9392505050565b6000611760602860208486612433565b61176991612a16565b60c01c9392505050565b60006108b77f000000000000000000000000000000000000000000000000000000e8d4a510006001600160401b0384166129d3565b60006117de6001600160a01b037f0000000000000000000000004c1746a800d224393fe2470c70a35717ed4ea5f1168585611a80565b509092915050565b60606117f58260288186612433565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929695505050505050565b60608484848460405160200161184a9493929190612a4e565b6040516020818303038152906040529050949350505050565b60006108b77f000000000000000000000000000000000000000000000000000000e8d4a51000836129b1565b80516060901515806118d85784846040516020016118c492919091825260c01b6001600160c01b031916602082015260280190565b6040516020818303038152906040526118ff565b848433856040516020016118ef9493929190612a9d565b6040516020818303038152906040525b9150935093915050565b6040516001600160a01b0384811660248301528381166044830152606482018390526119709186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050611ab6565b50505050565b600081341461199a576040516304fb820960e51b81523460048201526024016107c5565b5090565b60007f0000000000000000000000001a44076050125825900e736c501f859c50fe728c6001600160a01b031663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119fe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a229190612ae0565b90506001600160a01b038116611a4b576040516329b99a9560e11b815260040160405180910390fd5b6108506001600160a01b038216337f0000000000000000000000001a44076050125825900e736c501f859c50fe728c85611909565b6040516001600160a01b03838116602483015260448201839052611ab191859182169063a9059cbb9060640161193e565b505050565b6000611acb6001600160a01b03841683611b19565b90508051600014158015611af0575080806020019051810190611aee91906126ed565b155b15611ab157604051635274afe760e01b81526001600160a01b03841660048201526024016107c5565b60606117498383600084600080856001600160a01b03168486604051611b3f9190612afd565b60006040518083038185875af1925050503d8060008114611b7c576040519150601f19603f3d011682016040523d82523d6000602084013e611b81565b606091505b5091509150611b91868383611b9b565b9695505050505050565b606082611bb057611bab82611bf7565b611749565b8151158015611bc757506001600160a01b0384163b155b15611bf057604051639996b31560e01b81526001600160a01b03851660048201526024016107c5565b5080611749565b805115611c075780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b60405180606001604052806000801916815260200160006001600160401b03168152602001611c62604051806040016040528060008152602001600081525090565b905290565b600060e08284031215611c7957600080fd5b50919050565b600060208284031215611c9157600080fd5b81356001600160401b03811115611ca757600080fd5b6109e084828501611c67565b60005b83811015611cce578181015183820152602001611cb6565b50506000910152565b60008151808452611cef816020860160208601611cb3565b601f01601f19169290920160200192915050565b8351815260208085015190820152600060a0820160a0604084015280855180835260c08501915060c08160051b86010192506020870160005b82811015611d845760bf198786030184528151805186526020810151905060406020870152611d6e6040870182611cd7565b9550506020938401939190910190600101611d3c565b50508551606086015250506020840151608084015290506109e0565b600060608284031215611c7957600080fd5b60008083601f840112611dc457600080fd5b5081356001600160401b03811115611ddb57600080fd5b602083019150836020828501011115611df357600080fd5b9250929050565b6001600160a01b0381168114610f7557600080fd5b600080600080600080600060e0888a031215611e2a57600080fd5b611e348989611da0565b96506060880135955060808801356001600160401b03811115611e5657600080fd5b611e628a828b01611db2565b90965094505060a0880135611e7681611dfa565b925060c08801356001600160401b03811115611e9157600080fd5b611e9d8a828b01611db2565b989b979a50959850939692959293505050565b803563ffffffff81168114611ec457600080fd5b919050565b60008060408385031215611edc57600080fd5b611ee583611eb0565b946020939093013593505050565b8015158114610f7557600080fd5b60008060408385031215611f1457600080fd5b82356001600160401b03811115611f2a57600080fd5b611f3685828601611c67565b9250506020830135611f4781611ef3565b809150509250929050565b8151815260208083015190820152604081016108b7565b803561ffff81168114611ec457600080fd5b60008060408385031215611f8e57600080fd5b611f9783611eb0565b9150611fa560208401611f69565b90509250929050565b6020815260006117496020830184611cd7565b600060208284031215611fd357600080fd5b813561174981611dfa565b60008060008060a08587031215611ff457600080fd5b611ffe8686611da0565b935060608501356001600160401b0381111561201957600080fd5b61202587828801611db2565b909450925050608085013561203981611dfa565b939692955090935050565b60008083601f84011261205657600080fd5b5081356001600160401b0381111561206d57600080fd5b6020830191508360208260051b8501011115611df357600080fd5b6000806020838503121561209b57600080fd5b82356001600160401b038111156120b157600080fd5b6120bd85828601612044565b90969095509350505050565b6000602082840312156120db57600080fd5b61174982611eb0565b600080600080606085870312156120fa57600080fd5b61210385611eb0565b935061211160208601611f69565b925060408501356001600160401b0381111561212c57600080fd5b61213887828801611db2565b95989497509550505050565b6000806000838503608081121561215a57600080fd5b84356001600160401b0381111561217057600080fd5b61217c87828801611c67565b9450506040601f198201121561219157600080fd5b5060208401915060608401356121a681611dfa565b809150509250925092565b600060c082019050835182526001600160401b03602085015116602083015260408401516121ec604084018280518252602090810151910152565b5082516080830152602083015160a0830152611749565b60006060828403121561221557600080fd5b6117498383611da0565b634e487b7160e01b600052604160045260246000fd5b600181811c9082168061224957607f821691505b602082108103611c7957634e487b7160e01b600052602260045260246000fd5b604051606081016001600160401b038111828210171561228b5761228b61221f565b60405290565b604080519081016001600160401b038111828210171561228b5761228b61221f565b604051601f8201601f191681016001600160401b03811182821017156122db576122db61221f565b604052919050565b60006001600160401b038211156122fc576122fc61221f565b50601f01601f191660200190565b60006001600160401b038311156123235761232361221f565b8260051b612333602082016122b3565b8481529083019060208101903683111561234c57600080fd5b845b838110156124295780356001600160401b0381111561236c57600080fd5b8601606036829003121561237f57600080fd5b612387612269565b61239082611eb0565b815261239e60208301611f69565b602082015260408201356001600160401b038111156123bc57600080fd5b919091019036601f8301126123d057600080fd5b81356123e36123de826122e3565b6122b3565b8181523660208386010111156123f857600080fd5b816020850160208301376000602083830101528060408401525050808552505060208301925060208101905061234e565b5095945050505050565b6000808585111561244357600080fd5b8386111561245057600080fd5b5050820193919092039150565b6000845161246f818460208901611cb3565b8201838582376000930192835250909392505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6020815260006109e0602083018486612485565b634e487b7160e01b600052603260045260246000fd5b6000823561013e198336030181126124ef57600080fd5b9190910192915050565b6000808335601e1984360301811261251057600080fd5b8301803591506001600160401b0382111561252a57600080fd5b602001915036819003821315611df357600080fd5b6001600160401b0381168114610f7557600080fd5b63ffffffff61256289611eb0565b168152602088810135908201526000604089013561257f8161253f565b6001600160401b03811660408401525087606083015260e060808301526125aa60e083018789612485565b6001600160a01b03861660a084015282810360c08401526125cc818587612485565b9a9950505050505050505050565b6000602082840312156125ec57600080fd5b81516001600160401b0381111561260257600080fd5b8201601f8101841361261357600080fd5b80516126216123de826122e3565b81815285602083850101111561263657600080fd5b611412826020830160208601611cb3565b6000604082840312801561265a57600080fd5b50612663612291565b823581526020928301359281019290925250919050565b60006020828403121561268c57600080fd5b81356117498161253f565b60018060a01b038516815283602082015261ffff83166040820152608060608201526000611b916080830184611cd7565b6040815260006126db6040830185611cd7565b82810360208401526114128185611cd7565b6000602082840312156126ff57600080fd5b815161174981611ef3565b6040815263ffffffff8351166040820152602083015160608201526000604084015160a0608084015261274060e0840182611cd7565b90506060850151603f198483030160a085015261275d8282611cd7565b60809690960151151560c08501525050506001600160a01b039190911660209091015290565b60006040828403121561279557600080fd5b61279d612291565b825181526020928301519281019290925250919050565b6000604082840312156127c657600080fd5b6117498383612783565b601f821115611ab157806000526020600020601f840160051c810160208510156127f75750805b601f840160051c820191505b81811015610eae5760008155600101612803565b81516001600160401b038111156128305761283061221f565b6128448161283e8454612235565b846127d0565b6020601f82116001811461287857600083156128605750848201515b600019600385901b1c1916600184901b178455610eae565b600084815260208120601f198516915b828110156128a85787850151825560209485019460019092019101612888565b50848210156128c65786840151600019600387901b60f8161c191681555b50505050600190811b01905550565b6000602082016020835280845180835260408501915060408160051b86010192506020860160005b8281101561295957603f19878603018452815163ffffffff815116865261ffff602082015116602087015260408101519050606060408701526129436060870182611cd7565b95505060209384019391909101906001016128fd565b50929695505050505050565b6000608082840312801561297857600080fd5b50612981612269565b8251815260208301516129938161253f565b60208201526129a58460408501612783565b60408201529392505050565b6000826129ce57634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176108b757634e487b7160e01b600052601160045260246000fd5b803560208310156108b757600019602084900360031b1b1692915050565b80356001600160c01b03198116906008841015612a47576001600160c01b0319600885900360031b81901b82161691505b5092915050565b6001600160401b0360c01b8560c01b16815263ffffffff60e01b8460e01b16600882015282600c82015260008251612a8d81602c850160208701611cb3565b91909101602c0195945050505050565b8481526001600160401b0360c01b8460c01b16602082015282602882015260008251612ad0816048850160208701611cb3565b9190910160480195945050505050565b600060208284031215612af257600080fd5b815161174981611dfa565b600082516124ef818460208701611cb356fea26469706673582212205c6f631f1c5a47785d55b30d150736973ffc94eed8f3b5c3c27743d9b517abeb64736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000004c1746a800d224393fe2470c70a35717ed4ea5f10000000000000000000000001a44076050125825900e736c501f859c50fe728c00000000000000000000000032269a597bd1ec70a1ae53bb88cedb479916c470
-----Decoded View---------------
Arg [0] : _token (address): 0x4C1746A800D224393fE2470C70A35717eD4eA5F1
Arg [1] : _lzEndpoint (address): 0x1a44076050125825900e736c501f859c50fE728c
Arg [2] : _delegate (address): 0x32269A597bd1Ec70A1aE53Bb88Cedb479916c470
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000004c1746a800d224393fe2470c70a35717ed4ea5f1
Arg [1] : 0000000000000000000000001a44076050125825900e736c501f859c50fe728c
Arg [2] : 00000000000000000000000032269a597bd1ec70a1ae53bb88cedb479916c470
Deployed Bytecode Sourcemap
121956:533:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102705:1283;;;;;;;;;;-1:-1:-1;102705:1283:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;99848:27;;;;;;;;;;-1:-1:-1;99848:27:0;;;;-1:-1:-1;;;;;99848:27:0;;;;;;-1:-1:-1;;;;;2696:32:1;;;2678:51;;2666:2;2651:18;99848:27:0;2532:203:1;71136:725:0;;;;;;:::i;:::-;;:::i;:::-;;99719:40;;;;;;;;;;;;99758:1;99719:40;;;;;4663:6:1;4651:19;;;4633:38;;4621:2;4606:18;99719:40:0;4489:188:1;101017:142:0;;;;;;;;;;-1:-1:-1;101017:142:0;;;-1:-1:-1;;;4852:52:1;;101149:1:0;4935:2:1;4920:18;;4913:59;4825:18;101017:142:0;4682:296:1;97920:245:0;;;;;;;;;;-1:-1:-1;97920:245:0;;;74791:1;5153:50:1;;67365:1:0;5234:2:1;5219:18;;5212:59;5126:18;97920:245:0;4983:294:1;99681:31:0;;;;;;;;;;;;99711:1;99681:31;;59007:110;;;;;;;;;;-1:-1:-1;59007:110:0;;;;;:::i;:::-;;:::i;104451:789::-;;;;;;;;;;-1:-1:-1;104451:789:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;92189:95::-;;;;;;;;;;-1:-1:-1;92271:4:0;92189:95;;37780:93;;;;;;;;;;-1:-1:-1;37780:93:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;112881:134::-;;;;;;;;;;-1:-1:-1;112881:134:0;;;;;:::i;:::-;112987:11;;;;;112963:4;112987:11;;;:5;:11;;;;;;:20;;112881:134;;;;7449:14:1;;7442:22;7424:41;;7412:2;7397:18;112881:134:0;7284:187:1;57696:48:0;;;;;;;;;;;;;;;102224:166;;;;;;;;;;-1:-1:-1;102224:166:0;;;;;:::i;:::-;;:::i;35091:103::-;;;;;;;;;;;;;:::i;70258:130::-;;;;;;;;;;-1:-1:-1;70258:130:0;;;;;:::i;:::-;70347:12;70258:130;;;;;;;;-1:-1:-1;;;;;8129:31:1;;;8111:50;;8099:2;8084:18;70258:130:0;7967:200:1;68728:224:0;;;;;;;;;;-1:-1:-1;68728:224:0;;;;;:::i;:::-;;:::i;101778:89::-;;;;;;;;;;-1:-1:-1;101778:89:0;;101858:1;8991:36:1;;8979:2;8964:18;101778:89:0;8849:184:1;34416:87:0;;;;;;;;;;-1:-1:-1;34462:7:0;34489:6;-1:-1:-1;;;;;34489:6:0;34416:87;;99370:46;;;;;;;;;;;;;;;;;;9184:25:1;;;9172:2;9157:18;99370:46:0;9038:177:1;119360:95:0;;;;;;;;;;-1:-1:-1;119443:4:0;119360:95;;91864:23;;;;;;;;;;-1:-1:-1;91864:23:0;;;;-1:-1:-1;;;;;91864:23:0;;;38645:158;;;;;;;;;;-1:-1:-1;38645:158:0;;;;;:::i;:::-;;:::i;57824:48::-;;;;;;;;;;-1:-1:-1;57824:48:0;;;;;:::i;:::-;;;;;;;;;;;;;;40799:1003;;;;;;;;;;-1:-1:-1;40799:1003:0;;;;;:::i;:::-;;:::i;93033:1358::-;;;;;;:::i;:::-;;:::i;105945:1368::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;60572:107::-;;;;;;;;;;-1:-1:-1;60572:107:0;;;;;:::i;:::-;;:::i;95053:421::-;;;;;;:::i;:::-;;:::i;92422:142::-;;;;;;;;;;-1:-1:-1;92422:142:0;;;;;:::i;:::-;;:::i;35349:220::-;;;;;;;;;;-1:-1:-1;35349:220:0;;;;;:::i;:::-;;:::i;118858:92::-;;;;;;;;;;-1:-1:-1;118931:10:0;118858:92;;69505:153;;;;;;;;;;-1:-1:-1;69505:153:0;;;;;:::i;:::-;;:::i;102705:1283::-;-1:-1:-1;;;;;;;;;;;;;;;;;102863:35:0;102900:28;-1:-1:-1;;;;;;;;;;;;;;;;;;;102900:28:0;103122:34;;;;;;;;-1:-1:-1;103122:34:0;;;-1:-1:-1;;;;;103122:34:0;;;;;;;103276:21;;;;;;;;;;;103122:34;;-1:-1:-1;;;103276:21:0;;;-1:-1:-1;;;;;;;;;;;;;;;;;103276:21:0;;;;;;;;;;;;;;;-1:-1:-1;103260:37:0;-1:-1:-1;103740:20:0;;103790:124;103815:19;;;;103849:22;;;;103886:17;;;;103815:10;103886:17;:::i;:::-;103790:10;:124::i;:::-;103938:42;;;;;;;;;;;;;;;;102705:1283;;;;-1:-1:-1;;;;;;102705:1283:0:o;71136:725::-;71459:8;-1:-1:-1;;;;;71451:31:0;71472:10;71451:31;71447:68;;71491:24;;-1:-1:-1;;;71491:24:0;;71504:10;71491:24;;;2678:51:1;2651:18;;71491:24:0;;;;;;;;71447:68;71654:14;;;;;;71618:32;;71635:14;;71654:7;71635:14;:::i;:::-;71618:16;:32::i;:::-;:50;71614:103;;71686:14;;;;:7;:14;:::i;:::-;71677:40;;-1:-1:-1;;;71677:40:0;;13423:10:1;13411:23;;;71677:40:0;;;13393:42:1;71702:14:0;;;;13451:18:1;;;13444:34;13366:18;;71677:40:0;13221:263:1;71614:103:0;71794:59;71805:7;71814:5;71821:8;;71831:9;71842:10;;71794;:59::i;:::-;71136:725;;;;;;;:::o;59007:110::-;34302:13;:11;:13::i;:::-;59088:21:::1;59097:4;59103:5;59088:8;:21::i;:::-;59007:110:::0;;:::o;104451:789::-;-1:-1:-1;;;;;;;;;;;;;;;;;104793:24:0;104821:74;104832:19;;;;104853:22;;;;104877:17;;;;104832:10;104877:17;:::i;104821:74::-;104790:105;;;104987:20;105009;105033:49;105053:10;105065:16;105033:19;:49::i;:::-;104986:96;;-1:-1:-1;104986:96:0;-1:-1:-1;105174:58:0;105181:17;;;;:10;:17;:::i;:::-;105200:7;105209;105218:13;105174:6;:58::i;:::-;105167:65;;;;;104451:789;;;;;:::o;37780:93::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;102224:166::-;34302:13;:11;:13::i;:::-;102308:12:::1;:28:::0;;-1:-1:-1;;;;;;102308:28:0::1;-1:-1:-1::0;;;;;102308:28:0;::::1;::::0;;::::1;::::0;;;102352:30:::1;::::0;2678:51:1;;;102352:30:0::1;::::0;2666:2:1;2651:18;102352:30:0::1;;;;;;;;102224:166:::0;:::o;35091:103::-;34302:13;:11;:13::i;:::-;35156:30:::1;35183:1;35156:18;:30::i;:::-;35091:103::o:0;68728:224::-;-1:-1:-1;;;;;68920:24:0;;68939:4;68920:24;68728:224;;;;;;;:::o;38645:158::-;34302:13;:11;:13::i;:::-;38758:37:::1;;38778:16:::0;;38758:37:::1;:::i;:::-;:19;:37::i;40799:1003::-:0;40995:21;;;40971;40995;;;:15;:21;;;;;;;;:31;;;;;;;;;;40971:55;;40946:12;;40971:21;40995:31;40971:55;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41158:8;:15;41177:1;41158:20;41154:46;;41187:13;;41180:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41180:20:0;;-1:-1:-1;41180:20:0;;-1:-1:-1;;;;41180:20:0;41154:46;41288:1;41264:25;;;41260:46;;41298:8;-1:-1:-1;41291:15:0;;41260:46;41456:1;41432:25;;41428:271;;41474:34;41494:13;;41474:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41474:19:0;;-1:-1:-1;;;41474:34:0:i;:::-;41659:8;41669:17;:13;41683:1;41669:13;;:17;:::i;:::-;41646:41;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;41639:48;;;;;41428:271;41780:13;;41765:29;;-1:-1:-1;;;41765:29:0;;;;;;;;;:::i;93033:1358::-;93135:9;93130:1057;93150:19;;;93130:1057;;;93191:29;93223:8;;93232:1;93223:11;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;93191:43;-1:-1:-1;93320:50:0;93327:20;;;;93191:43;93327:20;:::i;:::-;93349;;;;112987:11;;;;;112963:4;112987:11;;;:5;:11;;;;;;:20;;112881:134;93320:50;93315:65;;93372:8;;;93315:65;93951:4;:22;93982:12;;;;:6;94047:11;;;;94077:14;;;;93982:6;94077:14;:::i;:::-;94110:15;;;;;;;;:::i;:::-;94144:16;;;;:6;:16;:::i;:::-;93951:224;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93176:1011;93130:1057;93171:3;;93130:1057;;;;94347:10;-1:-1:-1;;;;;94337:43:0;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;94337:45:0;;;;;;;;;;;;:::i;:::-;94320:63;;-1:-1:-1;;;94320:63:0;;;;;;;;:::i;105945:1368::-;106112:36;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;106516:20:0;;106566:145;106587:10;106612:19;;;;106646:22;;;;106683:17;;;;106612:10;106683:17;:::i;:::-;106566:6;:145::i;:::-;106515:196;;;;106803:20;106825;106849:49;106869:10;106881:16;106849:19;:49::i;:::-;106802:96;;-1:-1:-1;106802:96:0;-1:-1:-1;107024:66:0;107032:17;;;;:10;:17;:::i;:::-;107051:7;107060;107024:66;;;;;;;107069:4;107024:66;:::i;:::-;107075:14;107024:7;:66::i;:::-;107158:42;;;;;;;;;;;;;;;;;;;107226:15;;107011:79;;-1:-1:-1;107158:42:0;;-1:-1:-1;107262:10:0;;107226:15;107218:87;;107243:17;;;;:10;:17;:::i;:::-;107218:87;;;21562:10:1;21550:23;;;21532:42;;21605:2;21590:18;;21583:34;;;21633:18;;21626:34;;;21520:2;21505:18;107218:87:0;;;;;;;106180:1133;;;;105945:1368;;;;;;:::o;60572:107::-;34302:13;:11;:13::i;:::-;60640:31:::1;::::0;-1:-1:-1;;;60640:31:0;;-1:-1:-1;;;;;2696:32:1;;;60640:31:0::1;::::0;::::1;2678:51:1::0;60640:8:0::1;:20;::::0;::::1;::::0;2651:18:1;;60640:31:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;60572:107:::0;:::o;95053:421::-;95342:10;95364:4;95342:27;95338:50;;95378:10;;-1:-1:-1;;;95378:10:0;;;;;;;;;;;95338:50;95399:67;95418:7;95427:5;95434:8;;95444:9;95455:10;;95399:18;:67::i;92422:142::-;34302:13;:11;:13::i;:::-;92498:8:::1;:20:::0;;-1:-1:-1;;;;;;92498:20:0::1;-1:-1:-1::0;;;;;92498:20:0;::::1;::::0;;::::1;::::0;;;92534:22:::1;::::0;2678:51:1;;;92534:22:0::1;::::0;2666:2:1;2651:18;92534:22:0::1;2532:203:1::0;35349:220:0;34302:13;:11;:13::i;:::-;-1:-1:-1;;;;;35434:22:0;::::1;35430:93;;35480:31;::::0;-1:-1:-1;;;35480:31:0;;35508:1:::1;35480:31;::::0;::::1;2678:51:1::0;2651:18;;35480:31:0::1;2532:203:1::0;35430:93:0::1;35533:28;35552:8;35533:18;:28::i;:::-;35349:220:::0;:::o;69505:153::-;69589:4;69637:13;;;;;;69613:5;;69589:4;;69619:13;;69637:6;69619:13;:::i;:::-;69613:20;;;;;;;;;;;;;-1:-1:-1;69613:20:0;;:37;;69505:153;-1:-1:-1;;69505:153:0:o;114942:682::-;115088:20;115110:24;115286:22;115298:9;115286:11;:22::i;:::-;115271:37;;115436:12;115417:31;;115521:12;115502:16;:31;115498:119;;;115557:48;;-1:-1:-1;;;115557:48:0;;;;;21845:25:1;;;21886:18;;;21879:34;;;21818:18;;115557:48:0;21671:248:1;115498:119:0;114942:682;;;;;;:::o;60025:200::-;60130:11;;;60095:7;60130:11;;;:5;:11;;;;;;;60152:43;;60183:12;;-1:-1:-1;;;60183:12:0;;22098:10:1;22086:23;;60183:12:0;;;22068:42:1;22041:18;;60183:12:0;21924:192:1;109605:1839:0;110093:17;110113:36;:17;:8;;:15;:17::i;:::-;18410:2;18298:125;110113:36;110093:56;;110284:24;110311:62;110319:9;110330:26;110336:19;:8;;:17;:19::i;:::-;110330:5;:26::i;:::-;110358:14;;;;:7;:14;:::i;:::-;110311:7;:62::i;:::-;110284:89;-1:-1:-1;15689:2:0;-1:-1:-1;;110386:970:0;;;110492:23;110518:180;110562:13;;;;;;;;:::i;:::-;110594:14;;;;:7;:14;:::i;:::-;110627:16;110662:21;:8;;:19;:21::i;:::-;110518:25;:180::i;:::-;111252:92;;-1:-1:-1;;;111252:92:0;;110492:206;;-1:-1:-1;;;;;;111252:8:0;:20;;;;:92;;111273:9;;111284:5;;111291:1;;110492:206;;111252:92;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;110413:943;110386:970;-1:-1:-1;;;;;111373:63:0;;111385:5;111373:63;111392:14;;;;:7;:14;:::i;:::-;111373:63;;;13423:10:1;13411:23;;;13393:42;;13466:2;13451:18;;13444:34;;;13366:18;111373:63:0;;;;;;;109916:1528;;109605:1839;;;;;;;:::o;34581:166::-;34462:7;34489:6;-1:-1:-1;;;;;34489:6:0;32527:10;34641:23;34637:103;;34688:40;;-1:-1:-1;;;34688:40:0;;32527:10;34688:40;;;2678:51:1;2651:18;;34688:40:0;2532:203:1;59582:137:0;59656:11;;;;;;;:5;:11;;;;;;;;;:19;;;59691:20;;13393:42:1;;;13451:18;;13444:34;;;59691:20:0;;13366:18:1;59691:20:0;;;;;;;59582:137;;:::o;107616:1458::-;107751:20;107773;107806:15;107979:330;108012:10;:13;;;108040:16;108046:9;108040:5;:16::i;:::-;108277:21;;;;:10;:21;:::i;:::-;107979:330;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;107979:18:0;;-1:-1:-1;;;107979:330:0:i;:::-;107955:354;;-1:-1:-1;107955:354:0;-1:-1:-1;108391:14:0;107955:354;108408:33;;99711:1;108408:33;;;99758:1;108408:33;108391:50;-1:-1:-1;108565:67:0;108580:17;;;;:10;:17;:::i;:::-;108599:7;108608:23;;;;:10;:23;:::i;108565:67::-;108894:12;;108555:77;;-1:-1:-1;;;;;;108894:12:0;108987:23;;108983:83;;109012:54;;-1:-1:-1;;;109012:54:0;;-1:-1:-1;;;;;109012:36:0;;;;;:54;;109049:7;;109058;;109012:54;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;108983:83;107795:1279;;;107616:1458;;;;;:::o;76011:406::-;-1:-1:-1;;;;;;;;;;;;;;;;;76241:8:0;-1:-1:-1;;;;;76241:14:0;;76274:88;;;;;;;;76292:7;76274:88;;;;;;76301:25;76318:7;76301:16;:25::i;:::-;76274:88;;;;76328:8;76274:88;;;;76338:8;76274:88;;;;76348:13;76274:88;;;;;76389:4;76241:168;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;76221:188;76011:406;-1:-1:-1;;;;;76011:406:0:o;35729:191::-;35803:16;35822:6;;-1:-1:-1;;;;;35839:17:0;;;-1:-1:-1;;;;;;35839:17:0;;;;;;35872:40;;35822:6;;;;;;;35872:40;;35803:16;35872:40;35792:128;35729:191;:::o;39504:522::-;39613:9;39608:358;39632:16;:23;39628:1;:27;39608:358;;;39792:48;39812:16;39829:1;39812:19;;;;;;;;:::i;:::-;;;;;;;:27;;;39792:19;:48::i;:::-;39927:16;39944:1;39927:19;;;;;;;;:::i;:::-;;;;;;;:27;;;39855:15;:40;39871:16;39888:1;39871:19;;;;;;;;:::i;:::-;;;;;;;:23;;;39855:40;;;;;;;;;;;;;;;:69;39896:16;39913:1;39896:19;;;;;;;;:::i;:::-;;;;;;;:27;;;39855:69;;;;;;;;;;;;;;;:99;;;;;;:::i;:::-;-1:-1:-1;39657:3:0;;39608:358;;;;39983:35;40001:16;39983:35;;;;;;:::i;41948:270::-;42121:1;42107:16;;42101:23;42149:28;;;37702:1;42149:28;42145:65;;42201:8;42186:24;;-1:-1:-1;;;42186:24:0;;;;;;;;:::i;120372:466::-;120538:20;120560:24;120632:44;120643:9;120654:12;120668:7;120632:10;:44::i;:::-;120597:79;;-1:-1:-1;120597:79:0;-1:-1:-1;120767:63:0;-1:-1:-1;;;;;120767:10:0;:27;120795:5;120810:4;120597:79;120767:27;:63::i;:::-;120372:466;;;;;;;:::o;77192:789::-;77401:33;;:::i;:::-;77570:20;77593:26;77604:4;:14;;;77593:10;:26::i;:::-;77634:15;;;;77570:49;;-1:-1:-1;77634:19:0;77630:53;;77655:28;77667:4;:15;;;77655:11;:28::i;:::-;77776:8;-1:-1:-1;;;;;77776:13:0;;77798:12;77831:94;;;;;;;;77849:7;77831:94;;;;;;77858:25;77875:7;77858:16;:25::i;:::-;77831:94;;;;77885:8;77831:94;;;;77895:8;77831:94;;;;77923:1;77905:4;:15;;;:19;77831:94;;;;;77944:14;77776:197;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77696:277;77192:789;-1:-1:-1;;;;;;;77192:789:0:o;113419:174::-;113490:16;113564:21;113527:33;113564:21;113527:9;:33;:::i;:::-;113526:59;;;;:::i;17055:125::-;17115:7;17150:21;15633:2;17115:7;17150:4;;:21;:::i;:::-;17142:30;;;:::i;:::-;17135:37;17055:125;-1:-1:-1;;;17055:125:0:o;17365:154::-;17427:6;17467:42;15689:2;15633;17467:4;;:42;:::i;:::-;17460:50;;;:::i;:::-;17453:58;;;17365:154;-1:-1:-1;;;17365:154:0:o;113824:141::-;113888:16;113924:33;113936:21;-1:-1:-1;;;;;113924:33:0;;;:::i;121492:418::-;121630:24;121733:39;-1:-1:-1;;;;;121733:10:0;:23;121757:3;121762:9;121733:23;:39::i;:::-;-1:-1:-1;121893:9:0;;121492:418;-1:-1:-1;;121492:418:0:o;17686:132::-;17750:12;17782:28;:4;15689:2;17782:4;;:28;:::i;:::-;17775:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;17775:35:0;;17686:132;-1:-1:-1;;;;;;17686:132:0:o;12969:291::-;13158:17;13212:6;13220:7;13229:9;13240:11;13195:57;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;13188:64;;12969:291;;;;;;:::o;114196:149::-;114261:15;114303:33;114315:21;114303:9;:33;:::i;16054:516::-;16252:18;;16192:17;;16252:22;;;16397:165;;16539:7;16548:13;16522:40;;;;;;;;30952:19:1;;;31027:3;31005:16;-1:-1:-1;;;;;;31001:51:1;30996:2;30987:12;;30980:73;31078:2;31069:12;;30797:290;16522:40:0;;;;;;;;;;;;;16397:165;;;16440:7;16449:13;16481:10;16494:11;16423:83;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;16397:165;16390:172;;16054:516;;;;;;:::o;43831:190::-;43959:53;;-1:-1:-1;;;;;31849:32:1;;;43959:53:0;;;31831:51:1;31918:32;;;31898:18;;;31891:60;31967:18;;;31960:34;;;43932:81:0;;43952:5;;43974:18;;;;;31804::1;;43959:53:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;43959:53:0;;;;;;;;;;;43932:19;:81::i;:::-;43831:190;;;;:::o;78690:194::-;78756:17;78803:10;78790:9;:23;78786:62;;78822:26;;-1:-1:-1;;;78822:26:0;;78838:9;78822:26;;;9184:25:1;9157:18;;78822:26:0;9038:177:1;78786:62:0;-1:-1:-1;78866:10:0;78690:194::o;79270:417::-;79425:15;79443:8;-1:-1:-1;;;;;79443:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79425:36;-1:-1:-1;;;;;;79476:21:0;;79472:54;;79506:20;;-1:-1:-1;;;79506:20:0;;;;;;;;;;;79472:54;79603:76;-1:-1:-1;;;;;79603:32:0;;79636:10;79656:8;79667:11;79603:32;:76::i;43424:162::-;43534:43;;-1:-1:-1;;;;;32453:32:1;;;43534:43:0;;;32435:51:1;32502:18;;;32495:34;;;43507:71:0;;43527:5;;43549:14;;;;;32408:18:1;;43534:43:0;32261:274:1;43507:71:0;43424:162;;;:::o;46235:638::-;46659:23;46685:33;-1:-1:-1;;;;;46685:27:0;;46713:4;46685:27;:33::i;:::-;46659:59;;46733:10;:17;46754:1;46733:22;;:57;;;;;46771:10;46760:30;;;;;;;;;;;;:::i;:::-;46759:31;46733:57;46729:137;;;46814:40;;-1:-1:-1;;;46814:40:0;;-1:-1:-1;;;;;2696:32:1;;46814:40:0;;;2678:51:1;2651:18;;46814:40:0;2532:203:1;28091:153:0;28166:12;28198:38;28220:6;28228:4;28234:1;28166:12;28824;28838:23;28865:6;-1:-1:-1;;;;;28865:11:0;28884:5;28891:4;28865:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28823:73;;;;28914:55;28941:6;28949:7;28958:10;28914:26;:55::i;:::-;28907:62;28579:398;-1:-1:-1;;;;;;28579:398:0:o;30055:597::-;30203:12;30233:7;30228:417;;30257:19;30265:10;30257:7;:19::i;:::-;30228:417;;;30485:17;;:22;:49;;;;-1:-1:-1;;;;;;30511:18:0;;;:23;30485:49;30481:121;;;30562:24;;-1:-1:-1;;;30562:24:0;;-1:-1:-1;;;;;2696:32:1;;30562:24:0;;;2678:51:1;2651:18;;30562:24:0;2532:203:1;30481:121:0;-1:-1:-1;30623:10:0;30616:17;;31205:528;31338:17;;:21;31334:392;;31570:10;31564:17;31627:15;31614:10;31610:2;31606:19;31599:44;31334:392;31697:17;;-1:-1:-1;;;31697:17:0;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:158:1:-;76:5;121:3;112:6;107:3;103:16;99:26;96:46;;;138:1;135;128:12;96:46;-1:-1:-1;160:6:1;14:158;-1:-1:-1;14:158:1:o;177:360::-;265:6;318:2;306:9;297:7;293:23;289:32;286:52;;;334:1;331;324:12;286:52;374:9;361:23;-1:-1:-1;;;;;399:6:1;396:30;393:50;;;439:1;436;429:12;393:50;462:69;523:7;514:6;503:9;499:22;462:69;:::i;696:250::-;781:1;791:113;805:6;802:1;799:13;791:113;;;881:11;;;875:18;862:11;;;855:39;827:2;820:10;791:113;;;-1:-1:-1;;938:1:1;920:16;;913:27;696:250::o;951:271::-;993:3;1031:5;1025:12;1058:6;1053:3;1046:19;1074:76;1143:6;1136:4;1131:3;1127:14;1120:4;1113:5;1109:16;1074:76;:::i;:::-;1204:2;1183:15;-1:-1:-1;;1179:29:1;1170:39;;;;1211:4;1166:50;;951:271;-1:-1:-1;;951:271:1:o;1227:1300::-;616:12;;604:25;;678:4;667:16;;;661:23;645:14;;;638:47;1593:4;1641:3;1626:19;;1735:3;1730:2;1719:9;1715:18;1708:31;1759:6;1794;1788:13;1825:6;1817;1810:22;1863:3;1852:9;1848:19;1841:26;;1926:3;1916:6;1913:1;1909:14;1898:9;1894:30;1890:40;1876:54;;1965:4;1957:6;1953:17;1988:1;1998:437;2012:6;2009:1;2006:13;1998:437;;;2105:3;2101:8;2089:9;2081:6;2077:22;2073:37;2068:3;2061:50;2140:6;2134:13;2181:2;2175:9;2167:6;2160:25;2232:4;2228:2;2224:13;2218:20;2198:40;;2277:2;2270:4;2262:6;2258:17;2251:29;2303:48;2347:2;2339:6;2335:15;2321:12;2303:48;:::i;:::-;2293:58;-1:-1:-1;;2386:4:1;2411:14;;;;2374:17;;;;;2034:1;2027:9;1998:437;;;-1:-1:-1;;616:12:1;;2517:2;2502:18;;604:25;-1:-1:-1;;678:4:1;667:16;;661:23;645:14;;;638:47;2452:6;-1:-1:-1;2467:54:1;542:149;2740:154;2799:5;2844:2;2835:6;2830:3;2826:16;2822:25;2819:45;;;2860:1;2857;2850:12;2899:347;2950:8;2960:6;3014:3;3007:4;2999:6;2995:17;2991:27;2981:55;;3032:1;3029;3022:12;2981:55;-1:-1:-1;3055:20:1;;-1:-1:-1;;;;;3087:30:1;;3084:50;;;3130:1;3127;3120:12;3084:50;3167:4;3159:6;3155:17;3143:29;;3219:3;3212:4;3203:6;3195;3191:19;3187:30;3184:39;3181:59;;;3236:1;3233;3226:12;3181:59;2899:347;;;;;:::o;3251:131::-;-1:-1:-1;;;;;3326:31:1;;3316:42;;3306:70;;3372:1;3369;3362:12;3387:1097;3532:6;3540;3548;3556;3564;3572;3580;3633:3;3621:9;3612:7;3608:23;3604:33;3601:53;;;3650:1;3647;3640:12;3601:53;3673;3718:7;3707:9;3673:53;:::i;:::-;3663:63;-1:-1:-1;3795:2:1;3780:18;;3767:32;;-1:-1:-1;3874:3:1;3859:19;;3846:33;-1:-1:-1;;;;;3891:30:1;;3888:50;;;3934:1;3931;3924:12;3888:50;3973:58;4023:7;4014:6;4003:9;3999:22;3973:58;:::i;:::-;4050:8;;-1:-1:-1;3947:84:1;-1:-1:-1;;4137:3:1;4122:19;;4109:33;4151;4109;4151;:::i;:::-;4203:7;-1:-1:-1;4263:3:1;4248:19;;4235:33;-1:-1:-1;;;;;4280:32:1;;4277:52;;;4325:1;4322;4315:12;4277:52;4364:60;4416:7;4405:8;4394:9;4390:24;4364:60;:::i;:::-;3387:1097;;;;-1:-1:-1;3387:1097:1;;-1:-1:-1;3387:1097:1;;;;4338:86;;-1:-1:-1;;;3387:1097:1:o;5282:163::-;5349:20;;5409:10;5398:22;;5388:33;;5378:61;;5435:1;5432;5425:12;5378:61;5282:163;;;:::o;5450:298::-;5517:6;5525;5578:2;5566:9;5557:7;5553:23;5549:32;5546:52;;;5594:1;5591;5584:12;5546:52;5617:28;5635:9;5617:28;:::i;:::-;5607:38;5714:2;5699:18;;;;5686:32;;-1:-1:-1;;;5450:298:1:o;5753:118::-;5839:5;5832:13;5825:21;5818:5;5815:32;5805:60;;5861:1;5858;5851:12;5876:489;5970:6;5978;6031:2;6019:9;6010:7;6006:23;6002:32;5999:52;;;6047:1;6044;6037:12;5999:52;6087:9;6074:23;-1:-1:-1;;;;;6112:6:1;6109:30;6106:50;;;6152:1;6149;6142:12;6106:50;6175:69;6236:7;6227:6;6216:9;6212:22;6175:69;:::i;:::-;6165:79;;;6294:2;6283:9;6279:18;6266:32;6307:28;6329:5;6307:28;:::i;:::-;6354:5;6344:15;;;5876:489;;;;;:::o;6370:261::-;616:12;;604:25;;678:4;667:16;;;661:23;645:14;;;638:47;6568:2;6553:18;;6580:45;542:149;6636:159;6703:20;;6763:6;6752:18;;6742:29;;6732:57;;6785:1;6782;6775:12;6800:256;6866:6;6874;6927:2;6915:9;6906:7;6902:23;6898:32;6895:52;;;6943:1;6940;6933:12;6895:52;6966:28;6984:9;6966:28;:::i;:::-;6956:38;;7013:37;7046:2;7035:9;7031:18;7013:37;:::i;:::-;7003:47;;6800:256;;;;;:::o;7061:218::-;7208:2;7197:9;7190:21;7171:4;7228:45;7269:2;7258:9;7254:18;7246:6;7228:45;:::i;7715:247::-;7774:6;7827:2;7815:9;7806:7;7802:23;7798:32;7795:52;;;7843:1;7840;7833:12;7795:52;7882:9;7869:23;7901:31;7926:5;7901:31;:::i;8172:672::-;8288:6;8296;8304;8312;8365:3;8353:9;8344:7;8340:23;8336:33;8333:53;;;8382:1;8379;8372:12;8333:53;8405;8450:7;8439:9;8405:53;:::i;:::-;8395:63;;8509:2;8498:9;8494:18;8481:32;-1:-1:-1;;;;;8528:6:1;8525:30;8522:50;;;8568:1;8565;8558:12;8522:50;8607:58;8657:7;8648:6;8637:9;8633:22;8607:58;:::i;:::-;8684:8;;-1:-1:-1;8581:84:1;-1:-1:-1;;8769:3:1;8754:19;;8741:33;8783:31;8741:33;8783:31;:::i;:::-;8172:672;;;;-1:-1:-1;8172:672:1;;-1:-1:-1;;8172:672:1:o;9220:395::-;9311:8;9321:6;9375:3;9368:4;9360:6;9356:17;9352:27;9342:55;;9393:1;9390;9383:12;9342:55;-1:-1:-1;9416:20:1;;-1:-1:-1;;;;;9448:30:1;;9445:50;;;9491:1;9488;9481:12;9445:50;9528:4;9520:6;9516:17;9504:29;;9588:3;9581:4;9571:6;9568:1;9564:14;9556:6;9552:27;9548:38;9545:47;9542:67;;;9605:1;9602;9595:12;9620:503;9744:6;9752;9805:2;9793:9;9784:7;9780:23;9776:32;9773:52;;;9821:1;9818;9811:12;9773:52;9861:9;9848:23;-1:-1:-1;;;;;9886:6:1;9883:30;9880:50;;;9926:1;9923;9916:12;9880:50;9965:98;10055:7;10046:6;10035:9;10031:22;9965:98;:::i;:::-;10082:8;;9939:124;;-1:-1:-1;9620:503:1;-1:-1:-1;;;;9620:503:1:o;10128:184::-;10186:6;10239:2;10227:9;10218:7;10214:23;10210:32;10207:52;;;10255:1;10252;10245:12;10207:52;10278:28;10296:9;10278:28;:::i;10499:553::-;10585:6;10593;10601;10609;10662:2;10650:9;10641:7;10637:23;10633:32;10630:52;;;10678:1;10675;10668:12;10630:52;10701:28;10719:9;10701:28;:::i;:::-;10691:38;;10748:37;10781:2;10770:9;10766:18;10748:37;:::i;:::-;10738:47;;10836:2;10825:9;10821:18;10808:32;-1:-1:-1;;;;;10855:6:1;10852:30;10849:50;;;10895:1;10892;10885:12;10849:50;10934:58;10984:7;10975:6;10964:9;10960:22;10934:58;:::i;:::-;10499:553;;;;-1:-1:-1;11011:8:1;-1:-1:-1;;;;10499:553:1:o;11560:659::-;11700:6;11708;11716;11760:9;11751:7;11747:23;11790:3;11786:2;11782:12;11779:32;;;11807:1;11804;11797:12;11779:32;11847:9;11834:23;-1:-1:-1;;;;;11872:6:1;11869:30;11866:50;;;11912:1;11909;11902:12;11866:50;11935:69;11996:7;11987:6;11976:9;11972:22;11935:69;:::i;:::-;11925:79;-1:-1:-1;;12038:2:1;-1:-1:-1;;12020:16:1;;12016:25;12013:45;;;12054:1;12051;12044:12;12013:45;;12092:2;12081:9;12077:18;12067:28;;12145:2;12134:9;12130:18;12117:32;12158:31;12183:5;12158:31;:::i;:::-;12208:5;12198:15;;;11560:659;;;;;:::o;12224:617::-;12472:4;12514:3;12503:9;12499:19;12491:27;;12551:6;12545:13;12534:9;12527:32;-1:-1:-1;;;;;12619:4:1;12611:6;12607:17;12601:24;12597:49;12590:4;12579:9;12575:20;12568:79;12694:4;12686:6;12682:17;12676:24;12709:62;12765:4;12754:9;12750:20;12736:12;616;;604:25;;678:4;667:16;;;661:23;645:14;;638:47;542:149;12709:62;-1:-1:-1;616:12:1;;12830:3;12815:19;;604:25;678:4;667:16;;661:23;645:14;;;638:47;12780:55;542:149;12846:238;12933:6;12986:2;12974:9;12965:7;12961:23;12957:32;12954:52;;;13002:1;12999;12992:12;12954:52;13025:53;13070:7;13059:9;13025:53;:::i;13089:127::-;13150:10;13145:3;13141:20;13138:1;13131:31;13181:4;13178:1;13171:15;13205:4;13202:1;13195:15;13489:380;13568:1;13564:12;;;;13611;;;13632:61;;13686:4;13678:6;13674:17;13664:27;;13632:61;13739:2;13731:6;13728:14;13708:18;13705:38;13702:161;;13785:10;13780:3;13776:20;13773:1;13766:31;13820:4;13817:1;13810:15;13848:4;13845:1;13838:15;13874:253;13946:2;13940:9;13988:4;13976:17;;-1:-1:-1;;;;;14008:34:1;;14044:22;;;14005:62;14002:88;;;14070:18;;:::i;:::-;14106:2;14099:22;13874:253;:::o;14132:251::-;14204:2;14198:9;;;14234:15;;-1:-1:-1;;;;;14264:34:1;;14300:22;;;14261:62;14258:88;;;14326:18;;:::i;14388:275::-;14459:2;14453:9;14524:2;14505:13;;-1:-1:-1;;14501:27:1;14489:40;;-1:-1:-1;;;;;14544:34:1;;14580:22;;;14541:62;14538:88;;;14606:18;;:::i;:::-;14642:2;14635:22;14388:275;;-1:-1:-1;14388:275:1:o;14668:186::-;14716:4;-1:-1:-1;;;;;14741:6:1;14738:30;14735:56;;;14771:18;;:::i;:::-;-1:-1:-1;14837:2:1;14816:15;-1:-1:-1;;14812:29:1;14843:4;14808:40;;14668:186::o;14859:1782::-;15049:9;-1:-1:-1;;;;;15079:6:1;15076:30;15073:56;;;15109:18;;:::i;:::-;15155:6;15152:1;15148:14;15182:30;15206:4;15202:2;15198:13;15182:30;:::i;:::-;15246:19;;;15318:14;;;;15290:4;15281:14;;;15355;15344:26;;15341:46;;;15383:1;15380;15373:12;15341:46;15407:5;15421:1187;15437:6;15432:3;15429:15;15421:1187;;;15525:3;15512:17;-1:-1:-1;;;;;15548:11:1;15545:35;15542:55;;;15593:1;15590;15583:12;15542:55;15620:23;;15688:4;15667:14;15663:23;;;15659:34;15656:54;;;15706:1;15703;15696:12;15656:54;15738:22;;:::i;:::-;15789:21;15807:2;15789:21;:::i;:::-;15780:7;15773:38;15851:32;15877:4;15873:2;15869:13;15851:32;:::i;:::-;15844:4;15835:7;15831:18;15824:60;15932:2;15928;15924:11;15911:25;-1:-1:-1;;;;;15955:6:1;15952:30;15949:50;;;15995:1;15992;15985:12;15949:50;16022:15;;;;;16079:14;16072:4;16064:13;;16060:34;16050:62;;16108:1;16105;16098:12;16050:62;16154:2;16141:16;16185:54;16201:37;16229:8;16201:37;:::i;:::-;16185:54;:::i;:::-;16268:8;16259:7;16252:25;16326:14;16319:4;16308:8;16304:2;16300:17;16296:28;16293:48;16290:68;;;16354:1;16351;16344:12;16290:68;16419:8;16412:4;16408:2;16404:13;16397:4;16388:7;16384:18;16371:57;16483:1;16476:4;16465:8;16456:7;16452:22;16448:33;16441:44;16523:7;16518:2;16509:7;16505:16;16498:33;;;16556:7;16551:3;16544:20;;;16593:4;16588:3;16584:14;16577:21;;15463:4;15458:3;15454:14;15447:21;;15421:1187;;;-1:-1:-1;16630:5:1;14859:1782;-1:-1:-1;;;;;14859:1782:1:o;16646:331::-;16751:9;16762;16804:8;16792:10;16789:24;16786:44;;;16826:1;16823;16816:12;16786:44;16855:6;16845:8;16842:20;16839:40;;;16875:1;16872;16865:12;16839:40;-1:-1:-1;;16901:23:1;;;16946:25;;;;;-1:-1:-1;16646:331:1:o;16982:476::-;17173:3;17211:6;17205:13;17227:66;17286:6;17281:3;17274:4;17266:6;17262:17;17227:66;:::i;:::-;17315:16;;17368:6;17360;17315:16;17340:35;17432:1;17394:18;;17421:13;;;-1:-1:-1;17394:18:1;;16982:476;-1:-1:-1;;;16982:476:1:o;17463:266::-;17551:6;17546:3;17539:19;17603:6;17596:5;17589:4;17584:3;17580:14;17567:43;-1:-1:-1;17655:1:1;17630:16;;;17648:4;17626:27;;;17619:38;;;;17711:2;17690:15;;;-1:-1:-1;;17686:29:1;17677:39;;;17673:50;;17463:266::o;17734:244::-;17891:2;17880:9;17873:21;17854:4;17911:61;17968:2;17957:9;17953:18;17945:6;17937;17911:61;:::i;17983:127::-;18044:10;18039:3;18035:20;18032:1;18025:31;18075:4;18072:1;18065:15;18099:4;18096:1;18089:15;18115:331;18214:4;18272:11;18259:25;18366:3;18362:8;18351;18335:14;18331:29;18327:44;18307:18;18303:69;18293:97;;18386:1;18383;18376:12;18293:97;18407:33;;;;;18115:331;-1:-1:-1;;18115:331:1:o;18451:521::-;18528:4;18534:6;18594:11;18581:25;18688:2;18684:7;18673:8;18657:14;18653:29;18649:43;18629:18;18625:68;18615:96;;18707:1;18704;18697:12;18615:96;18734:33;;18786:20;;;-1:-1:-1;;;;;;18818:30:1;;18815:50;;;18861:1;18858;18851:12;18815:50;18894:4;18882:17;;-1:-1:-1;18925:14:1;18921:27;;;18911:38;;18908:58;;;18962:1;18959;18952:12;18977:129;-1:-1:-1;;;;;19055:5:1;19051:30;19044:5;19041:41;19031:69;;19096:1;19093;19086:12;19111:1048;19493:10;19466:25;19484:6;19466:25;:::i;:::-;19462:42;19444:61;;19571:4;19559:17;;;19546:31;19593:20;;;19586:35;19425:4;19670;19658:17;;19645:31;19685:32;19645:31;19685:32;:::i;:::-;-1:-1:-1;;;;;19759:7:1;19755:32;19748:4;19737:9;19733:20;19726:62;;19824:6;19819:2;19808:9;19804:18;19797:34;19868:3;19862;19851:9;19847:19;19840:32;19895:62;19952:3;19941:9;19937:19;19929:6;19921;19895:62;:::i;:::-;-1:-1:-1;;;;;19994:32:1;;20014:3;19973:19;;19966:61;20064:22;;;20058:3;20043:19;;20036:51;20104:49;20068:6;20138;20130;20104:49;:::i;:::-;20096:57;19111:1048;-1:-1:-1;;;;;;;;;;19111:1048:1:o;20164:667::-;20243:6;20296:2;20284:9;20275:7;20271:23;20267:32;20264:52;;;20312:1;20309;20302:12;20264:52;20345:9;20339:16;-1:-1:-1;;;;;20370:6:1;20367:30;20364:50;;;20410:1;20407;20400:12;20364:50;20433:22;;20486:4;20478:13;;20474:27;-1:-1:-1;20464:55:1;;20515:1;20512;20505:12;20464:55;20548:2;20542:9;20573:52;20589:35;20617:6;20589:35;:::i;20573:52::-;20648:6;20641:5;20634:21;20696:7;20691:2;20682:6;20678:2;20674:15;20670:24;20667:37;20664:57;;;20717:1;20714;20707:12;20664:57;20730:71;20794:6;20789:2;20782:5;20778:14;20773:2;20769;20765:11;20730:71;:::i;20836:491::-;20927:6;20987:2;20975:9;20966:7;20962:23;20958:32;21002:2;20999:22;;;21017:1;21014;21007:12;20999:22;-1:-1:-1;21059:22:1;;:::i;:::-;21126:23;;21158:22;;21253:2;21238:18;;;21225:32;21273:14;;;21266:31;;;;-1:-1:-1;21165:5:1;20836:491;-1:-1:-1;20836:491:1:o;22121:245::-;22179:6;22232:2;22220:9;22211:7;22207:23;22203:32;22200:52;;;22248:1;22245;22238:12;22200:52;22287:9;22274:23;22306:30;22330:5;22306:30;:::i;22371:479::-;22638:1;22634;22629:3;22625:11;22621:19;22613:6;22609:32;22598:9;22591:51;22678:6;22673:2;22662:9;22658:18;22651:34;22733:6;22725;22721:19;22716:2;22705:9;22701:18;22694:47;22777:3;22772:2;22761:9;22757:18;22750:31;22572:4;22798:46;22839:3;22828:9;22824:19;22816:6;22798:46;:::i;23123:379::-;23316:2;23305:9;23298:21;23279:4;23342:45;23383:2;23372:9;23368:18;23360:6;23342:45;:::i;:::-;23435:9;23427:6;23423:22;23418:2;23407:9;23403:18;23396:50;23463:33;23489:6;23481;23463:33;:::i;23507:245::-;23574:6;23627:2;23615:9;23606:7;23602:23;23598:32;23595:52;;;23643:1;23640;23633:12;23595:52;23675:9;23669:16;23694:28;23716:5;23694:28;:::i;23757:895::-;23984:2;23973:9;23966:21;24042:10;24033:6;24027:13;24023:30;24018:2;24007:9;24003:18;23996:58;24108:4;24100:6;24096:17;24090:24;24085:2;24074:9;24070:18;24063:52;23947:4;24162:2;24154:6;24150:15;24144:22;24203:4;24197:3;24186:9;24182:19;24175:33;24231:52;24278:3;24267:9;24263:19;24249:12;24231:52;:::i;:::-;24217:66;;24332:2;24324:6;24320:15;24314:22;24406:2;24402:7;24390:9;24382:6;24378:22;24374:36;24367:4;24356:9;24352:20;24345:66;24434:41;24468:6;24452:14;24434:41;:::i;:::-;24544:3;24532:16;;;;24526:23;24519:31;24512:39;24506:3;24491:19;;24484:68;-1:-1:-1;;;;;;;;24613:32:1;;;;24606:4;24591:20;;;24584:62;24420:55;23757:895::o;24657:388::-;24727:5;24775:4;24763:9;24758:3;24754:19;24750:30;24747:50;;;24793:1;24790;24783:12;24747:50;24815:22;;:::i;:::-;24882:16;;24907:22;;24995:2;24980:18;;;24974:25;25015:14;;;25008:31;;;;-1:-1:-1;24806:31:1;24657:388;-1:-1:-1;24657:388:1:o;25050:261::-;25152:6;25205:2;25193:9;25184:7;25180:23;25176:32;25173:52;;;25221:1;25218;25211:12;25173:52;25244:61;25297:7;25286:9;25244:61;:::i;25441:517::-;25542:2;25537:3;25534:11;25531:421;;;25578:5;25575:1;25568:16;25622:4;25619:1;25609:18;25692:2;25680:10;25676:19;25673:1;25669:27;25663:4;25659:38;25728:4;25716:10;25713:20;25710:47;;;-1:-1:-1;25751:4:1;25710:47;25806:2;25801:3;25797:12;25794:1;25790:20;25784:4;25780:31;25770:41;;25861:81;25879:2;25872:5;25869:13;25861:81;;;25938:1;25924:16;;25905:1;25894:13;25861:81;;26134:1295;26258:3;26252:10;-1:-1:-1;;;;;26277:6:1;26274:30;26271:56;;;26307:18;;:::i;:::-;26336:96;26425:6;26385:38;26417:4;26411:11;26385:38;:::i;:::-;26379:4;26336:96;:::i;:::-;26481:4;26512:2;26501:14;;26529:1;26524:648;;;;27216:1;27233:6;27230:89;;;-1:-1:-1;27285:19:1;;;27279:26;27230:89;-1:-1:-1;;26091:1:1;26087:11;;;26083:24;26079:29;26069:40;26115:1;26111:11;;;26066:57;27332:81;;26494:929;;26524:648;25388:1;25381:14;;;25425:4;25412:18;;-1:-1:-1;;26560:20:1;;;26677:222;26691:7;26688:1;26685:14;26677:222;;;26773:19;;;26767:26;26752:42;;26880:4;26865:20;;;;26833:1;26821:14;;;;26707:12;26677:222;;;26681:3;26927:6;26918:7;26915:19;26912:201;;;26988:19;;;26982:26;-1:-1:-1;;27071:1:1;27067:14;;;27083:3;27063:24;27059:37;27055:42;27040:58;27025:74;;26912:201;-1:-1:-1;;;;27159:1:1;27143:14;;;27139:22;27126:36;;-1:-1:-1;26134:1295:1:o;27434:1097::-;27648:4;27696:2;27685:9;27681:18;27726:2;27715:9;27708:21;27749:6;27784;27778:13;27815:6;27807;27800:22;27853:2;27842:9;27838:18;27831:25;;27915:2;27905:6;27902:1;27898:14;27887:9;27883:30;27879:39;27865:53;;27953:2;27945:6;27941:15;27974:1;27984:518;27998:6;27995:1;27992:13;27984:518;;;28091:2;28087:7;28075:9;28067:6;28063:22;28059:36;28054:3;28047:49;28125:6;28119:13;28175:10;28170:2;28164:9;28160:26;28152:6;28145:42;28248:6;28242:2;28238;28234:11;28228:18;28224:31;28219:2;28211:6;28207:15;28200:56;28303:2;28299;28295:11;28289:18;28269:38;;28344:4;28339:2;28331:6;28327:15;28320:29;28372:50;28416:4;28408:6;28404:17;28390:12;28372:50;:::i;:::-;28362:60;-1:-1:-1;;28457:2:1;28480:12;;;;28445:15;;;;;28020:1;28013:9;27984:518;;;-1:-1:-1;28519:6:1;;27434:1097;-1:-1:-1;;;;;;27434:1097:1:o;28536:564::-;28642:6;28702:3;28690:9;28681:7;28677:23;28673:33;28718:2;28715:22;;;28733:1;28730;28723:12;28715:22;-1:-1:-1;28775:22:1;;:::i;:::-;28826:9;28820:16;28813:5;28806:31;28882:2;28871:9;28867:18;28861:25;28895:32;28919:7;28895:32;:::i;:::-;28954:2;28943:14;;28936:31;28999:70;29061:7;29056:2;29041:18;;28999:70;:::i;:::-;28994:2;28983:14;;28976:94;28987:5;28536:564;-1:-1:-1;;;28536:564:1:o;29105:217::-;29145:1;29171;29161:132;;29215:10;29210:3;29206:20;29203:1;29196:31;29250:4;29247:1;29240:15;29278:4;29275:1;29268:15;29161:132;-1:-1:-1;29307:9:1;;29105:217::o;29327:265::-;29400:9;;;29431;;29448:15;;;29442:22;;29428:37;29418:168;;29508:10;29503:3;29499:20;29496:1;29489:31;29543:4;29540:1;29533:15;29571:4;29568:1;29561:15;29597:255;29717:19;;29756:2;29748:11;;29745:101;;;-1:-1:-1;;29817:2:1;29813:12;;;29810:1;29806:20;29802:33;29791:45;29597:255;;;;:::o;29857:362::-;29977:19;;-1:-1:-1;;;;;;30014:37:1;;;30071:1;30063:10;;30060:153;;;-1:-1:-1;;;;;;30132:1:1;30128:11;;;30125:1;30121:19;30117:54;;;30109:63;;30105:98;;-1:-1:-1;30060:153:1;;29857:362;;;;:::o;30224:568::-;-1:-1:-1;;;;;30489:3:1;30485:28;30476:6;30471:3;30467:16;30463:51;30458:3;30451:64;30575:10;30570:3;30566:20;30557:6;30552:3;30548:16;30544:43;30540:1;30535:3;30531:11;30524:64;30618:6;30613:2;30608:3;30604:12;30597:28;30433:3;30654:6;30648:13;30670:75;30738:6;30733:2;30728:3;30724:12;30717:4;30709:6;30705:17;30670:75;:::i;:::-;30765:16;;;;30783:2;30761:25;;30224:568;-1:-1:-1;;;;;30224:568:1:o;31092:532::-;31333:6;31328:3;31321:19;-1:-1:-1;;;;;31396:3:1;31392:28;31383:6;31378:3;31374:16;31370:51;31365:2;31360:3;31356:12;31349:73;31452:6;31447:2;31442:3;31438:12;31431:28;31303:3;31488:6;31482:13;31504:73;31570:6;31565:2;31560:3;31556:12;31551:2;31543:6;31539:15;31504:73;:::i;:::-;31597:16;;;;31615:2;31593:25;;31092:532;-1:-1:-1;;;;;31092:532:1:o;32005:251::-;32075:6;32128:2;32116:9;32107:7;32103:23;32099:32;32096:52;;;32144:1;32141;32134:12;32096:52;32176:9;32170:16;32195:31;32220:5;32195:31;:::i;32540:287::-;32669:3;32707:6;32701:13;32723:66;32782:6;32777:3;32770:4;32762:6;32758:17;32723:66;:::i
Swarm Source
ipfs://5c6f631f1c5a47785d55b30d150736973ffc94eed8f3b5c3c27743d9b517abeb
Loading...
Loading
Loading...
Loading
Net Worth in USD
$8,575.99
Net Worth in ETH
4.388928
Token Allocations
PLUME
100.00%
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ETH | 100.00% | $0.009016 | 951,223.5776 | $8,575.99 |
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.