Overview
S Balance
0 S
S Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
EXFateAdventureToken
Compiler Version
v0.8.28+commit.7893614a
Contract Source Code (Solidity)
/** *Submitted for verification at SonicScan.org on 2024-12-30 */ // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } } // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; /** * @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); } } // File: @openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-20 standard as defined in the ERC. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); } // File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; /** * @dev Interface for the optional metadata functions from the ERC-20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File: @openzeppelin/contracts/interfaces/draft-IERC6093.sol // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/draft-IERC6093.sol) pragma solidity ^0.8.20; /** * @dev Standard ERC-20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC-721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC-1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); } // File: @openzeppelin/contracts/token/ERC20/ERC20.sol // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.20; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC-20 * applications. */ abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors { mapping(address account => uint256) private _balances; mapping(address account => mapping(address spender => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the default value returned by this function, unless * it's overridden. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `value`. */ function transfer(address to, uint256 value) public virtual returns (bool) { address owner = _msgSender(); _transfer(owner, to, value); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 value) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, value); return true; } /** * @dev See {IERC20-transferFrom}. * * Skips emitting an {Approval} event indicating an allowance update. This is not * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve]. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `value`. * - the caller must have allowance for ``from``'s tokens of at least * `value`. */ function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, value); _transfer(from, to, value); return true; } /** * @dev Moves a `value` amount of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _transfer(address from, address to, uint256 value) internal { if (from == address(0)) { revert ERC20InvalidSender(address(0)); } if (to == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(from, to, value); } /** * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from` * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding * this function. * * Emits a {Transfer} event. */ function _update(address from, address to, uint256 value) internal virtual { if (from == address(0)) { // Overflow check required: The rest of the code assumes that totalSupply never overflows _totalSupply += value; } else { uint256 fromBalance = _balances[from]; if (fromBalance < value) { revert ERC20InsufficientBalance(from, fromBalance, value); } unchecked { // Overflow not possible: value <= fromBalance <= totalSupply. _balances[from] = fromBalance - value; } } if (to == address(0)) { unchecked { // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply. _totalSupply -= value; } } else { unchecked { // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256. _balances[to] += value; } } emit Transfer(from, to, value); } /** * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0). * Relies on the `_update` mechanism * * Emits a {Transfer} event with `from` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _mint(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(address(0), account, value); } /** * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply. * Relies on the `_update` mechanism. * * Emits a {Transfer} event with `to` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead */ function _burn(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidSender(address(0)); } _update(account, address(0), value); } /** * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. * * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. */ function _approve(address owner, address spender, uint256 value) internal { _approve(owner, spender, value, true); } /** * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event. * * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any * `Approval` event during `transferFrom` operations. * * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to * true using the following override: * * ```solidity * function _approve(address owner, address spender, uint256 value, bool) internal virtual override { * super._approve(owner, spender, value, true); * } * ``` * * Requirements are the same as {_approve}. */ function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual { if (owner == address(0)) { revert ERC20InvalidApprover(address(0)); } if (spender == address(0)) { revert ERC20InvalidSpender(address(0)); } _allowances[owner][spender] = value; if (emitEvent) { emit Approval(owner, spender, value); } } /** * @dev Updates `owner` s allowance for `spender` based on spent `value`. * * Does not update the allowance value in case of infinite allowance. * Revert if not enough allowance is available. * * Does not emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 value) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { if (currentAllowance < value) { revert ERC20InsufficientAllowance(spender, currentAllowance, value); } unchecked { _approve(owner, spender, currentAllowance - value, false); } } } } // File: @openzeppelin/contracts/interfaces/IERC20.sol // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol) pragma solidity ^0.8.20; // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/interfaces/IERC165.sol // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol) pragma solidity ^0.8.20; // File: @openzeppelin/contracts/interfaces/IERC1363.sol // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol) pragma solidity ^0.8.20; /** * @title IERC1363 * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363]. * * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction. */ interface IERC1363 is IERC20, IERC165 { /* * Note: the ERC-165 identifier for this interface is 0xb0202a11. * 0xb0202a11 === * bytes4(keccak256('transferAndCall(address,uint256)')) ^ * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^ * bytes4(keccak256('approveAndCall(address,uint256)')) ^ * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) */ /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @param data Additional data with no specified format, sent in call to `spender`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool); } // File: @openzeppelin/contracts/utils/Errors.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol) pragma solidity ^0.8.20; /** * @dev Collection of common custom errors used in multiple contracts * * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library. * It is recommended to avoid relying on the error API for critical functionality. * * _Available since v5.1._ */ library Errors { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error InsufficientBalance(uint256 balance, uint256 needed); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedCall(); /** * @dev The deployment failed. */ error FailedDeployment(); /** * @dev A necessary precompile is missing. */ error MissingPrecompile(address); } // File: @openzeppelin/contracts/utils/Address.sol // OpenZeppelin Contracts (last updated v5.1.0) (utils/Address.sol) pragma solidity ^0.8.20; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert Errors.InsufficientBalance(address(this).balance, amount); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert Errors.FailedCall(); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {Errors.FailedCall} error. * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert Errors.InsufficientBalance(address(this).balance, value); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case * of an unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {Errors.FailedCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}. */ function _revert(bytes memory returndata) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly ("memory-safe") { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert Errors.FailedCall(); } } } // File: @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; /** * @title SafeERC20 * @dev Wrappers around ERC-20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { /** * @dev An operation with an ERC-20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. * * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function * only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being * set here. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { safeTransfer(token, to, value); } else if (!token.transferAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferFromAndCallRelaxed( IERC1363 token, address from, address to, uint256 value, bytes memory data ) internal { if (to.code.length == 0) { safeTransferFrom(token, from, to, value); } else if (!token.transferFromAndCall(from, to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}. * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall} * once without retrying, and relies on the returned value to be true. * * Reverts if the returned value is other than `true`. */ function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { forceApprove(token, to, value); } else if (!token.approveAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements. */ function _callOptionalReturn(IERC20 token, bytes memory data) private { uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) // bubble errors if iszero(success) { let ptr := mload(0x40) returndatacopy(ptr, 0, returndatasize()) revert(ptr, returndatasize()) } returnSize := returndatasize() returnValue := mload(0) } if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { bool success; uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) returnSize := returndatasize() returnValue := mload(0) } return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1); } } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessageLibManager.sol pragma solidity >=0.8.0; struct SetConfigParam { uint32 eid; uint32 configType; bytes config; } interface IMessageLibManager { struct Timeout { address lib; uint256 expiry; } event LibraryRegistered(address newLib); event DefaultSendLibrarySet(uint32 eid, address newLib); event DefaultReceiveLibrarySet(uint32 eid, address newLib); event DefaultReceiveLibraryTimeoutSet(uint32 eid, address oldLib, uint256 expiry); event SendLibrarySet(address sender, uint32 eid, address newLib); event ReceiveLibrarySet(address receiver, uint32 eid, address newLib); event ReceiveLibraryTimeoutSet(address receiver, uint32 eid, address oldLib, uint256 timeout); function registerLibrary(address _lib) external; function isRegisteredLibrary(address _lib) external view returns (bool); function getRegisteredLibraries() external view returns (address[] memory); function setDefaultSendLibrary(uint32 _eid, address _newLib) external; function defaultSendLibrary(uint32 _eid) external view returns (address); function setDefaultReceiveLibrary(uint32 _eid, address _newLib, uint256 _gracePeriod) external; function defaultReceiveLibrary(uint32 _eid) external view returns (address); function setDefaultReceiveLibraryTimeout(uint32 _eid, address _lib, uint256 _expiry) external; function defaultReceiveLibraryTimeout(uint32 _eid) external view returns (address lib, uint256 expiry); function isSupportedEid(uint32 _eid) external view returns (bool); function isValidReceiveLibrary(address _receiver, uint32 _eid, address _lib) external view returns (bool); /// ------------------- OApp interfaces ------------------- function setSendLibrary(address _oapp, uint32 _eid, address _newLib) external; function getSendLibrary(address _sender, uint32 _eid) external view returns (address lib); function isDefaultSendLibrary(address _sender, uint32 _eid) external view returns (bool); function setReceiveLibrary(address _oapp, uint32 _eid, address _newLib, uint256 _gracePeriod) external; function getReceiveLibrary(address _receiver, uint32 _eid) external view returns (address lib, bool isDefault); function setReceiveLibraryTimeout(address _oapp, uint32 _eid, address _lib, uint256 _expiry) external; function receiveLibraryTimeout(address _receiver, uint32 _eid) external view returns (address lib, uint256 expiry); function setConfig(address _oapp, address _lib, SetConfigParam[] calldata _params) external; function getConfig( address _oapp, address _lib, uint32 _eid, uint32 _configType ) external view returns (bytes memory config); } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessagingComposer.sol pragma solidity >=0.8.0; interface IMessagingComposer { event ComposeSent(address from, address to, bytes32 guid, uint16 index, bytes message); event ComposeDelivered(address from, address to, bytes32 guid, uint16 index); event LzComposeAlert( address indexed from, address indexed to, address indexed executor, bytes32 guid, uint16 index, uint256 gas, uint256 value, bytes message, bytes extraData, bytes reason ); function composeQueue( address _from, address _to, bytes32 _guid, uint16 _index ) external view returns (bytes32 messageHash); function sendCompose(address _to, bytes32 _guid, uint16 _index, bytes calldata _message) external; function lzCompose( address _from, address _to, bytes32 _guid, uint16 _index, bytes calldata _message, bytes calldata _extraData ) external payable; } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessagingChannel.sol pragma solidity >=0.8.0; interface IMessagingChannel { event InboundNonceSkipped(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce); event PacketNilified(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash); event PacketBurnt(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash); function eid() external view returns (uint32); // this is an emergency function if a message cannot be verified for some reasons // required to provide _nextNonce to avoid race condition function skip(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce) external; function nilify(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external; function burn(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external; function nextGuid(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (bytes32); function inboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64); function outboundNonce(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (uint64); function inboundPayloadHash( address _receiver, uint32 _srcEid, bytes32 _sender, uint64 _nonce ) external view returns (bytes32); function lazyInboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64); } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessagingContext.sol pragma solidity >=0.8.0; interface IMessagingContext { function isSendingMessage() external view returns (bool); function getSendContext() external view returns (uint32 dstEid, address sender); } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol pragma solidity >=0.8.0; struct MessagingParams { uint32 dstEid; bytes32 receiver; bytes message; bytes options; bool payInLzToken; } struct MessagingReceipt { bytes32 guid; uint64 nonce; MessagingFee fee; } struct MessagingFee { uint256 nativeFee; uint256 lzTokenFee; } struct Origin { uint32 srcEid; bytes32 sender; uint64 nonce; } interface ILayerZeroEndpointV2 is IMessageLibManager, IMessagingComposer, IMessagingChannel, IMessagingContext { event PacketSent(bytes encodedPayload, bytes options, address sendLibrary); event PacketVerified(Origin origin, address receiver, bytes32 payloadHash); event PacketDelivered(Origin origin, address receiver); event LzReceiveAlert( address indexed receiver, address indexed executor, Origin origin, bytes32 guid, uint256 gas, uint256 value, bytes message, bytes extraData, bytes reason ); event LzTokenSet(address token); event DelegateSet(address sender, address delegate); function quote(MessagingParams calldata _params, address _sender) external view returns (MessagingFee memory); function send( MessagingParams calldata _params, address _refundAddress ) external payable returns (MessagingReceipt memory); function verify(Origin calldata _origin, address _receiver, bytes32 _payloadHash) external; function verifiable(Origin calldata _origin, address _receiver) external view returns (bool); function initializable(Origin calldata _origin, address _receiver) external view returns (bool); function lzReceive( Origin calldata _origin, address _receiver, bytes32 _guid, bytes calldata _message, bytes calldata _extraData ) external payable; // oapp can burn messages partially by calling this function with its own business logic if messages are verified in order function clear(address _oapp, Origin calldata _origin, bytes32 _guid, bytes calldata _message) external; function setLzToken(address _lzToken) external; function lzToken() external view returns (address); function nativeToken() external view returns (address); function setDelegate(address _delegate) external; } // File: @layerzerolabs/oapp-evm/contracts/oapp/interfaces/IOAppCore.sol pragma solidity ^0.8.20; /** * @title IOAppCore */ interface IOAppCore { // Custom error messages error OnlyPeer(uint32 eid, bytes32 sender); error NoPeer(uint32 eid); error InvalidEndpointCall(); error InvalidDelegate(); // Event emitted when a peer (OApp) is set for a corresponding endpoint event PeerSet(uint32 eid, bytes32 peer); /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol contract. * @return receiverVersion The version of the OAppReceiver.sol contract. */ function oAppVersion() external view returns (uint64 senderVersion, uint64 receiverVersion); /** * @notice Retrieves the LayerZero endpoint associated with the OApp. * @return iEndpoint The LayerZero endpoint as an interface. */ function endpoint() external view returns (ILayerZeroEndpointV2 iEndpoint); /** * @notice Retrieves the peer (OApp) associated with a corresponding endpoint. * @param _eid The endpoint ID. * @return peer The peer address (OApp instance) associated with the corresponding endpoint. */ function peers(uint32 _eid) external view returns (bytes32 peer); /** * @notice Sets the peer address (OApp instance) for a corresponding endpoint. * @param _eid The endpoint ID. * @param _peer The address of the peer to be associated with the corresponding endpoint. */ function setPeer(uint32 _eid, bytes32 _peer) external; /** * @notice Sets the delegate address for the OApp Core. * @param _delegate The address of the delegate to be set. */ function setDelegate(address _delegate) external; } // File: @layerzerolabs/oapp-evm/contracts/oapp/OAppCore.sol pragma solidity ^0.8.20; /** * @title OAppCore * @dev Abstract contract implementing the IOAppCore interface with basic OApp configurations. */ abstract contract OAppCore is IOAppCore, Ownable { // The LayerZero endpoint associated with the given OApp ILayerZeroEndpointV2 public immutable endpoint; // Mapping to store peers associated with corresponding endpoints mapping(uint32 eid => bytes32 peer) public peers; /** * @dev Constructor to initialize the OAppCore with the provided endpoint and delegate. * @param _endpoint The address of the LOCAL Layer Zero endpoint. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. * * @dev The delegate typically should be set as the owner of the contract. */ constructor(address _endpoint, address _delegate) { endpoint = ILayerZeroEndpointV2(_endpoint); if (_delegate == address(0)) revert InvalidDelegate(); endpoint.setDelegate(_delegate); } /** * @notice Sets the peer address (OApp instance) for a corresponding endpoint. * @param _eid The endpoint ID. * @param _peer The address of the peer to be associated with the corresponding endpoint. * * @dev Only the owner/admin of the OApp can call this function. * @dev Indicates that the peer is trusted to send LayerZero messages to this OApp. * @dev Set this to bytes32(0) to remove the peer address. * @dev Peer is a bytes32 to accommodate non-evm chains. */ function setPeer(uint32 _eid, bytes32 _peer) public virtual onlyOwner { _setPeer(_eid, _peer); } /** * @notice Sets the peer address (OApp instance) for a corresponding endpoint. * @param _eid The endpoint ID. * @param _peer The address of the peer to be associated with the corresponding endpoint. * * @dev Indicates that the peer is trusted to send LayerZero messages to this OApp. * @dev Set this to bytes32(0) to remove the peer address. * @dev Peer is a bytes32 to accommodate non-evm chains. */ function _setPeer(uint32 _eid, bytes32 _peer) internal virtual { peers[_eid] = _peer; emit PeerSet(_eid, _peer); } /** * @notice Internal function to get the peer address associated with a specific endpoint; reverts if NOT set. * ie. the peer is set to bytes32(0). * @param _eid The endpoint ID. * @return peer The address of the peer associated with the specified endpoint. */ function _getPeerOrRevert(uint32 _eid) internal view virtual returns (bytes32) { bytes32 peer = peers[_eid]; if (peer == bytes32(0)) revert NoPeer(_eid); return peer; } /** * @notice Sets the delegate address for the OApp. * @param _delegate The address of the delegate to be set. * * @dev Only the owner/admin of the OApp can call this function. * @dev Provides the ability for a delegate to set configs, on behalf of the OApp, directly on the Endpoint contract. */ function setDelegate(address _delegate) public onlyOwner { endpoint.setDelegate(_delegate); } } // File: @layerzerolabs/oapp-evm/contracts/oapp/OAppSender.sol pragma solidity ^0.8.20; /** * @title OAppSender * @dev Abstract contract implementing the OAppSender functionality for sending messages to a LayerZero endpoint. */ abstract contract OAppSender is OAppCore { using SafeERC20 for IERC20; // Custom error messages error NotEnoughNative(uint256 msgValue); error LzTokenUnavailable(); // @dev The version of the OAppSender implementation. // @dev Version is bumped when changes are made to this contract. uint64 internal constant SENDER_VERSION = 1; /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol contract. * @return receiverVersion The version of the OAppReceiver.sol contract. * * @dev Providing 0 as the default for OAppReceiver version. Indicates that the OAppReceiver is not implemented. * ie. this is a SEND only OApp. * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct versions */ function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) { return (SENDER_VERSION, 0); } /** * @dev Internal function to interact with the LayerZero EndpointV2.quote() for fee calculation. * @param _dstEid The destination endpoint ID. * @param _message The message payload. * @param _options Additional options for the message. * @param _payInLzToken Flag indicating whether to pay the fee in LZ tokens. * @return fee The calculated MessagingFee for the message. * - nativeFee: The native fee for the message. * - lzTokenFee: The LZ token fee for the message. */ function _quote( uint32 _dstEid, bytes memory _message, bytes memory _options, bool _payInLzToken ) internal view virtual returns (MessagingFee memory fee) { return endpoint.quote( MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _payInLzToken), address(this) ); } /** * @dev Internal function to interact with the LayerZero EndpointV2.send() for sending a message. * @param _dstEid The destination endpoint ID. * @param _message The message payload. * @param _options Additional options for the message. * @param _fee The calculated LayerZero fee for the message. * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. * @param _refundAddress The address to receive any excess fee values sent to the endpoint. * @return receipt The receipt for the sent message. * - guid: The unique identifier for the sent message. * - nonce: The nonce of the sent message. * - fee: The LayerZero fee incurred for the message. */ function _lzSend( uint32 _dstEid, bytes memory _message, bytes memory _options, MessagingFee memory _fee, address _refundAddress ) internal virtual returns (MessagingReceipt memory receipt) { // @dev Push corresponding fees to the endpoint, any excess is sent back to the _refundAddress from the endpoint. uint256 messageValue = _payNative(_fee.nativeFee); if (_fee.lzTokenFee > 0) _payLzToken(_fee.lzTokenFee); return // solhint-disable-next-line check-send-result endpoint.send{ value: messageValue }( MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _fee.lzTokenFee > 0), _refundAddress ); } /** * @dev Internal function to pay the native fee associated with the message. * @param _nativeFee The native fee to be paid. * @return nativeFee The amount of native currency paid. * * @dev If the OApp needs to initiate MULTIPLE LayerZero messages in a single transaction, * this will need to be overridden because msg.value would contain multiple lzFees. * @dev Should be overridden in the event the LayerZero endpoint requires a different native currency. * @dev Some EVMs use an ERC20 as a method for paying transactions/gasFees. * @dev The endpoint is EITHER/OR, ie. it will NOT support both types of native payment at a time. */ function _payNative(uint256 _nativeFee) internal virtual returns (uint256 nativeFee) { if (msg.value != _nativeFee) revert NotEnoughNative(msg.value); return _nativeFee; } /** * @dev Internal function to pay the LZ token fee associated with the message. * @param _lzTokenFee The LZ token fee to be paid. * * @dev If the caller is trying to pay in the specified lzToken, then the lzTokenFee is passed to the endpoint. * @dev Any excess sent, is passed back to the specified _refundAddress in the _lzSend(). */ function _payLzToken(uint256 _lzTokenFee) internal virtual { // @dev Cannot cache the token because it is not immutable in the endpoint. address lzToken = endpoint.lzToken(); if (lzToken == address(0)) revert LzTokenUnavailable(); // Pay LZ token fee by sending tokens to the endpoint. IERC20(lzToken).safeTransferFrom(msg.sender, address(endpoint), _lzTokenFee); } } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroReceiver.sol pragma solidity >=0.8.0; interface ILayerZeroReceiver { function allowInitializePath(Origin calldata _origin) external view returns (bool); function nextNonce(uint32 _eid, bytes32 _sender) external view returns (uint64); function lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) external payable; } // File: @layerzerolabs/oapp-evm/contracts/oapp/interfaces/IOAppReceiver.sol pragma solidity ^0.8.20; interface IOAppReceiver is ILayerZeroReceiver { /** * @notice Indicates whether an address is an approved composeMsg sender to the Endpoint. * @param _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @param _message The lzReceive payload. * @param _sender The sender address. * @return isSender Is a valid sender. * * @dev Applications can optionally choose to implement a separate composeMsg sender that is NOT the bridging layer. * @dev The default sender IS the OAppReceiver implementer. */ function isComposeMsgSender( Origin calldata _origin, bytes calldata _message, address _sender ) external view returns (bool isSender); } // File: @layerzerolabs/oapp-evm/contracts/oapp/OAppReceiver.sol pragma solidity ^0.8.20; /** * @title OAppReceiver * @dev Abstract contract implementing the ILayerZeroReceiver interface and extending OAppCore for OApp receivers. */ abstract contract OAppReceiver is IOAppReceiver, OAppCore { // Custom error message for when the caller is not the registered endpoint/ error OnlyEndpoint(address addr); // @dev The version of the OAppReceiver implementation. // @dev Version is bumped when changes are made to this contract. uint64 internal constant RECEIVER_VERSION = 2; /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol contract. * @return receiverVersion The version of the OAppReceiver.sol contract. * * @dev Providing 0 as the default for OAppSender version. Indicates that the OAppSender is not implemented. * ie. this is a RECEIVE only OApp. * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct versions. */ function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) { return (0, RECEIVER_VERSION); } /** * @notice Indicates whether an address is an approved composeMsg sender to the Endpoint. * @dev _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @dev _message The lzReceive payload. * @param _sender The sender address. * @return isSender Is a valid sender. * * @dev Applications can optionally choose to implement separate composeMsg senders that are NOT the bridging layer. * @dev The default sender IS the OAppReceiver implementer. */ function isComposeMsgSender( Origin calldata /*_origin*/, bytes calldata /*_message*/, address _sender ) public view virtual returns (bool) { return _sender == address(this); } /** * @notice Checks if the path initialization is allowed based on the provided origin. * @param origin The origin information containing the source endpoint and sender address. * @return Whether the path has been initialized. * * @dev This indicates to the endpoint that the OApp has enabled msgs for this particular path to be received. * @dev This defaults to assuming if a peer has been set, its initialized. * Can be overridden by the OApp if there is other logic to determine this. */ function allowInitializePath(Origin calldata origin) public view virtual returns (bool) { return peers[origin.srcEid] == origin.sender; } /** * @notice Retrieves the next nonce for a given source endpoint and sender address. * @dev _srcEid The source endpoint ID. * @dev _sender The sender address. * @return nonce The next nonce. * * @dev The path nonce starts from 1. If 0 is returned it means that there is NO nonce ordered enforcement. * @dev Is required by the off-chain executor to determine the OApp expects msg execution is ordered. * @dev This is also enforced by the OApp. * @dev By default this is NOT enabled. ie. nextNonce is hardcoded to return 0. */ function nextNonce(uint32 /*_srcEid*/, bytes32 /*_sender*/) public view virtual returns (uint64 nonce) { return 0; } /** * @dev Entry point for receiving messages or packets from the endpoint. * @param _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @param _guid The unique identifier for the received LayerZero message. * @param _message The payload of the received message. * @param _executor The address of the executor for the received message. * @param _extraData Additional arbitrary data provided by the corresponding executor. * * @dev Entry point for receiving msg/packet from the LayerZero endpoint. */ function lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) public payable virtual { // Ensures that only the endpoint can attempt to lzReceive() messages to this OApp. if (address(endpoint) != msg.sender) revert OnlyEndpoint(msg.sender); // Ensure that the sender matches the expected peer for the source endpoint. if (_getPeerOrRevert(_origin.srcEid) != _origin.sender) revert OnlyPeer(_origin.srcEid, _origin.sender); // Call the internal OApp implementation of lzReceive. _lzReceive(_origin, _guid, _message, _executor, _extraData); } /** * @dev Internal function to implement lzReceive logic without needing to copy the basic parameter validation. */ function _lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) internal virtual; } // File: @layerzerolabs/oapp-evm/contracts/oapp/OApp.sol pragma solidity ^0.8.20; // @dev Import the 'MessagingFee' and 'MessagingReceipt' so it's exposed to OApp implementers // solhint-disable-next-line no-unused-import // @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, OAppReceiver { /** * @dev Constructor to initialize the OApp with the provided endpoint and owner. * @param _endpoint The address of the LOCAL LayerZero endpoint. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. */ constructor(address _endpoint, address _delegate) OAppCore(_endpoint, _delegate) {} /** * @notice Retrieves the OApp version information. * @return senderVersion The version of the OAppSender.sol implementation. * @return receiverVersion The version of the OAppReceiver.sol implementation. */ function oAppVersion() public pure virtual override(OAppSender, OAppReceiver) returns (uint64 senderVersion, uint64 receiverVersion) { return (SENDER_VERSION, RECEIVER_VERSION); } } // File: @layerzerolabs/oapp-evm/contracts/oapp/interfaces/IOAppOptionsType3.sol pragma solidity ^0.8.20; /** * @dev Struct representing enforced option parameters. */ struct EnforcedOptionParam { uint32 eid; // Endpoint ID uint16 msgType; // Message Type bytes options; // Additional options } /** * @title IOAppOptionsType3 * @dev Interface for the OApp with Type 3 Options, allowing the setting and combining of enforced options. */ interface IOAppOptionsType3 { // Custom error message for invalid options error InvalidOptions(bytes options); // Event emitted when enforced options are set event EnforcedOptionSet(EnforcedOptionParam[] _enforcedOptions); /** * @notice Sets enforced options for specific endpoint and message type combinations. * @param _enforcedOptions An array of EnforcedOptionParam structures specifying enforced options. */ function setEnforcedOptions(EnforcedOptionParam[] calldata _enforcedOptions) external; /** * @notice Combines options for a given endpoint and message type. * @param _eid The endpoint ID. * @param _msgType The OApp message type. * @param _extraOptions Additional options passed by the caller. * @return options The combination of caller specified options AND enforced options. */ function combineOptions( uint32 _eid, uint16 _msgType, bytes calldata _extraOptions ) external view returns (bytes memory options); } // File: @layerzerolabs/oapp-evm/contracts/oapp/libs/OAppOptionsType3.sol pragma solidity ^0.8.20; /** * @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); } } // File: @layerzerolabs/oapp-evm/contracts/oapp/interfaces/IOAppMsgInspector.sol pragma solidity ^0.8.20; /** * @title IOAppMsgInspector * @dev Interface for the OApp Message Inspector, allowing examination of message and options contents. */ interface IOAppMsgInspector { // Custom error message for inspection failure error InspectionFailed(bytes message, bytes options); /** * @notice Allows the inspector to examine LayerZero message contents and optionally throw a revert if invalid. * @param _message The message payload to be inspected. * @param _options Additional options or parameters for inspection. * @return valid A boolean indicating whether the inspection passed (true) or failed (false). * * @dev Optionally done as a revert, OR use the boolean provided to handle the failure. */ function inspect(bytes calldata _message, bytes calldata _options) external view returns (bool valid); } // File: @layerzerolabs/oapp-evm/contracts/precrime/interfaces/IPreCrime.sol pragma solidity ^0.8.20; struct PreCrimePeer { uint32 eid; bytes32 preCrime; bytes32 oApp; } // TODO not done yet interface IPreCrime { error OnlyOffChain(); // for simulate() error PacketOversize(uint256 max, uint256 actual); error PacketUnsorted(); error SimulationFailed(bytes reason); // for preCrime() error SimulationResultNotFound(uint32 eid); error InvalidSimulationResult(uint32 eid, bytes reason); error CrimeFound(bytes crime); function getConfig(bytes[] calldata _packets, uint256[] calldata _packetMsgValues) external returns (bytes memory); function simulate( bytes[] calldata _packets, uint256[] calldata _packetMsgValues ) external payable returns (bytes memory); function buildSimulationResult() external view returns (bytes memory); function preCrime( bytes[] calldata _packets, uint256[] calldata _packetMsgValues, bytes[] calldata _simulations ) external; function version() external view returns (uint64 major, uint8 minor); } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessageLib.sol pragma solidity >=0.8.0; 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); } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ISendLib.sol pragma solidity >=0.8.0; struct Packet { uint64 nonce; uint32 srcEid; address sender; uint32 dstEid; bytes32 receiver; bytes32 guid; bytes message; } interface ISendLib is IMessageLib { function send( Packet calldata _packet, bytes calldata _options, bool _payInLzToken ) external returns (MessagingFee memory, bytes memory encodedPacket); function quote( Packet calldata _packet, bytes calldata _options, bool _payInLzToken ) external view returns (MessagingFee memory); function setTreasury(address _treasury) external; function withdrawFee(address _to, uint256 _amount) external; function withdrawLzTokenFee(address _lzToken, address _to, uint256 _amount) external; } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/libs/AddressCast.sol pragma solidity ^0.8.20; library AddressCast { error AddressCast_InvalidSizeForAddress(); error AddressCast_InvalidAddress(); function toBytes32(bytes calldata _addressBytes) internal pure returns (bytes32 result) { if (_addressBytes.length > 32) revert AddressCast_InvalidAddress(); result = bytes32(_addressBytes); unchecked { uint256 offset = 32 - _addressBytes.length; result = result >> (offset * 8); } } function toBytes32(address _address) internal pure returns (bytes32 result) { result = bytes32(uint256(uint160(_address))); } function toBytes(bytes32 _addressBytes32, uint256 _size) internal pure returns (bytes memory result) { if (_size == 0 || _size > 32) revert AddressCast_InvalidSizeForAddress(); result = new bytes(_size); unchecked { uint256 offset = 256 - _size * 8; assembly { mstore(add(result, 32), shl(offset, _addressBytes32)) } } } function toAddress(bytes32 _addressBytes32) internal pure returns (address result) { result = address(uint160(uint256(_addressBytes32))); } function toAddress(bytes calldata _addressBytes) internal pure returns (address result) { if (_addressBytes.length != 20) revert AddressCast_InvalidAddress(); result = address(bytes20(_addressBytes)); } } // File: @layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/libs/PacketV1Codec.sol pragma solidity ^0.8.20; 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)); } } // File: @layerzerolabs/oapp-evm/contracts/precrime/libs/Packet.sol pragma solidity ^0.8.20; /** * @title InboundPacket * @dev Structure representing an inbound packet received by the contract. */ struct InboundPacket { Origin origin; // Origin information of the packet. uint32 dstEid; // Destination endpointId of the packet. address receiver; // Receiver address for the packet. bytes32 guid; // Unique identifier of the packet. uint256 value; // msg.value of the packet. address executor; // Executor address for the packet. bytes message; // Message payload of the packet. bytes extraData; // Additional arbitrary data for the packet. } /** * @title PacketDecoder * @dev Library for decoding LayerZero packets. */ library PacketDecoder { using PacketV1Codec for bytes; /** * @dev Decode an inbound packet from the given packet data. * @param _packet The packet data to decode. * @return packet An InboundPacket struct representing the decoded packet. */ function decode(bytes calldata _packet) internal pure returns (InboundPacket memory packet) { packet.origin = Origin(_packet.srcEid(), _packet.sender(), _packet.nonce()); packet.dstEid = _packet.dstEid(); packet.receiver = _packet.receiverB20(); packet.guid = _packet.guid(); packet.message = _packet.message(); } /** * @dev Decode multiple inbound packets from the given packet data and associated message values. * @param _packets An array of packet data to decode. * @param _packetMsgValues An array of associated message values for each packet. * @return packets An array of InboundPacket structs representing the decoded packets. */ function decode( bytes[] calldata _packets, uint256[] memory _packetMsgValues ) internal pure returns (InboundPacket[] memory packets) { packets = new InboundPacket[](_packets.length); for (uint256 i = 0; i < _packets.length; i++) { bytes calldata packet = _packets[i]; packets[i] = PacketDecoder.decode(packet); // @dev Allows the verifier to specify the msg.value that gets passed in lzReceive. packets[i].value = _packetMsgValues[i]; } } } // File: @layerzerolabs/oapp-evm/contracts/precrime/interfaces/IOAppPreCrimeSimulator.sol pragma solidity ^0.8.20; // @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); } // File: @layerzerolabs/oapp-evm/contracts/precrime/OAppPreCrimeSimulator.sol pragma solidity ^0.8.20; /** * @title OAppPreCrimeSimulator * @dev Abstract contract serving as the base for preCrime simulation functionality in an OApp. */ abstract contract OAppPreCrimeSimulator is IOAppPreCrimeSimulator, Ownable { // The address of the preCrime implementation. address public preCrime; /** * @dev Retrieves the address of the OApp contract. * @return The address of the OApp contract. * * @dev The simulator contract is the base contract for the OApp by default. * @dev If the simulator is a separate contract, override this function. */ function oApp() external view virtual returns (address) { return address(this); } /** * @dev Sets the preCrime contract address. * @param _preCrime The address of the preCrime contract. */ function setPreCrime(address _preCrime) public virtual onlyOwner { preCrime = _preCrime; emit PreCrimeSet(_preCrime); } /** * @dev Interface for pre-crime simulations. Always reverts at the end with the simulation results. * @param _packets An array of InboundPacket objects representing received packets to be delivered. * * @dev WARNING: MUST revert at the end with the simulation results. * @dev Gives the preCrime implementation the ability to mock sending packets to the lzReceive function, * WITHOUT actually executing them. */ function lzReceiveAndRevert(InboundPacket[] calldata _packets) public payable virtual { for (uint256 i = 0; i < _packets.length; i++) { InboundPacket calldata packet = _packets[i]; // Ignore packets that are not from trusted peers. if (!isPeer(packet.origin.srcEid, packet.origin.sender)) continue; // @dev Because a verifier is calling this function, it doesnt have access to executor params: // - address _executor // - bytes calldata _extraData // preCrime will NOT work for OApps that rely on these two parameters inside of their _lzReceive(). // They are instead stubbed to default values, address(0) and bytes("") // @dev Calling this.lzReceiveSimulate removes ability for assembly return 0 callstack exit, // which would cause the revert to be ignored. this.lzReceiveSimulate{ value: packet.value }( packet.origin, packet.guid, packet.message, packet.executor, packet.extraData ); } // @dev Revert with the simulation results. msg.sender must implement IPreCrime.buildSimulationResult(). revert SimulationResult(IPreCrime(msg.sender).buildSimulationResult()); } /** * @dev Is effectively an internal function because msg.sender must be address(this). * Allows resetting the call stack for 'internal' calls. * @param _origin The origin information containing the source endpoint and sender address. * - srcEid: The source chain endpoint ID. * - sender: The sender address on the src chain. * - nonce: The nonce of the message. * @param _guid The unique identifier of the packet. * @param _message The message payload of the packet. * @param _executor The executor address for the packet. * @param _extraData Additional data for the packet. */ function lzReceiveSimulate( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) external payable virtual { // @dev Ensure ONLY can be called 'internally'. if (msg.sender != address(this)) revert OnlySelf(); _lzReceiveSimulate(_origin, _guid, _message, _executor, _extraData); } /** * @dev Internal function to handle the OAppPreCrimeSimulator simulated receive. * @param _origin The origin information. * - srcEid: The source chain endpoint ID. * - sender: The sender address from the src chain. * - nonce: The nonce of the LayerZero message. * @param _guid The GUID of the LayerZero message. * @param _message The LayerZero message. * @param _executor The address of the off-chain executor. * @param _extraData Arbitrary data passed by the msg executor. * * @dev Enables the preCrime simulator to mock sending lzReceive() messages, * routes the msg down from the OAppPreCrimeSimulator, and back up to the OAppReceiver. */ function _lzReceiveSimulate( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) internal virtual; /** * @dev checks if the specified peer is considered 'trusted' by the OApp. * @param _eid The endpoint Id to check. * @param _peer The peer to check. * @return Whether the peer passed is considered 'trusted' by the OApp. */ function isPeer(uint32 _eid, bytes32 _peer) public view virtual returns (bool); } // File: @layerzerolabs/oft-evm/contracts/interfaces/IOFT.sol pragma solidity ^0.8.20; /** * @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 the fee breakdown and settings data for an OFT. Unused in the default implementation. * @param _sendParam The parameters for the send operation. * @return limit The OFT limit information. * @return oftFeeDetails The details of OFT fees. * @return receipt The OFT receipt information. */ function quoteOFT( SendParam calldata _sendParam ) external view returns (OFTLimit memory, OFTFeeDetail[] memory oftFeeDetails, OFTReceipt memory); /** * @notice Provides a quote for the send() operation. * @param _sendParam The parameters for the send() operation. * @param _payInLzToken Flag indicating whether the caller is paying in the LZ token. * @return fee The calculated LayerZero messaging fee from the send() operation. * * @dev MessagingFee: LayerZero msg fee * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. */ function quoteSend(SendParam calldata _sendParam, bool _payInLzToken) external view returns (MessagingFee memory); /** * @notice Executes the send() operation. * @param _sendParam The parameters for the send operation. * @param _fee The fee information supplied by the caller. * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. * @param _refundAddress The address to receive any excess funds from fees etc. on the src. * @return receipt The LayerZero messaging receipt from the send() operation. * @return oftReceipt The OFT receipt information. * * @dev MessagingReceipt: LayerZero msg receipt * - guid: The unique identifier for the sent message. * - nonce: The nonce of the sent message. * - fee: The LayerZero fee incurred for the message. */ function send( SendParam calldata _sendParam, MessagingFee calldata _fee, address _refundAddress ) external payable returns (MessagingReceipt memory, OFTReceipt memory); } // File: @layerzerolabs/oft-evm/contracts/libs/OFTMsgCodec.sol pragma solidity ^0.8.20; library OFTMsgCodec { // Offset constants for encoding and decoding OFT messages uint8 private constant SEND_TO_OFFSET = 32; uint8 private constant SEND_AMOUNT_SD_OFFSET = 40; /** * @dev Encodes an OFT LayerZero message. * @param _sendTo The recipient address. * @param _amountShared The amount in shared decimals. * @param _composeMsg The composed message. * @return _msg The encoded message. * @return hasCompose A boolean indicating whether the message has a composed payload. */ function encode( bytes32 _sendTo, uint64 _amountShared, bytes memory _composeMsg ) internal view returns (bytes memory _msg, bool hasCompose) { hasCompose = _composeMsg.length > 0; // @dev Remote chains will want to know the composed function caller ie. msg.sender on the src. _msg = hasCompose ? abi.encodePacked(_sendTo, _amountShared, addressToBytes32(msg.sender), _composeMsg) : abi.encodePacked(_sendTo, _amountShared); } /** * @dev Checks if the OFT message is composed. * @param _msg The OFT message. * @return A boolean indicating whether the message is composed. */ function isComposed(bytes calldata _msg) internal pure returns (bool) { return _msg.length > SEND_AMOUNT_SD_OFFSET; } /** * @dev Retrieves the recipient address from the OFT message. * @param _msg The OFT message. * @return The recipient address. */ function sendTo(bytes calldata _msg) internal pure returns (bytes32) { return bytes32(_msg[:SEND_TO_OFFSET]); } /** * @dev Retrieves the amount in shared decimals from the OFT message. * @param _msg The OFT message. * @return The amount in shared decimals. */ function amountSD(bytes calldata _msg) internal pure returns (uint64) { return uint64(bytes8(_msg[SEND_TO_OFFSET:SEND_AMOUNT_SD_OFFSET])); } /** * @dev Retrieves the composed message from the OFT message. * @param _msg The OFT message. * @return The composed message. */ function composeMsg(bytes calldata _msg) internal pure returns (bytes memory) { return _msg[SEND_AMOUNT_SD_OFFSET:]; } /** * @dev Converts an address to bytes32. * @param _addr The address to convert. * @return The bytes32 representation of the address. */ function addressToBytes32(address _addr) internal pure returns (bytes32) { return bytes32(uint256(uint160(_addr))); } /** * @dev Converts bytes32 to an address. * @param _b The bytes32 value to convert. * @return The address representation of bytes32. */ function bytes32ToAddress(bytes32 _b) internal pure returns (address) { return address(uint160(uint256(_b))); } } // File: @layerzerolabs/oft-evm/contracts/libs/OFTComposeMsgCodec.sol pragma solidity ^0.8.20; library OFTComposeMsgCodec { // Offset constants for decoding composed messages uint8 private constant NONCE_OFFSET = 8; uint8 private constant SRC_EID_OFFSET = 12; uint8 private constant AMOUNT_LD_OFFSET = 44; uint8 private constant COMPOSE_FROM_OFFSET = 76; /** * @dev Encodes a OFT composed message. * @param _nonce The nonce value. * @param _srcEid The source endpoint ID. * @param _amountLD The amount in local decimals. * @param _composeMsg The composed message. * @return _msg The encoded Composed message. */ function encode( uint64 _nonce, uint32 _srcEid, uint256 _amountLD, bytes memory _composeMsg // 0x[composeFrom][composeMsg] ) internal pure returns (bytes memory _msg) { _msg = abi.encodePacked(_nonce, _srcEid, _amountLD, _composeMsg); } /** * @dev Retrieves the nonce for the composed message. * @param _msg The message. * @return The nonce value. */ function nonce(bytes calldata _msg) internal pure returns (uint64) { return uint64(bytes8(_msg[:NONCE_OFFSET])); } /** * @dev Retrieves the source endpoint ID for the composed message. * @param _msg The message. * @return The source endpoint ID. */ function srcEid(bytes calldata _msg) internal pure returns (uint32) { return uint32(bytes4(_msg[NONCE_OFFSET:SRC_EID_OFFSET])); } /** * @dev Retrieves the amount in local decimals from the composed message. * @param _msg The message. * @return The amount in local decimals. */ function amountLD(bytes calldata _msg) internal pure returns (uint256) { return uint256(bytes32(_msg[SRC_EID_OFFSET:AMOUNT_LD_OFFSET])); } /** * @dev Retrieves the composeFrom value from the composed message. * @param _msg The message. * @return The composeFrom value. */ function composeFrom(bytes calldata _msg) internal pure returns (bytes32) { return bytes32(_msg[AMOUNT_LD_OFFSET:COMPOSE_FROM_OFFSET]); } /** * @dev Retrieves the composed message. * @param _msg The message. * @return The composed message. */ function composeMsg(bytes calldata _msg) internal pure returns (bytes memory) { return _msg[COMPOSE_FROM_OFFSET:]; } /** * @dev Converts an address to bytes32. * @param _addr The address to convert. * @return The bytes32 representation of the address. */ function addressToBytes32(address _addr) internal pure returns (bytes32) { return bytes32(uint256(uint160(_addr))); } /** * @dev Converts bytes32 to an address. * @param _b The bytes32 value to convert. * @return The address representation of bytes32. */ function bytes32ToAddress(bytes32 _b) internal pure returns (address) { return address(uint160(uint256(_b))); } } // File: @layerzerolabs/oft-evm/contracts/OFTCore.sol pragma solidity ^0.8.20; /** * @title OFTCore * @dev Abstract contract for the OftChain (OFT) token. */ abstract contract OFTCore is IOFT, OApp, OAppPreCrimeSimulator, OAppOptionsType3 { using OFTMsgCodec for bytes; using OFTMsgCodec for bytes32; // @notice Provides a conversion rate when swapping between denominations of SD and LD // - shareDecimals == SD == shared Decimals // - localDecimals == LD == local decimals // @dev Considers that tokens have different decimal amounts on various chains. // @dev eg. // For a token // - locally with 4 decimals --> 1.2345 => uint(12345) // - remotely with 2 decimals --> 1.23 => uint(123) // - The conversion rate would be 10 ** (4 - 2) = 100 // @dev If you want to send 1.2345 -> (uint 12345), you CANNOT represent that value on the remote, // you can only display 1.23 -> uint(123). // @dev To preserve the dust that would otherwise be lost on that conversion, // we need to unify a denomination that can be represented on ALL chains inside of the OFT mesh uint256 public immutable decimalConversionRate; // @notice Msg types that are used to identify the various OFT operations. // @dev This can be extended in child contracts for non-default oft operations // @dev These values are used in things like combineOptions() in OAppOptionsType3.sol. uint16 public constant SEND = 1; uint16 public constant SEND_AND_CALL = 2; // Address of an optional contract to inspect both 'message' and 'options' address public msgInspector; event MsgInspectorSet(address inspector); /** * @dev Constructor. * @param _localDecimals The decimals of the token on the local chain (this chain). * @param _endpoint The address of the LayerZero endpoint. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. */ constructor(uint8 _localDecimals, address _endpoint, address _delegate) OApp(_endpoint, _delegate) { if (_localDecimals < sharedDecimals()) revert InvalidLocalDecimals(); decimalConversionRate = 10 ** (_localDecimals - sharedDecimals()); } /** * @notice Retrieves interfaceID and the version of the OFT. * @return interfaceId The interface ID. * @return version The version. * * @dev interfaceId: This specific interface ID is '0x02e49c2c'. * @dev version: Indicates a cross-chain compatible msg encoding with other OFTs. * @dev If a new feature is added to the OFT cross-chain msg encoding, the version will be incremented. * ie. localOFT version(x,1) CAN send messages to remoteOFT version(x,1) */ function oftVersion() external pure virtual returns (bytes4 interfaceId, uint64 version) { return (type(IOFT).interfaceId, 1); } /** * @dev Retrieves the shared decimals of the OFT. * @return The shared decimals of the OFT. * * @dev Sets an implicit cap on the amount of tokens, over uint64.max() will need some sort of outbound cap / totalSupply cap * Lowest common decimal denominator between chains. * Defaults to 6 decimal places to provide up to 18,446,744,073,709.551615 units (max uint64). * For tokens exceeding this totalSupply(), they will need to override the sharedDecimals function with something smaller. * ie. 4 sharedDecimals would be 1,844,674,407,370,955.1615 */ function sharedDecimals() public view virtual returns (uint8) { return 6; } /** * @dev Sets the message inspector address for the OFT. * @param _msgInspector The address of the message inspector. * * @dev This is an optional contract that can be used to inspect both 'message' and 'options'. * @dev Set it to address(0) to disable it, or set it to a contract address to enable it. */ function setMsgInspector(address _msgInspector) public virtual onlyOwner { msgInspector = _msgInspector; emit MsgInspectorSet(_msgInspector); } /** * @notice Provides the fee breakdown and settings data for an OFT. Unused in the default implementation. * @param _sendParam The parameters for the send operation. * @return oftLimit The OFT limit information. * @return oftFeeDetails The details of OFT fees. * @return oftReceipt The OFT receipt information. */ function quoteOFT( SendParam calldata _sendParam ) external view virtual returns (OFTLimit memory oftLimit, OFTFeeDetail[] memory oftFeeDetails, OFTReceipt memory oftReceipt) { uint256 minAmountLD = 0; // Unused in the default implementation. uint256 maxAmountLD = IERC20(this.token()).totalSupply(); // Unused in the default implementation. oftLimit = OFTLimit(minAmountLD, maxAmountLD); // Unused in the default implementation; reserved for future complex fee details. oftFeeDetails = new OFTFeeDetail[](0); // @dev This is the same as the send() operation, but without the actual send. // - amountSentLD is the amount in local decimals that would be sent from the sender. // - amountReceivedLD is the amount in local decimals that will be credited to the recipient on the remote OFT instance. // @dev The amountSentLD MIGHT not equal the amount the user actually receives. HOWEVER, the default does. (uint256 amountSentLD, uint256 amountReceivedLD) = _debitView( _sendParam.amountLD, _sendParam.minAmountLD, _sendParam.dstEid ); oftReceipt = OFTReceipt(amountSentLD, amountReceivedLD); } /** * @notice Provides a quote for the send() operation. * @param _sendParam The parameters for the send() operation. * @param _payInLzToken Flag indicating whether the caller is paying in the LZ token. * @return msgFee The calculated LayerZero messaging fee from the send() operation. * * @dev MessagingFee: LayerZero msg fee * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. */ function quoteSend( SendParam calldata _sendParam, bool _payInLzToken ) external view virtual returns (MessagingFee memory msgFee) { // @dev mock the amount to receive, this is the same operation used in the send(). // The quote is as similar as possible to the actual send() operation. (, uint256 amountReceivedLD) = _debitView(_sendParam.amountLD, _sendParam.minAmountLD, _sendParam.dstEid); // @dev Builds the options and OFT message to quote in the endpoint. (bytes memory message, bytes memory options) = _buildMsgAndOptions(_sendParam, amountReceivedLD); // @dev Calculates the LayerZero fee for the send() operation. return _quote(_sendParam.dstEid, message, options, _payInLzToken); } /** * @dev Executes the send operation. * @param _sendParam The parameters for the send operation. * @param _fee The calculated fee for the send() operation. * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. * @param _refundAddress The address to receive any excess funds. * @return msgReceipt The receipt for the send operation. * @return oftReceipt The OFT receipt information. * * @dev MessagingReceipt: LayerZero msg receipt * - guid: The unique identifier for the sent message. * - nonce: The nonce of the sent message. * - fee: The LayerZero fee incurred for the message. */ function send( SendParam calldata _sendParam, MessagingFee calldata _fee, address _refundAddress ) external payable virtual returns (MessagingReceipt memory msgReceipt, OFTReceipt memory oftReceipt) { return _send(_sendParam, _fee, _refundAddress); } /** * @dev Internal function to execute the send operation. * @param _sendParam The parameters for the send operation. * @param _fee The calculated fee for the send() operation. * - nativeFee: The native fee. * - lzTokenFee: The lzToken fee. * @param _refundAddress The address to receive any excess funds. * @return msgReceipt The receipt for the send operation. * @return oftReceipt The OFT receipt information. * * @dev MessagingReceipt: LayerZero msg receipt * - guid: The unique identifier for the sent message. * - nonce: The nonce of the sent message. * - fee: The LayerZero fee incurred for the message. */ function _send( SendParam calldata _sendParam, MessagingFee calldata _fee, address _refundAddress ) internal virtual returns (MessagingReceipt memory msgReceipt, OFTReceipt memory oftReceipt) { // @dev Applies the token transfers regarding this send() operation. // - amountSentLD is the amount in local decimals that was ACTUALLY sent/debited from the sender. // - amountReceivedLD is the amount in local decimals that will be received/credited to the recipient on the remote OFT instance. (uint256 amountSentLD, uint256 amountReceivedLD) = _debit( msg.sender, _sendParam.amountLD, _sendParam.minAmountLD, _sendParam.dstEid ); // @dev Builds the options and OFT message to quote in the endpoint. (bytes memory message, bytes memory options) = _buildMsgAndOptions(_sendParam, amountReceivedLD); // @dev Sends the message to the LayerZero endpoint and returns the LayerZero msg receipt. msgReceipt = _lzSend(_sendParam.dstEid, message, options, _fee, _refundAddress); // @dev Formulate the OFT receipt. oftReceipt = OFTReceipt(amountSentLD, amountReceivedLD); emit OFTSent(msgReceipt.guid, _sendParam.dstEid, msg.sender, amountSentLD, amountReceivedLD); } /** * @dev Internal function to build the message and options. * @param _sendParam The parameters for the send() operation. * @param _amountLD The amount in local decimals. * @return message The encoded message. * @return options The encoded options. */ function _buildMsgAndOptions( SendParam calldata _sendParam, uint256 _amountLD ) internal view virtual returns (bytes memory message, bytes memory options) { bool hasCompose; // @dev This generated message has the msg.sender encoded into the payload so the remote knows who the caller is. (message, hasCompose) = OFTMsgCodec.encode( _sendParam.to, _toSD(_amountLD), // @dev Must be include a non empty bytes if you want to compose, EVEN if you dont need it on the remote. // EVEN if you dont require an arbitrary payload to be sent... eg. '0x01' _sendParam.composeMsg ); // @dev Change the msg type depending if its composed or not. uint16 msgType = hasCompose ? SEND_AND_CALL : SEND; // @dev Combine the callers _extraOptions with the enforced options via the OAppOptionsType3. options = combineOptions(_sendParam.dstEid, msgType, _sendParam.extraOptions); // @dev Optionally inspect the message and options depending if the OApp owner has set a msg inspector. // @dev If it fails inspection, needs to revert in the implementation. ie. does not rely on return boolean address inspector = msgInspector; // caches the msgInspector to avoid potential double storage read if (inspector != address(0)) IOAppMsgInspector(inspector).inspect(message, options); } /** * @dev Internal function to handle the receive on the LayerZero endpoint. * @param _origin The origin information. * - srcEid: The source chain endpoint ID. * - sender: The sender address from the src chain. * - nonce: The nonce of the LayerZero message. * @param _guid The unique identifier for the received LayerZero message. * @param _message The encoded message. * @dev _executor The address of the executor. * @dev _extraData Additional data. */ function _lzReceive( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address /*_executor*/, // @dev unused in the default implementation. bytes calldata /*_extraData*/ // @dev unused in the default implementation. ) internal virtual override { // @dev The src sending chain doesnt know the address length on this chain (potentially non-evm) // Thus everything is bytes32() encoded in flight. address toAddress = _message.sendTo().bytes32ToAddress(); // @dev Credit the amountLD to the recipient and return the ACTUAL amount the recipient received in local decimals uint256 amountReceivedLD = _credit(toAddress, _toLD(_message.amountSD()), _origin.srcEid); if (_message.isComposed()) { // @dev Proprietary composeMsg format for the OFT. bytes memory composeMsg = OFTComposeMsgCodec.encode( _origin.nonce, _origin.srcEid, amountReceivedLD, _message.composeMsg() ); // @dev Stores the lzCompose payload that will be executed in a separate tx. // Standardizes functionality for executing arbitrary contract invocation on some non-evm chains. // @dev The off-chain executor will listen and process the msg based on the src-chain-callers compose options passed. // @dev The index is used when a OApp needs to compose multiple msgs on lzReceive. // For default OFT implementation there is only 1 compose msg per lzReceive, thus its always 0. endpoint.sendCompose(toAddress, _guid, 0 /* the index of the composed message*/, composeMsg); } emit OFTReceived(_guid, _origin.srcEid, toAddress, amountReceivedLD); } /** * @dev Internal function to handle the OAppPreCrimeSimulator simulated receive. * @param _origin The origin information. * - srcEid: The source chain endpoint ID. * - sender: The sender address from the src chain. * - nonce: The nonce of the LayerZero message. * @param _guid The unique identifier for the received LayerZero message. * @param _message The LayerZero message. * @param _executor The address of the off-chain executor. * @param _extraData Arbitrary data passed by the msg executor. * * @dev Enables the preCrime simulator to mock sending lzReceive() messages, * routes the msg down from the OAppPreCrimeSimulator, and back up to the OAppReceiver. */ function _lzReceiveSimulate( Origin calldata _origin, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData ) internal virtual override { _lzReceive(_origin, _guid, _message, _executor, _extraData); } /** * @dev Check if the peer is considered 'trusted' by the OApp. * @param _eid The endpoint ID to check. * @param _peer The peer to check. * @return Whether the peer passed is considered 'trusted' by the OApp. * * @dev Enables OAppPreCrimeSimulator to check whether a potential Inbound Packet is from a trusted source. */ function isPeer(uint32 _eid, bytes32 _peer) public view virtual override returns (bool) { return peers[_eid] == _peer; } /** * @dev Internal function to remove dust from the given local decimal amount. * @param _amountLD The amount in local decimals. * @return amountLD The amount after removing dust. * * @dev Prevents the loss of dust when moving amounts between chains with different decimals. * @dev eg. uint(123) with a conversion rate of 100 becomes uint(100). */ function _removeDust(uint256 _amountLD) internal view virtual returns (uint256 amountLD) { return (_amountLD / decimalConversionRate) * decimalConversionRate; } /** * @dev Internal function to convert an amount from shared decimals into local decimals. * @param _amountSD The amount in shared decimals. * @return amountLD The amount in local decimals. */ function _toLD(uint64 _amountSD) internal view virtual returns (uint256 amountLD) { return _amountSD * decimalConversionRate; } /** * @dev Internal function to convert an amount from local decimals into shared decimals. * @param _amountLD The amount in local decimals. * @return amountSD The amount in shared decimals. */ 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); } // File: @layerzerolabs/oft-evm/contracts/OFT.sol pragma solidity ^0.8.20; /** * @title OFT Contract * @dev OFT is an ERC-20 token that extends the functionality of the OFTCore contract. */ abstract contract OFT is OFTCore, ERC20 { /** * @dev Constructor for the OFT contract. * @param _name The name of the OFT. * @param _symbol The symbol of the OFT. * @param _lzEndpoint The LayerZero endpoint address. * @param _delegate The delegate capable of making OApp configurations inside of the endpoint. */ constructor( string memory _name, string memory _symbol, address _lzEndpoint, address _delegate ) ERC20(_name, _symbol) OFTCore(decimals(), _lzEndpoint, _delegate) {} /** * @dev Retrieves the address of the underlying ERC20 implementation. * @return The address of the OFT token. * * @dev In the case of OFT, address(this) and erc20 are the same contract. */ function token() public view returns (address) { return address(this); } /** * @notice Indicates whether the OFT contract requires approval of the 'token()' to send. * @return requiresApproval Needs approval of the underlying token implementation. * * @dev In the case of OFT where the contract IS the token, approval is NOT required. */ function approvalRequired() external pure virtual returns (bool) { return false; } /** * @dev Burns tokens from the sender's specified balance. * @param _from The address to debit the tokens from. * @param _amountLD The amount of tokens to send in local decimals. * @param _minAmountLD The minimum amount to send in local decimals. * @param _dstEid The destination chain ID. * @return amountSentLD The amount sent in local decimals. * @return amountReceivedLD The amount received in local decimals on the remote. */ function _debit( address _from, uint256 _amountLD, uint256 _minAmountLD, uint32 _dstEid ) internal virtual override returns (uint256 amountSentLD, uint256 amountReceivedLD) { (amountSentLD, amountReceivedLD) = _debitView(_amountLD, _minAmountLD, _dstEid); // @dev In NON-default OFT, amountSentLD could be 100, with a 10% fee, the amountReceivedLD amount is 90, // therefore amountSentLD CAN differ from amountReceivedLD. // @dev Default OFT burns on src. _burn(_from, amountSentLD); } /** * @dev Credits tokens to the specified address. * @param _to The address to credit the tokens to. * @param _amountLD The amount of tokens to credit in local decimals. * @dev _srcEid The source chain ID. * @return amountReceivedLD The amount of tokens ACTUALLY received in local decimals. */ function _credit( address _to, uint256 _amountLD, uint32 /*_srcEid*/ ) internal virtual override returns (uint256 amountReceivedLD) { if (_to == address(0x0)) _to = address(0xdead); // _mint(...) does not support address(0x0) // @dev Default OFT mints on dst. _mint(_to, _amountLD); // @dev In the case of NON-default OFT, the _amountLD MIGHT not be == amountReceivedLD. return _amountLD; } } // File: Token/EXFate Adventure Token1.sol pragma solidity ^0.8.22; /// @notice OFT is an ERC-20 token that extends the OFTCore contract. contract EXFateAdventureToken is OFT { uint256 public constant MAX_SUPPLY = 10_000_000 * 10**18; // Fixed supply: 10 million tokens (18 decimals) constructor( ) OFT("EXFate Adventure", //token name "EXFA", //token symbol 0x6F475642a6e85809B1c36Fa62763669b1b48DD5B, //lzEndpoint msg.sender //deligate ) Ownable( msg.sender //owner ) { _mint(msg.sender, MAX_SUPPLY); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[],"name":"InvalidDelegate","type":"error"},{"inputs":[],"name":"InvalidEndpointCall","type":"error"},{"inputs":[],"name":"InvalidLocalDecimals","type":"error"},{"inputs":[{"internalType":"bytes","name":"options","type":"bytes"}],"name":"InvalidOptions","type":"error"},{"inputs":[],"name":"LzTokenUnavailable","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"NoPeer","type":"error"},{"inputs":[{"internalType":"uint256","name":"msgValue","type":"uint256"}],"name":"NotEnoughNative","type":"error"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"OnlyEndpoint","type":"error"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"}],"name":"OnlyPeer","type":"error"},{"inputs":[],"name":"OnlySelf","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[{"internalType":"bytes","name":"result","type":"bytes"}],"name":"SimulationResult","type":"error"},{"inputs":[{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"uint256","name":"minAmountLD","type":"uint256"}],"name":"SlippageExceeded","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint16","name":"msgType","type":"uint16"},{"internalType":"bytes","name":"options","type":"bytes"}],"indexed":false,"internalType":"struct EnforcedOptionParam[]","name":"_enforcedOptions","type":"tuple[]"}],"name":"EnforcedOptionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"inspector","type":"address"}],"name":"MsgInspectorSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"guid","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"srcEid","type":"uint32"},{"indexed":true,"internalType":"address","name":"toAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountReceivedLD","type":"uint256"}],"name":"OFTReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"guid","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"dstEid","type":"uint32"},{"indexed":true,"internalType":"address","name":"fromAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountSentLD","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountReceivedLD","type":"uint256"}],"name":"OFTSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"eid","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"peer","type":"bytes32"}],"name":"PeerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"preCrimeAddress","type":"address"}],"name":"PreCrimeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SEND","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SEND_AND_CALL","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"origin","type":"tuple"}],"name":"allowInitializePath","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"approvalRequired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"uint16","name":"_msgType","type":"uint16"},{"internalType":"bytes","name":"_extraOptions","type":"bytes"}],"name":"combineOptions","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimalConversionRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endpoint","outputs":[{"internalType":"contract ILayerZeroEndpointV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint16","name":"msgType","type":"uint16"}],"name":"enforcedOptions","outputs":[{"internalType":"bytes","name":"enforcedOption","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"","type":"tuple"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"address","name":"_sender","type":"address"}],"name":"isComposeMsgSender","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"bytes32","name":"_peer","type":"bytes32"}],"name":"isPeer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"_origin","type":"tuple"},{"internalType":"bytes32","name":"_guid","type":"bytes32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"address","name":"_executor","type":"address"},{"internalType":"bytes","name":"_extraData","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"origin","type":"tuple"},{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes32","name":"guid","type":"bytes32"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"address","name":"executor","type":"address"},{"internalType":"bytes","name":"message","type":"bytes"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct InboundPacket[]","name":"_packets","type":"tuple[]"}],"name":"lzReceiveAndRevert","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"_origin","type":"tuple"},{"internalType":"bytes32","name":"_guid","type":"bytes32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"address","name":"_executor","type":"address"},{"internalType":"bytes","name":"_extraData","type":"bytes"}],"name":"lzReceiveSimulate","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"msgInspector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"nextNonce","outputs":[{"internalType":"uint64","name":"nonce","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oApp","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oAppVersion","outputs":[{"internalType":"uint64","name":"senderVersion","type":"uint64"},{"internalType":"uint64","name":"receiverVersion","type":"uint64"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"oftVersion","outputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"},{"internalType":"uint64","name":"version","type":"uint64"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"eid","type":"uint32"}],"name":"peers","outputs":[{"internalType":"bytes32","name":"peer","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"preCrime","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"bytes32","name":"to","type":"bytes32"},{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"uint256","name":"minAmountLD","type":"uint256"},{"internalType":"bytes","name":"extraOptions","type":"bytes"},{"internalType":"bytes","name":"composeMsg","type":"bytes"},{"internalType":"bytes","name":"oftCmd","type":"bytes"}],"internalType":"struct SendParam","name":"_sendParam","type":"tuple"}],"name":"quoteOFT","outputs":[{"components":[{"internalType":"uint256","name":"minAmountLD","type":"uint256"},{"internalType":"uint256","name":"maxAmountLD","type":"uint256"}],"internalType":"struct OFTLimit","name":"oftLimit","type":"tuple"},{"components":[{"internalType":"int256","name":"feeAmountLD","type":"int256"},{"internalType":"string","name":"description","type":"string"}],"internalType":"struct OFTFeeDetail[]","name":"oftFeeDetails","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"amountSentLD","type":"uint256"},{"internalType":"uint256","name":"amountReceivedLD","type":"uint256"}],"internalType":"struct OFTReceipt","name":"oftReceipt","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"bytes32","name":"to","type":"bytes32"},{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"uint256","name":"minAmountLD","type":"uint256"},{"internalType":"bytes","name":"extraOptions","type":"bytes"},{"internalType":"bytes","name":"composeMsg","type":"bytes"},{"internalType":"bytes","name":"oftCmd","type":"bytes"}],"internalType":"struct SendParam","name":"_sendParam","type":"tuple"},{"internalType":"bool","name":"_payInLzToken","type":"bool"}],"name":"quoteSend","outputs":[{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"msgFee","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"dstEid","type":"uint32"},{"internalType":"bytes32","name":"to","type":"bytes32"},{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"uint256","name":"minAmountLD","type":"uint256"},{"internalType":"bytes","name":"extraOptions","type":"bytes"},{"internalType":"bytes","name":"composeMsg","type":"bytes"},{"internalType":"bytes","name":"oftCmd","type":"bytes"}],"internalType":"struct SendParam","name":"_sendParam","type":"tuple"},{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"_fee","type":"tuple"},{"internalType":"address","name":"_refundAddress","type":"address"}],"name":"send","outputs":[{"components":[{"internalType":"bytes32","name":"guid","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"},{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"fee","type":"tuple"}],"internalType":"struct MessagingReceipt","name":"msgReceipt","type":"tuple"},{"components":[{"internalType":"uint256","name":"amountSentLD","type":"uint256"},{"internalType":"uint256","name":"amountReceivedLD","type":"uint256"}],"internalType":"struct OFTReceipt","name":"oftReceipt","type":"tuple"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_delegate","type":"address"}],"name":"setDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"eid","type":"uint32"},{"internalType":"uint16","name":"msgType","type":"uint16"},{"internalType":"bytes","name":"options","type":"bytes"}],"internalType":"struct EnforcedOptionParam[]","name":"_enforcedOptions","type":"tuple[]"}],"name":"setEnforcedOptions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_msgInspector","type":"address"}],"name":"setMsgInspector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"bytes32","name":"_peer","type":"bytes32"}],"name":"setPeer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_preCrime","type":"address"}],"name":"setPreCrime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sharedDecimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60c060405234801561000f575f5ffd5b506040518060400160405280601081526020016f45584661746520416476656e7475726560801b815250604051806040016040528060048152602001634558464160e01b815250736f475642a6e85809b1c36fa62763669b1b48dd5b33838361007c6101cf60201b60201c565b84848181818133806100a857604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b6100b1816101d4565b506001600160a01b0380831660805281166100df57604051632d618d8160e21b815260040160405180910390fd5b60805160405163ca5eb5e160e01b81526001600160a01b0383811660048301529091169063ca5eb5e1906024015f604051808303815f87803b158015610123575f5ffd5b505af1158015610135573d5f5f3e3d5ffd5b505050505050505061014b61022360201b60201c565b60ff168360ff161015610171576040516301e9714b60e41b815260040160405180910390fd5b61017c60068461039a565b61018790600a61049c565b60a052506008915061019b90508382610549565b5060096101a88282610549565b505050505050506101ca336a084595161401484a00000061022860201b60201c565b610616565b601290565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600690565b6001600160a01b0382166102515760405163ec442f0560e01b81525f600482015260240161009f565b61025c5f8383610260565b5050565b6001600160a01b03831661028a578060075f82825461027f9190610603565b909155506102fa9050565b6001600160a01b0383165f90815260056020526040902054818110156102dc5760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640161009f565b6001600160a01b0384165f9081526005602052604090209082900390555b6001600160a01b03821661031657600780548290039055610334565b6001600160a01b0382165f9081526005602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161037991815260200190565b60405180910390a3505050565b634e487b7160e01b5f52601160045260245ffd5b60ff82811682821603908111156103b3576103b3610386565b92915050565b6001815b60018411156103f4578085048111156103d8576103d8610386565b60018416156103e657908102905b60019390931c9280026103bd565b935093915050565b5f8261040a575060016103b3565b8161041657505f6103b3565b816001811461042c576002811461043657610452565b60019150506103b3565b60ff84111561044757610447610386565b50506001821b6103b3565b5060208310610133831016604e8410600b8410161715610475575081810a6103b3565b6104815f1984846103b9565b805f190482111561049457610494610386565b029392505050565b5f6104aa60ff8416836103fc565b9392505050565b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806104d957607f821691505b6020821081036104f757634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561054457805f5260205f20601f840160051c810160208510156105225750805b601f840160051c820191505b81811015610541575f815560010161052e565b50505b505050565b81516001600160401b03811115610562576105626104b1565b6105768161057084546104c5565b846104fd565b6020601f8211600181146105a8575f83156105915750848201515b5f19600385901b1c1916600184901b178455610541565b5f84815260208120601f198516915b828110156105d757878501518255602094850194600190920191016105b7565b50848210156105f457868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b808201808211156103b3576103b3610386565b60805160a051612faf61067d5f395f818161062001528181611a3e01528181611ab00152611cad01525f81816104eb01528181610a360152818161106b015281816112d50152818161162c01528181611da201528181611f090152611fbe0152612faf5ff3fe608060405260043610610254575f3560e01c8063715018a61161013f578063bb0b6a53116100b3578063d045a0dc11610078578063d045a0dc1461074e578063d424388514610761578063dd62ed3e14610780578063f2fde38b146107c4578063fc0c546a14610474578063ff7bd03d146107e3575f5ffd5b8063bb0b6a53146106b1578063bc70b354146106dc578063bd815db0146106fb578063c7c7f5b31461070e578063ca5eb5e11461072f575f5ffd5b806395d89b411161010457806395d89b41146105fb578063963efcaa1461060f5780639f68b96414610642578063a9059cbb14610654578063b731ea0a14610673578063b98bd07014610692575f5ffd5b8063715018a6146105605780637d25a05e1461057457806382413eac146105ad578063857749b0146105cc5780638da5cb5b146105df575f5ffd5b806323b872dd116101d657806352ae28791161019b57806352ae2879146104745780635535d461146104865780635a0dfe4d146104a55780635e280f11146104da5780636fc1b31e1461050d57806370a082311461052c575f5ffd5b806323b872dd146103cb578063313ce567146103ea57806332cb6b0c1461040b5780633400288b146104295780633b6f743b14610448575f5ffd5b8063134d4f251161021c578063134d4f251461032b578063156a0d0f1461035257806317442b701461037857806318160ddd146103995780631f5e1334146103b7575f5ffd5b806306fdde0314610258578063095ea7b3146102825780630d35b415146102b1578063111ecdad146102df57806313137d6514610316575b5f5ffd5b348015610263575f5ffd5b5061026c610802565b604051610279919061210a565b60405180910390f35b34801561028d575f5ffd5b506102a161029c366004612130565b610892565b6040519015158152602001610279565b3480156102bc575f5ffd5b506102d06102cb366004612170565b6108ab565b604051610279939291906121a1565b3480156102ea575f5ffd5b506004546102fe906001600160a01b031681565b6040516001600160a01b039091168152602001610279565b610329610324366004612290565b610a34565b005b348015610336575f5ffd5b5061033f600281565b60405161ffff9091168152602001610279565b34801561035d575f5ffd5b506040805162b9270b60e21b81526001602082015201610279565b348015610383575f5ffd5b5060408051600181526002602082015201610279565b3480156103a4575f5ffd5b506007545b604051908152602001610279565b3480156103c2575f5ffd5b5061033f600181565b3480156103d6575f5ffd5b506102a16103e536600461232a565b610af4565b3480156103f5575f5ffd5b5060125b60405160ff9091168152602001610279565b348015610416575f5ffd5b506103a96a084595161401484a00000081565b348015610434575f5ffd5b50610329610443366004612380565b610b19565b348015610453575f5ffd5b506104676104623660046123a7565b610b2f565b60405161027991906123f5565b34801561047f575f5ffd5b50306102fe565b348015610491575f5ffd5b5061026c6104a036600461241d565b610b93565b3480156104b0575f5ffd5b506102a16104bf366004612380565b63ffffffff919091165f908152600160205260409020541490565b3480156104e5575f5ffd5b506102fe7f000000000000000000000000000000000000000000000000000000000000000081565b348015610518575f5ffd5b5061032961052736600461244e565b610c35565b348015610537575f5ffd5b506103a961054636600461244e565b6001600160a01b03165f9081526005602052604090205490565b34801561056b575f5ffd5b50610329610c92565b34801561057f575f5ffd5b5061059561058e366004612380565b5f92915050565b6040516001600160401b039091168152602001610279565b3480156105b8575f5ffd5b506102a16105c7366004612469565b610ca5565b3480156105d7575f5ffd5b5060066103f9565b3480156105ea575f5ffd5b505f546001600160a01b03166102fe565b348015610606575f5ffd5b5061026c610cba565b34801561061a575f5ffd5b506103a97f000000000000000000000000000000000000000000000000000000000000000081565b34801561064d575f5ffd5b505f6102a1565b34801561065f575f5ffd5b506102a161066e366004612130565b610cc9565b34801561067e575f5ffd5b506002546102fe906001600160a01b031681565b34801561069d575f5ffd5b506103296106ac36600461250b565b610cd6565b3480156106bc575f5ffd5b506103a96106cb366004612549565b60016020525f908152604090205481565b3480156106e7575f5ffd5b5061026c6106f6366004612562565b610cf0565b61032961070936600461250b565b610e91565b61072161071c3660046125be565b611011565b604051610279929190612626565b34801561073a575f5ffd5b5061032961074936600461244e565b611044565b61032961075c366004612290565b6110c5565b34801561076c575f5ffd5b5061032961077b36600461244e565b6110f4565b34801561078b575f5ffd5b506103a961079a366004612677565b6001600160a01b039182165f90815260066020908152604080832093909416825291909152205490565b3480156107cf575f5ffd5b506103296107de36600461244e565b61114a565b3480156107ee575f5ffd5b506102a16107fd3660046126a3565b611187565b606060088054610811906126bd565b80601f016020809104026020016040519081016040528092919081815260200182805461083d906126bd565b80156108885780601f1061085f57610100808354040283529160200191610888565b820191905f5260205f20905b81548152906001019060200180831161086b57829003601f168201915b5050505050905090565b5f3361089f8185856111bb565b60019150505b92915050565b604080518082019091525f808252602082015260606108db60405180604001604052805f81526020015f81525090565b5f5f90505f306001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561091c573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061094091906126ef565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561097b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061099f919061270a565b604080518082018252848152602080820184905282515f808252918101909352909750919250906109f2565b604080518082019091525f8152606060208201528152602001906001900390816109cb5790505b5093505f80610a16604089013560608a0135610a1160208c018c612549565b6111cd565b60408051808201909152918252602082015296989597505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163314610a84576040516391ac5e4f60e01b81523360048201526024015b60405180910390fd5b60208701803590610a9e90610a99908a612549565b611208565b14610adc57610ab06020880188612549565b60405163309afaf360e21b815263ffffffff909116600482015260208801356024820152604401610a7b565b610aeb87878787878787611243565b50505050505050565b5f33610b018582856113a1565b610b0c85858561141c565b60019150505b9392505050565b610b21611479565b610b2b82826114a5565b5050565b604080518082019091525f80825260208201525f610b5d60408501356060860135610a116020880188612549565b9150505f5f610b6c86846114f9565b9092509050610b89610b816020880188612549565b838388611617565b9695505050505050565b600360209081525f928352604080842090915290825290208054610bb6906126bd565b80601f0160208091040260200160405190810160405280929190818152602001828054610be2906126bd565b8015610c2d5780601f10610c0457610100808354040283529160200191610c2d565b820191905f5260205f20905b815481529060010190602001808311610c1057829003601f168201915b505050505081565b610c3d611479565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527ff0be4f1e87349231d80c36b33f9e8639658eeaf474014dee15a3e6a4d4414197906020015b60405180910390a150565b610c9a611479565b610ca35f6116f5565b565b6001600160a01b03811630145b949350505050565b606060098054610811906126bd565b5f3361089f81858561141c565b610cde611479565b610b2b610ceb82846127d5565b611744565b63ffffffff84165f90815260036020908152604080832061ffff87168452909152812080546060929190610d23906126bd565b80601f0160208091040260200160405190810160405280929190818152602001828054610d4f906126bd565b8015610d9a5780601f10610d7157610100808354040283529160200191610d9a565b820191905f5260205f20905b815481529060010190602001808311610d7d57829003601f168201915b5050505050905080515f03610de85783838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250929450610cb29350505050565b5f839003610df7579050610cb2565b60028310610e7457610e3d84848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061184592505050565b80610e4b84600281886128f6565b604051602001610e5d93929190612934565b604051602081830303815290604052915050610cb2565b8383604051639a6d49cd60e01b8152600401610a7b92919061297a565b5f5b81811015610f945736838383818110610eae57610eae61298d565b9050602002810190610ec091906129a1565b9050610ef2610ed26020830183612549565b602083013563ffffffff919091165f908152600160205260409020541490565b610efc5750610f8c565b3063d045a0dc60c08301358360a0810135610f1b6101008301836129c0565b610f2c610100890160e08a0161244e565b610f3a6101208a018a6129c0565b6040518963ffffffff1660e01b8152600401610f5c9796959493929190612a16565b5f604051808303818588803b158015610f73575f5ffd5b505af1158015610f85573d5f5f3e3d5ffd5b5050505050505b600101610e93565b50336001600160a01b0316638e9e70996040518163ffffffff1660e01b81526004015f60405180830381865afa158015610fd0573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610ff79190810190612a9b565b604051638351eea760e01b8152600401610a7b919061210a565b61101961209c565b604080518082019091525f8082526020820152611037858585611871565b915091505b935093915050565b61104c611479565b60405163ca5eb5e160e01b81526001600160a01b0382811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063ca5eb5e1906024015f604051808303815f87803b1580156110ac575f5ffd5b505af11580156110be573d5f5f3e3d5ffd5b5050505050565b3330146110e55760405163029a949d60e31b815260040160405180910390fd5b610aeb87878787878787610adc565b6110fc611479565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527fd48d879cef83a1c0bdda516f27b13ddb1b3f8bbac1c9e1511bb2a659c242776090602001610c87565b611152611479565b6001600160a01b03811661117b57604051631e4fbdf760e01b81525f6004820152602401610a7b565b611184816116f5565b50565b5f60208201803590600190839061119e9086612549565b63ffffffff16815260208101919091526040015f20541492915050565b6111c88383836001611969565b505050565b5f5f6111d885611a3b565b91508190508381101561103c576040516371c4efed60e01b81526004810182905260248101859052604401610a7b565b63ffffffff81165f90815260016020526040812054806108a55760405163f6ff4fb760e01b815263ffffffff84166004820152602401610a7b565b5f6112546112518787611a71565b90565b90505f61127f8261126d6112688a8a611a88565b611aaa565b61127a60208d018d612549565b611ade565b9050602886111561133f575f6112bb61129e60608c0160408d01612b0f565b6112ab60208d018d612549565b846112b68c8c611b05565b611b4f565b604051633e5ac80960e11b81529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690637cb59012906113109086908d905f908790600401612b2a565b5f604051808303815f87803b158015611327575f5ffd5b505af1158015611339573d5f5f3e3d5ffd5b50505050505b6001600160a01b038216887fefed6d3500546b29533b128a29e3a94d70788727f0507505ac12eaf2e578fd9c61137860208d018d612549565b6040805163ffffffff9092168252602082018690520160405180910390a3505050505050505050565b6001600160a01b038381165f908152600660209081526040808320938616835292905220545f198114611416578181101561140857604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610a7b565b61141684848484035f611969565b50505050565b6001600160a01b03831661144557604051634b637e8f60e11b81525f6004820152602401610a7b565b6001600160a01b03821661146e5760405163ec442f0560e01b81525f6004820152602401610a7b565b6111c8838383611b81565b5f546001600160a01b03163314610ca35760405163118cdaa760e01b8152336004820152602401610a7b565b63ffffffff82165f81815260016020908152604091829020849055815192835282018390527f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b910160405180910390a15050565b6060805f611554856020013561150e86611ca7565b61151b60a08901896129c0565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250611cd292505050565b90935090505f81611566576001611569565b60025b905061158961157b6020880188612549565b826106f660808a018a6129c0565b6004549093506001600160a01b0316801561160d5760405163043a78eb60e01b81526001600160a01b0382169063043a78eb906115cc9088908890600401612b5a565b602060405180830381865afa1580156115e7573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061160b9190612b7e565b505b5050509250929050565b604080518082019091525f80825260208201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ddc28c586040518060a001604052808863ffffffff16815260200161167989611208565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b81526004016116ae929190612b99565b6040805180830381865afa1580156116c8573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116ec9190612c40565b95945050505050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f5b8151811015611815576117758282815181106117645761176461298d565b602002602001015160400151611845565b8181815181106117875761178761298d565b60200260200101516040015160035f8484815181106117a8576117a861298d565b60200260200101515f015163ffffffff1663ffffffff1681526020019081526020015f205f8484815181106117df576117df61298d565b60200260200101516020015161ffff1661ffff1681526020019081526020015f20908161180c9190612c9e565b50600101611746565b507fbe4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b67481604051610c879190612d58565b600281015161ffff8116600314610b2b5781604051639a6d49cd60e01b8152600401610a7b919061210a565b61187961209c565b604080518082019091525f80825260208201525f806118ae33604089013560608a01356118a960208c018c612549565b611d4c565b915091505f5f6118be89846114f9565b90925090506118ea6118d360208b018b612549565b83836118e4368d90038d018d612de6565b8b611d71565b60408051808201909152858152602080820186905282519298509096503391907f85496b760a4b7f8d66384b9df21b381f5d1b1e79f229a47aaf4c232edc2fe59a90611938908d018d612549565b6040805163ffffffff909216825260208201899052810187905260600160405180910390a350505050935093915050565b6001600160a01b0384166119925760405163e602df0560e01b81525f6004820152602401610a7b565b6001600160a01b0383166119bb57604051634a1406b160e11b81525f6004820152602401610a7b565b6001600160a01b038085165f908152600660209081526040808320938716835292905220829055801561141657826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051611a2d91815260200190565b60405180910390a350505050565b5f7f0000000000000000000000000000000000000000000000000000000000000000611a678184612e2b565b6108a59190612e4a565b5f611a7f60208284866128f6565b610b1291612e61565b5f611a976028602084866128f6565b611aa091612e7e565b60c01c9392505050565b5f6108a57f00000000000000000000000000000000000000000000000000000000000000006001600160401b038416612e4a565b5f6001600160a01b038416611af35761dead93505b611afd8484611e77565b509092915050565b6060611b1482602881866128f6565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250929695505050505050565b606084848484604051602001611b689493929190612eb6565b6040516020818303038152906040529050949350505050565b6001600160a01b038316611bab578060075f828254611ba09190612ef0565b90915550611c1b9050565b6001600160a01b0383165f9081526005602052604090205481811015611bfd5760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610a7b565b6001600160a01b0384165f9081526005602052604090209082900390555b6001600160a01b038216611c3757600780548290039055611c55565b6001600160a01b0382165f9081526005602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611c9a91815260200190565b60405180910390a3505050565b5f6108a57f000000000000000000000000000000000000000000000000000000000000000083612e2b565b8051606090151580611d1b578484604051602001611d0792919091825260c01b6001600160c01b031916602082015260280190565b604051602081830303815290604052611d42565b84843385604051602001611d329493929190612f03565b6040516020818303038152906040525b9150935093915050565b5f5f611d598585856111cd565b9092509050611d688683611eab565b94509492505050565b611d7961209c565b5f611d86845f0151611edf565b602085015190915015611da057611da08460200151611f06565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632637a450826040518060a001604052808b63ffffffff168152602001611df08c611208565b81526020018a81526020018981526020015f8960200151111515815250866040518463ffffffff1660e01b8152600401611e2b929190612b99565b60806040518083038185885af1158015611e47573d5f5f3e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190611e6c9190612f2f565b979650505050505050565b6001600160a01b038216611ea05760405163ec442f0560e01b81525f6004820152602401610a7b565b610b2b5f8383611b81565b6001600160a01b038216611ed457604051634b637e8f60e11b81525f6004820152602401610a7b565b610b2b825f83611b81565b5f813414611f02576040516304fb820960e51b8152346004820152602401610a7b565b5090565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f63573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f8791906126ef565b90506001600160a01b038116611fb0576040516329b99a9560e11b815260040160405180910390fd5b6040805133602482018190527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0381811660448501526064808501889052855180860390910181526084909401909452602080840180516001600160e01b03166323b872dd60e01b1781528451610b2b9688169589936114169388935f9283929091839182885af18061204f576040513d5f823e3d81fd5b50505f513d91508115612066578060011415612073565b6001600160a01b0384163b155b1561141657604051635274afe760e01b81526001600160a01b0385166004820152602401610a7b565b60405180606001604052805f81526020015f6001600160401b031681526020016120d760405180604001604052805f81526020015f81525090565b905290565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610b1260208301846120dc565b6001600160a01b0381168114611184575f5ffd5b5f5f60408385031215612141575f5ffd5b823561214c8161211c565b946020939093013593505050565b5f60e0828403121561216a575f5ffd5b50919050565b5f60208284031215612180575f5ffd5b81356001600160401b03811115612195575f5ffd5b610cb28482850161215a565b83518152602080850151908201525f60a0820160a0604084015280855180835260c08501915060c08160051b8601019250602087015f5b828110156122205760bf19878603018452815180518652602081015190506040602087015261220a60408701826120dc565b95505060209384019391909101906001016121d8565b5050855160608601525050602084015160808401529050610cb2565b5f6060828403121561216a575f5ffd5b5f5f83601f84011261225c575f5ffd5b5081356001600160401b03811115612272575f5ffd5b602083019150836020828501011115612289575f5ffd5b9250929050565b5f5f5f5f5f5f5f60e0888a0312156122a6575f5ffd5b6122b0898961223c565b96506060880135955060808801356001600160401b038111156122d1575f5ffd5b6122dd8a828b0161224c565b90965094505060a08801356122f18161211c565b925060c08801356001600160401b0381111561230b575f5ffd5b6123178a828b0161224c565b989b979a50959850939692959293505050565b5f5f5f6060848603121561233c575f5ffd5b83356123478161211c565b925060208401356123578161211c565b929592945050506040919091013590565b803563ffffffff8116811461237b575f5ffd5b919050565b5f5f60408385031215612391575f5ffd5b61214c83612368565b8015158114611184575f5ffd5b5f5f604083850312156123b8575f5ffd5b82356001600160401b038111156123cd575f5ffd5b6123d98582860161215a565b92505060208301356123ea8161239a565b809150509250929050565b8151815260208083015190820152604081016108a5565b803561ffff8116811461237b575f5ffd5b5f5f6040838503121561242e575f5ffd5b61243783612368565b91506124456020840161240c565b90509250929050565b5f6020828403121561245e575f5ffd5b8135610b128161211c565b5f5f5f5f60a0858703121561247c575f5ffd5b612486868661223c565b935060608501356001600160401b038111156124a0575f5ffd5b6124ac8782880161224c565b90945092505060808501356124c08161211c565b939692955090935050565b5f5f83601f8401126124db575f5ffd5b5081356001600160401b038111156124f1575f5ffd5b6020830191508360208260051b8501011115612289575f5ffd5b5f5f6020838503121561251c575f5ffd5b82356001600160401b03811115612531575f5ffd5b61253d858286016124cb565b90969095509350505050565b5f60208284031215612559575f5ffd5b610b1282612368565b5f5f5f5f60608587031215612575575f5ffd5b61257e85612368565b935061258c6020860161240c565b925060408501356001600160401b038111156125a6575f5ffd5b6125b28782880161224c565b95989497509550505050565b5f5f5f83850360808112156125d1575f5ffd5b84356001600160401b038111156125e6575f5ffd5b6125f28782880161215a565b9450506040601f1982011215612606575f5ffd5b50602084019150606084013561261b8161211c565b809150509250925092565b5f60c082019050835182526001600160401b0360208501511660208301526040840151612660604084018280518252602090810151910152565b5082516080830152602083015160a0830152610b12565b5f5f60408385031215612688575f5ffd5b82356126938161211c565b915060208301356123ea8161211c565b5f606082840312156126b3575f5ffd5b610b12838361223c565b600181811c908216806126d157607f821691505b60208210810361216a57634e487b7160e01b5f52602260045260245ffd5b5f602082840312156126ff575f5ffd5b8151610b128161211c565b5f6020828403121561271a575f5ffd5b5051919050565b634e487b7160e01b5f52604160045260245ffd5b604051606081016001600160401b038111828210171561275757612757612721565b60405290565b604080519081016001600160401b038111828210171561275757612757612721565b604051601f8201601f191681016001600160401b03811182821017156127a7576127a7612721565b604052919050565b5f6001600160401b038211156127c7576127c7612721565b50601f01601f191660200190565b5f6001600160401b038311156127ed576127ed612721565b8260051b6127fd6020820161277f565b84815290830190602081019036831115612815575f5ffd5b845b838110156128ec5780356001600160401b03811115612834575f5ffd5b86016060368290031215612846575f5ffd5b61284e612735565b61285782612368565b81526128656020830161240c565b602082015260408201356001600160401b03811115612882575f5ffd5b919091019036601f830112612895575f5ffd5b81356128a86128a3826127af565b61277f565b8181523660208386010111156128bc575f5ffd5b816020850160208301375f6020838301015280604084015250508085525050602083019250602081019050612817565b5095945050505050565b5f5f85851115612904575f5ffd5b83861115612910575f5ffd5b5050820193919092039150565b5f81518060208401855e5f93019283525090919050565b5f61293f828661291d565b838582375f930192835250909392505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b602081525f610cb2602083018486612952565b634e487b7160e01b5f52603260045260245ffd5b5f823561013e198336030181126129b6575f5ffd5b9190910192915050565b5f5f8335601e198436030181126129d5575f5ffd5b8301803591506001600160401b038211156129ee575f5ffd5b602001915036819003821315612289575f5ffd5b6001600160401b0381168114611184575f5ffd5b63ffffffff612a2489612368565b168152602088810135908201525f6040890135612a4081612a02565b6001600160401b03811660408401525087606083015260e06080830152612a6b60e083018789612952565b6001600160a01b03861660a084015282810360c0840152612a8d818587612952565b9a9950505050505050505050565b5f60208284031215612aab575f5ffd5b81516001600160401b03811115612ac0575f5ffd5b8201601f81018413612ad0575f5ffd5b8051612ade6128a3826127af565b818152856020838501011115612af2575f5ffd5b8160208401602083015e5f91810160200191909152949350505050565b5f60208284031215612b1f575f5ffd5b8135610b1281612a02565b60018060a01b038516815283602082015261ffff83166040820152608060608201525f610b8960808301846120dc565b604081525f612b6c60408301856120dc565b82810360208401526116ec81856120dc565b5f60208284031215612b8e575f5ffd5b8151610b128161239a565b6040815263ffffffff8351166040820152602083015160608201525f604084015160a06080840152612bce60e08401826120dc565b90506060850151603f198483030160a0850152612beb82826120dc565b60809690960151151560c08501525050506001600160a01b039190911660209091015290565b5f60408284031215612c21575f5ffd5b612c2961275d565b825181526020928301519281019290925250919050565b5f60408284031215612c50575f5ffd5b610b128383612c11565b601f8211156111c857805f5260205f20601f840160051c81016020851015612c7f5750805b601f840160051c820191505b818110156110be575f8155600101612c8b565b81516001600160401b03811115612cb757612cb7612721565b612ccb81612cc584546126bd565b84612c5a565b6020601f821160018114612cfd575f8315612ce65750848201515b5f19600385901b1c1916600184901b1784556110be565b5f84815260208120601f198516915b82811015612d2c5787850151825560209485019460019092019101612d0c565b5084821015612d4957868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b82811015612dda57603f19878603018452815163ffffffff815116865261ffff60208201511660208701526040810151905060606040870152612dc460608701826120dc565b9550506020938401939190910190600101612d7e565b50929695505050505050565b5f6040828403128015612df7575f5ffd5b50612e0061275d565b823581526020928301359281019290925250919050565b634e487b7160e01b5f52601160045260245ffd5b5f82612e4557634e487b7160e01b5f52601260045260245ffd5b500490565b80820281158282048414176108a5576108a5612e17565b803560208310156108a5575f19602084900360031b1b1692915050565b80356001600160c01b03198116906008841015612eaf576001600160c01b0319600885900360031b81901b82161691505b5092915050565b60c085901b6001600160c01b031916815260e084901b6001600160e01b0319166008820152600c81018390525f610b89602c83018461291d565b808201808211156108a5576108a5612e17565b8481526001600160401b0360c01b8460c01b1660208201528260288201525f610b89604883018461291d565b5f6080828403128015612f40575f5ffd5b50612f49612735565b825181526020830151612f5b81612a02565b6020820152612f6d8460408501612c11565b6040820152939250505056fea26469706673582212200619beffdfde08e0ea967bb64cc5966cd86340bd85f617c1f5ba87e5d29e9e9264736f6c634300081c0033
Deployed Bytecode
0x608060405260043610610254575f3560e01c8063715018a61161013f578063bb0b6a53116100b3578063d045a0dc11610078578063d045a0dc1461074e578063d424388514610761578063dd62ed3e14610780578063f2fde38b146107c4578063fc0c546a14610474578063ff7bd03d146107e3575f5ffd5b8063bb0b6a53146106b1578063bc70b354146106dc578063bd815db0146106fb578063c7c7f5b31461070e578063ca5eb5e11461072f575f5ffd5b806395d89b411161010457806395d89b41146105fb578063963efcaa1461060f5780639f68b96414610642578063a9059cbb14610654578063b731ea0a14610673578063b98bd07014610692575f5ffd5b8063715018a6146105605780637d25a05e1461057457806382413eac146105ad578063857749b0146105cc5780638da5cb5b146105df575f5ffd5b806323b872dd116101d657806352ae28791161019b57806352ae2879146104745780635535d461146104865780635a0dfe4d146104a55780635e280f11146104da5780636fc1b31e1461050d57806370a082311461052c575f5ffd5b806323b872dd146103cb578063313ce567146103ea57806332cb6b0c1461040b5780633400288b146104295780633b6f743b14610448575f5ffd5b8063134d4f251161021c578063134d4f251461032b578063156a0d0f1461035257806317442b701461037857806318160ddd146103995780631f5e1334146103b7575f5ffd5b806306fdde0314610258578063095ea7b3146102825780630d35b415146102b1578063111ecdad146102df57806313137d6514610316575b5f5ffd5b348015610263575f5ffd5b5061026c610802565b604051610279919061210a565b60405180910390f35b34801561028d575f5ffd5b506102a161029c366004612130565b610892565b6040519015158152602001610279565b3480156102bc575f5ffd5b506102d06102cb366004612170565b6108ab565b604051610279939291906121a1565b3480156102ea575f5ffd5b506004546102fe906001600160a01b031681565b6040516001600160a01b039091168152602001610279565b610329610324366004612290565b610a34565b005b348015610336575f5ffd5b5061033f600281565b60405161ffff9091168152602001610279565b34801561035d575f5ffd5b506040805162b9270b60e21b81526001602082015201610279565b348015610383575f5ffd5b5060408051600181526002602082015201610279565b3480156103a4575f5ffd5b506007545b604051908152602001610279565b3480156103c2575f5ffd5b5061033f600181565b3480156103d6575f5ffd5b506102a16103e536600461232a565b610af4565b3480156103f5575f5ffd5b5060125b60405160ff9091168152602001610279565b348015610416575f5ffd5b506103a96a084595161401484a00000081565b348015610434575f5ffd5b50610329610443366004612380565b610b19565b348015610453575f5ffd5b506104676104623660046123a7565b610b2f565b60405161027991906123f5565b34801561047f575f5ffd5b50306102fe565b348015610491575f5ffd5b5061026c6104a036600461241d565b610b93565b3480156104b0575f5ffd5b506102a16104bf366004612380565b63ffffffff919091165f908152600160205260409020541490565b3480156104e5575f5ffd5b506102fe7f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b81565b348015610518575f5ffd5b5061032961052736600461244e565b610c35565b348015610537575f5ffd5b506103a961054636600461244e565b6001600160a01b03165f9081526005602052604090205490565b34801561056b575f5ffd5b50610329610c92565b34801561057f575f5ffd5b5061059561058e366004612380565b5f92915050565b6040516001600160401b039091168152602001610279565b3480156105b8575f5ffd5b506102a16105c7366004612469565b610ca5565b3480156105d7575f5ffd5b5060066103f9565b3480156105ea575f5ffd5b505f546001600160a01b03166102fe565b348015610606575f5ffd5b5061026c610cba565b34801561061a575f5ffd5b506103a97f000000000000000000000000000000000000000000000000000000e8d4a5100081565b34801561064d575f5ffd5b505f6102a1565b34801561065f575f5ffd5b506102a161066e366004612130565b610cc9565b34801561067e575f5ffd5b506002546102fe906001600160a01b031681565b34801561069d575f5ffd5b506103296106ac36600461250b565b610cd6565b3480156106bc575f5ffd5b506103a96106cb366004612549565b60016020525f908152604090205481565b3480156106e7575f5ffd5b5061026c6106f6366004612562565b610cf0565b61032961070936600461250b565b610e91565b61072161071c3660046125be565b611011565b604051610279929190612626565b34801561073a575f5ffd5b5061032961074936600461244e565b611044565b61032961075c366004612290565b6110c5565b34801561076c575f5ffd5b5061032961077b36600461244e565b6110f4565b34801561078b575f5ffd5b506103a961079a366004612677565b6001600160a01b039182165f90815260066020908152604080832093909416825291909152205490565b3480156107cf575f5ffd5b506103296107de36600461244e565b61114a565b3480156107ee575f5ffd5b506102a16107fd3660046126a3565b611187565b606060088054610811906126bd565b80601f016020809104026020016040519081016040528092919081815260200182805461083d906126bd565b80156108885780601f1061085f57610100808354040283529160200191610888565b820191905f5260205f20905b81548152906001019060200180831161086b57829003601f168201915b5050505050905090565b5f3361089f8185856111bb565b60019150505b92915050565b604080518082019091525f808252602082015260606108db60405180604001604052805f81526020015f81525090565b5f5f90505f306001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561091c573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061094091906126ef565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561097b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061099f919061270a565b604080518082018252848152602080820184905282515f808252918101909352909750919250906109f2565b604080518082019091525f8152606060208201528152602001906001900390816109cb5790505b5093505f80610a16604089013560608a0135610a1160208c018c612549565b6111cd565b60408051808201909152918252602082015296989597505050505050565b7f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b6001600160a01b03163314610a84576040516391ac5e4f60e01b81523360048201526024015b60405180910390fd5b60208701803590610a9e90610a99908a612549565b611208565b14610adc57610ab06020880188612549565b60405163309afaf360e21b815263ffffffff909116600482015260208801356024820152604401610a7b565b610aeb87878787878787611243565b50505050505050565b5f33610b018582856113a1565b610b0c85858561141c565b60019150505b9392505050565b610b21611479565b610b2b82826114a5565b5050565b604080518082019091525f80825260208201525f610b5d60408501356060860135610a116020880188612549565b9150505f5f610b6c86846114f9565b9092509050610b89610b816020880188612549565b838388611617565b9695505050505050565b600360209081525f928352604080842090915290825290208054610bb6906126bd565b80601f0160208091040260200160405190810160405280929190818152602001828054610be2906126bd565b8015610c2d5780601f10610c0457610100808354040283529160200191610c2d565b820191905f5260205f20905b815481529060010190602001808311610c1057829003601f168201915b505050505081565b610c3d611479565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527ff0be4f1e87349231d80c36b33f9e8639658eeaf474014dee15a3e6a4d4414197906020015b60405180910390a150565b610c9a611479565b610ca35f6116f5565b565b6001600160a01b03811630145b949350505050565b606060098054610811906126bd565b5f3361089f81858561141c565b610cde611479565b610b2b610ceb82846127d5565b611744565b63ffffffff84165f90815260036020908152604080832061ffff87168452909152812080546060929190610d23906126bd565b80601f0160208091040260200160405190810160405280929190818152602001828054610d4f906126bd565b8015610d9a5780601f10610d7157610100808354040283529160200191610d9a565b820191905f5260205f20905b815481529060010190602001808311610d7d57829003601f168201915b5050505050905080515f03610de85783838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250929450610cb29350505050565b5f839003610df7579050610cb2565b60028310610e7457610e3d84848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061184592505050565b80610e4b84600281886128f6565b604051602001610e5d93929190612934565b604051602081830303815290604052915050610cb2565b8383604051639a6d49cd60e01b8152600401610a7b92919061297a565b5f5b81811015610f945736838383818110610eae57610eae61298d565b9050602002810190610ec091906129a1565b9050610ef2610ed26020830183612549565b602083013563ffffffff919091165f908152600160205260409020541490565b610efc5750610f8c565b3063d045a0dc60c08301358360a0810135610f1b6101008301836129c0565b610f2c610100890160e08a0161244e565b610f3a6101208a018a6129c0565b6040518963ffffffff1660e01b8152600401610f5c9796959493929190612a16565b5f604051808303818588803b158015610f73575f5ffd5b505af1158015610f85573d5f5f3e3d5ffd5b5050505050505b600101610e93565b50336001600160a01b0316638e9e70996040518163ffffffff1660e01b81526004015f60405180830381865afa158015610fd0573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610ff79190810190612a9b565b604051638351eea760e01b8152600401610a7b919061210a565b61101961209c565b604080518082019091525f8082526020820152611037858585611871565b915091505b935093915050565b61104c611479565b60405163ca5eb5e160e01b81526001600160a01b0382811660048301527f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b169063ca5eb5e1906024015f604051808303815f87803b1580156110ac575f5ffd5b505af11580156110be573d5f5f3e3d5ffd5b5050505050565b3330146110e55760405163029a949d60e31b815260040160405180910390fd5b610aeb87878787878787610adc565b6110fc611479565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527fd48d879cef83a1c0bdda516f27b13ddb1b3f8bbac1c9e1511bb2a659c242776090602001610c87565b611152611479565b6001600160a01b03811661117b57604051631e4fbdf760e01b81525f6004820152602401610a7b565b611184816116f5565b50565b5f60208201803590600190839061119e9086612549565b63ffffffff16815260208101919091526040015f20541492915050565b6111c88383836001611969565b505050565b5f5f6111d885611a3b565b91508190508381101561103c576040516371c4efed60e01b81526004810182905260248101859052604401610a7b565b63ffffffff81165f90815260016020526040812054806108a55760405163f6ff4fb760e01b815263ffffffff84166004820152602401610a7b565b5f6112546112518787611a71565b90565b90505f61127f8261126d6112688a8a611a88565b611aaa565b61127a60208d018d612549565b611ade565b9050602886111561133f575f6112bb61129e60608c0160408d01612b0f565b6112ab60208d018d612549565b846112b68c8c611b05565b611b4f565b604051633e5ac80960e11b81529091506001600160a01b037f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b1690637cb59012906113109086908d905f908790600401612b2a565b5f604051808303815f87803b158015611327575f5ffd5b505af1158015611339573d5f5f3e3d5ffd5b50505050505b6001600160a01b038216887fefed6d3500546b29533b128a29e3a94d70788727f0507505ac12eaf2e578fd9c61137860208d018d612549565b6040805163ffffffff9092168252602082018690520160405180910390a3505050505050505050565b6001600160a01b038381165f908152600660209081526040808320938616835292905220545f198114611416578181101561140857604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610a7b565b61141684848484035f611969565b50505050565b6001600160a01b03831661144557604051634b637e8f60e11b81525f6004820152602401610a7b565b6001600160a01b03821661146e5760405163ec442f0560e01b81525f6004820152602401610a7b565b6111c8838383611b81565b5f546001600160a01b03163314610ca35760405163118cdaa760e01b8152336004820152602401610a7b565b63ffffffff82165f81815260016020908152604091829020849055815192835282018390527f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b910160405180910390a15050565b6060805f611554856020013561150e86611ca7565b61151b60a08901896129c0565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250611cd292505050565b90935090505f81611566576001611569565b60025b905061158961157b6020880188612549565b826106f660808a018a6129c0565b6004549093506001600160a01b0316801561160d5760405163043a78eb60e01b81526001600160a01b0382169063043a78eb906115cc9088908890600401612b5a565b602060405180830381865afa1580156115e7573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061160b9190612b7e565b505b5050509250929050565b604080518082019091525f80825260208201527f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b6001600160a01b031663ddc28c586040518060a001604052808863ffffffff16815260200161167989611208565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b81526004016116ae929190612b99565b6040805180830381865afa1580156116c8573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116ec9190612c40565b95945050505050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f5b8151811015611815576117758282815181106117645761176461298d565b602002602001015160400151611845565b8181815181106117875761178761298d565b60200260200101516040015160035f8484815181106117a8576117a861298d565b60200260200101515f015163ffffffff1663ffffffff1681526020019081526020015f205f8484815181106117df576117df61298d565b60200260200101516020015161ffff1661ffff1681526020019081526020015f20908161180c9190612c9e565b50600101611746565b507fbe4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b67481604051610c879190612d58565b600281015161ffff8116600314610b2b5781604051639a6d49cd60e01b8152600401610a7b919061210a565b61187961209c565b604080518082019091525f80825260208201525f806118ae33604089013560608a01356118a960208c018c612549565b611d4c565b915091505f5f6118be89846114f9565b90925090506118ea6118d360208b018b612549565b83836118e4368d90038d018d612de6565b8b611d71565b60408051808201909152858152602080820186905282519298509096503391907f85496b760a4b7f8d66384b9df21b381f5d1b1e79f229a47aaf4c232edc2fe59a90611938908d018d612549565b6040805163ffffffff909216825260208201899052810187905260600160405180910390a350505050935093915050565b6001600160a01b0384166119925760405163e602df0560e01b81525f6004820152602401610a7b565b6001600160a01b0383166119bb57604051634a1406b160e11b81525f6004820152602401610a7b565b6001600160a01b038085165f908152600660209081526040808320938716835292905220829055801561141657826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051611a2d91815260200190565b60405180910390a350505050565b5f7f000000000000000000000000000000000000000000000000000000e8d4a51000611a678184612e2b565b6108a59190612e4a565b5f611a7f60208284866128f6565b610b1291612e61565b5f611a976028602084866128f6565b611aa091612e7e565b60c01c9392505050565b5f6108a57f000000000000000000000000000000000000000000000000000000e8d4a510006001600160401b038416612e4a565b5f6001600160a01b038416611af35761dead93505b611afd8484611e77565b509092915050565b6060611b1482602881866128f6565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250929695505050505050565b606084848484604051602001611b689493929190612eb6565b6040516020818303038152906040529050949350505050565b6001600160a01b038316611bab578060075f828254611ba09190612ef0565b90915550611c1b9050565b6001600160a01b0383165f9081526005602052604090205481811015611bfd5760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610a7b565b6001600160a01b0384165f9081526005602052604090209082900390555b6001600160a01b038216611c3757600780548290039055611c55565b6001600160a01b0382165f9081526005602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611c9a91815260200190565b60405180910390a3505050565b5f6108a57f000000000000000000000000000000000000000000000000000000e8d4a5100083612e2b565b8051606090151580611d1b578484604051602001611d0792919091825260c01b6001600160c01b031916602082015260280190565b604051602081830303815290604052611d42565b84843385604051602001611d329493929190612f03565b6040516020818303038152906040525b9150935093915050565b5f5f611d598585856111cd565b9092509050611d688683611eab565b94509492505050565b611d7961209c565b5f611d86845f0151611edf565b602085015190915015611da057611da08460200151611f06565b7f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b6001600160a01b0316632637a450826040518060a001604052808b63ffffffff168152602001611df08c611208565b81526020018a81526020018981526020015f8960200151111515815250866040518463ffffffff1660e01b8152600401611e2b929190612b99565b60806040518083038185885af1158015611e47573d5f5f3e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190611e6c9190612f2f565b979650505050505050565b6001600160a01b038216611ea05760405163ec442f0560e01b81525f6004820152602401610a7b565b610b2b5f8383611b81565b6001600160a01b038216611ed457604051634b637e8f60e11b81525f6004820152602401610a7b565b610b2b825f83611b81565b5f813414611f02576040516304fb820960e51b8152346004820152602401610a7b565b5090565b5f7f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b6001600160a01b031663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f63573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f8791906126ef565b90506001600160a01b038116611fb0576040516329b99a9560e11b815260040160405180910390fd5b6040805133602482018190527f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b6001600160a01b0381811660448501526064808501889052855180860390910181526084909401909452602080840180516001600160e01b03166323b872dd60e01b1781528451610b2b9688169589936114169388935f9283929091839182885af18061204f576040513d5f823e3d81fd5b50505f513d91508115612066578060011415612073565b6001600160a01b0384163b155b1561141657604051635274afe760e01b81526001600160a01b0385166004820152602401610a7b565b60405180606001604052805f81526020015f6001600160401b031681526020016120d760405180604001604052805f81526020015f81525090565b905290565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610b1260208301846120dc565b6001600160a01b0381168114611184575f5ffd5b5f5f60408385031215612141575f5ffd5b823561214c8161211c565b946020939093013593505050565b5f60e0828403121561216a575f5ffd5b50919050565b5f60208284031215612180575f5ffd5b81356001600160401b03811115612195575f5ffd5b610cb28482850161215a565b83518152602080850151908201525f60a0820160a0604084015280855180835260c08501915060c08160051b8601019250602087015f5b828110156122205760bf19878603018452815180518652602081015190506040602087015261220a60408701826120dc565b95505060209384019391909101906001016121d8565b5050855160608601525050602084015160808401529050610cb2565b5f6060828403121561216a575f5ffd5b5f5f83601f84011261225c575f5ffd5b5081356001600160401b03811115612272575f5ffd5b602083019150836020828501011115612289575f5ffd5b9250929050565b5f5f5f5f5f5f5f60e0888a0312156122a6575f5ffd5b6122b0898961223c565b96506060880135955060808801356001600160401b038111156122d1575f5ffd5b6122dd8a828b0161224c565b90965094505060a08801356122f18161211c565b925060c08801356001600160401b0381111561230b575f5ffd5b6123178a828b0161224c565b989b979a50959850939692959293505050565b5f5f5f6060848603121561233c575f5ffd5b83356123478161211c565b925060208401356123578161211c565b929592945050506040919091013590565b803563ffffffff8116811461237b575f5ffd5b919050565b5f5f60408385031215612391575f5ffd5b61214c83612368565b8015158114611184575f5ffd5b5f5f604083850312156123b8575f5ffd5b82356001600160401b038111156123cd575f5ffd5b6123d98582860161215a565b92505060208301356123ea8161239a565b809150509250929050565b8151815260208083015190820152604081016108a5565b803561ffff8116811461237b575f5ffd5b5f5f6040838503121561242e575f5ffd5b61243783612368565b91506124456020840161240c565b90509250929050565b5f6020828403121561245e575f5ffd5b8135610b128161211c565b5f5f5f5f60a0858703121561247c575f5ffd5b612486868661223c565b935060608501356001600160401b038111156124a0575f5ffd5b6124ac8782880161224c565b90945092505060808501356124c08161211c565b939692955090935050565b5f5f83601f8401126124db575f5ffd5b5081356001600160401b038111156124f1575f5ffd5b6020830191508360208260051b8501011115612289575f5ffd5b5f5f6020838503121561251c575f5ffd5b82356001600160401b03811115612531575f5ffd5b61253d858286016124cb565b90969095509350505050565b5f60208284031215612559575f5ffd5b610b1282612368565b5f5f5f5f60608587031215612575575f5ffd5b61257e85612368565b935061258c6020860161240c565b925060408501356001600160401b038111156125a6575f5ffd5b6125b28782880161224c565b95989497509550505050565b5f5f5f83850360808112156125d1575f5ffd5b84356001600160401b038111156125e6575f5ffd5b6125f28782880161215a565b9450506040601f1982011215612606575f5ffd5b50602084019150606084013561261b8161211c565b809150509250925092565b5f60c082019050835182526001600160401b0360208501511660208301526040840151612660604084018280518252602090810151910152565b5082516080830152602083015160a0830152610b12565b5f5f60408385031215612688575f5ffd5b82356126938161211c565b915060208301356123ea8161211c565b5f606082840312156126b3575f5ffd5b610b12838361223c565b600181811c908216806126d157607f821691505b60208210810361216a57634e487b7160e01b5f52602260045260245ffd5b5f602082840312156126ff575f5ffd5b8151610b128161211c565b5f6020828403121561271a575f5ffd5b5051919050565b634e487b7160e01b5f52604160045260245ffd5b604051606081016001600160401b038111828210171561275757612757612721565b60405290565b604080519081016001600160401b038111828210171561275757612757612721565b604051601f8201601f191681016001600160401b03811182821017156127a7576127a7612721565b604052919050565b5f6001600160401b038211156127c7576127c7612721565b50601f01601f191660200190565b5f6001600160401b038311156127ed576127ed612721565b8260051b6127fd6020820161277f565b84815290830190602081019036831115612815575f5ffd5b845b838110156128ec5780356001600160401b03811115612834575f5ffd5b86016060368290031215612846575f5ffd5b61284e612735565b61285782612368565b81526128656020830161240c565b602082015260408201356001600160401b03811115612882575f5ffd5b919091019036601f830112612895575f5ffd5b81356128a86128a3826127af565b61277f565b8181523660208386010111156128bc575f5ffd5b816020850160208301375f6020838301015280604084015250508085525050602083019250602081019050612817565b5095945050505050565b5f5f85851115612904575f5ffd5b83861115612910575f5ffd5b5050820193919092039150565b5f81518060208401855e5f93019283525090919050565b5f61293f828661291d565b838582375f930192835250909392505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b602081525f610cb2602083018486612952565b634e487b7160e01b5f52603260045260245ffd5b5f823561013e198336030181126129b6575f5ffd5b9190910192915050565b5f5f8335601e198436030181126129d5575f5ffd5b8301803591506001600160401b038211156129ee575f5ffd5b602001915036819003821315612289575f5ffd5b6001600160401b0381168114611184575f5ffd5b63ffffffff612a2489612368565b168152602088810135908201525f6040890135612a4081612a02565b6001600160401b03811660408401525087606083015260e06080830152612a6b60e083018789612952565b6001600160a01b03861660a084015282810360c0840152612a8d818587612952565b9a9950505050505050505050565b5f60208284031215612aab575f5ffd5b81516001600160401b03811115612ac0575f5ffd5b8201601f81018413612ad0575f5ffd5b8051612ade6128a3826127af565b818152856020838501011115612af2575f5ffd5b8160208401602083015e5f91810160200191909152949350505050565b5f60208284031215612b1f575f5ffd5b8135610b1281612a02565b60018060a01b038516815283602082015261ffff83166040820152608060608201525f610b8960808301846120dc565b604081525f612b6c60408301856120dc565b82810360208401526116ec81856120dc565b5f60208284031215612b8e575f5ffd5b8151610b128161239a565b6040815263ffffffff8351166040820152602083015160608201525f604084015160a06080840152612bce60e08401826120dc565b90506060850151603f198483030160a0850152612beb82826120dc565b60809690960151151560c08501525050506001600160a01b039190911660209091015290565b5f60408284031215612c21575f5ffd5b612c2961275d565b825181526020928301519281019290925250919050565b5f60408284031215612c50575f5ffd5b610b128383612c11565b601f8211156111c857805f5260205f20601f840160051c81016020851015612c7f5750805b601f840160051c820191505b818110156110be575f8155600101612c8b565b81516001600160401b03811115612cb757612cb7612721565b612ccb81612cc584546126bd565b84612c5a565b6020601f821160018114612cfd575f8315612ce65750848201515b5f19600385901b1c1916600184901b1784556110be565b5f84815260208120601f198516915b82811015612d2c5787850151825560209485019460019092019101612d0c565b5084821015612d4957868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b82811015612dda57603f19878603018452815163ffffffff815116865261ffff60208201511660208701526040810151905060606040870152612dc460608701826120dc565b9550506020938401939190910190600101612d7e565b50929695505050505050565b5f6040828403128015612df7575f5ffd5b50612e0061275d565b823581526020928301359281019290925250919050565b634e487b7160e01b5f52601160045260245ffd5b5f82612e4557634e487b7160e01b5f52601260045260245ffd5b500490565b80820281158282048414176108a5576108a5612e17565b803560208310156108a5575f19602084900360031b1b1692915050565b80356001600160c01b03198116906008841015612eaf576001600160c01b0319600885900360031b81901b82161691505b5092915050565b60c085901b6001600160c01b031916815260e084901b6001600160e01b0319166008820152600c81018390525f610b89602c83018461291d565b808201808211156108a5576108a5612e17565b8481526001600160401b0360c01b8460c01b1660208201528260288201525f610b89604883018461291d565b5f6080828403128015612f40575f5ffd5b50612f49612735565b825181526020830151612f5b81612a02565b6020820152612f6d8460408501612c11565b6040820152939250505056fea26469706673582212200619beffdfde08e0ea967bb64cc5966cd86340bd85f617c1f5ba87e5d29e9e9264736f6c634300081c0033
Deployed Bytecode Sourcemap
136819:474:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16186:91;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;18479:190;;;;;;;;;;-1:-1:-1;18479:190:0;;;;;:::i;:::-;;:::i;:::-;;;1206:14:1;;1199:22;1181:41;;1169:2;1154:18;18479:190:0;1041:187:1;117767:1301:0;;;;;;;;;;-1:-1:-1;117767:1301:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;114860:27::-;;;;;;;;;;-1:-1:-1;114860:27:0;;;;-1:-1:-1;;;;;114860:27:0;;;;;;-1:-1:-1;;;;;3384:32:1;;;3366:51;;3354:2;3339:18;114860:27:0;3220:203:1;73073:723:0;;;;;;:::i;:::-;;:::i;:::-;;114731:40;;;;;;;;;;;;114770:1;114731:40;;;;;5213:6:1;5201:19;;;5183:38;;5171:2;5156:18;114731:40:0;5039:188:1;116029:142:0;;;;;;;;;;-1:-1:-1;116029:142:0;;;-1:-1:-1;;;5402:52:1;;116161:1:0;5485:2:1;5470:18;;5463:59;5375:18;116029:142:0;5232:296:1;75312:243:0;;;;;;;;;;-1:-1:-1;75312:243:0;;;62224:1;5703:50:1;;69306:1:0;5784:2:1;5769:18;;5762:59;5676:18;75312:243:0;5533:294:1;17288:99:0;;;;;;;;;;-1:-1:-1;17367:12:0;;17288:99;;;5978:25:1;;;5966:2;5951:18;17288:99:0;5832:177:1;114693:31:0;;;;;;;;;;;;114723:1;114693:31;;19279:249;;;;;;;;;;-1:-1:-1;19279:249:0;;;;;:::i;:::-;;:::i;17139:84::-;;;;;;;;;;-1:-1:-1;17213:2:0;17139:84;;;6699:4:1;6687:17;;;6669:36;;6657:2;6642:18;17139:84:0;6527:184:1;136863:56:0;;;;;;;;;;;;136900:19;136863:56;;59928:110;;;;;;;;;;-1:-1:-1;59928:110:0;;;;;:::i;:::-;;:::i;119531:787::-;;;;;;;;;;-1:-1:-1;119531:787:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;96127:95::-;;;;;;;;;;-1:-1:-1;96209:4:0;96127:95;;77537:93;;;;;;;;;;-1:-1:-1;77537:93:0;;;;;:::i;:::-;;:::i;128965:134::-;;;;;;;;;;-1:-1:-1;128965:134:0;;;;;:::i;:::-;129071:11;;;;;129047:4;129071:11;;;:5;:11;;;;;;:20;;128965:134;58621:46;;;;;;;;;;;;;;;117236:166;;;;;;;;;;-1:-1:-1;117236:166:0;;;;;:::i;:::-;;:::i;17450:118::-;;;;;;;;;;-1:-1:-1;17450:118:0;;;;;:::i;:::-;-1:-1:-1;;;;;17542:18:0;17515:7;17542:18;;;:9;:18;;;;;;;17450:118;3361:103;;;;;;;;;;;;;:::i;72195:130::-;;;;;;;;;;-1:-1:-1;72195:130:0;;;;;:::i;:::-;72284:12;72195:130;;;;;;;;-1:-1:-1;;;;;9365:31:1;;;9347:50;;9335:2;9320:18;72195:130:0;9203:200:1;70669:222:0;;;;;;;;;;-1:-1:-1;70669:222:0;;;;;:::i;:::-;;:::i;116790:89::-;;;;;;;;;;-1:-1:-1;116870:1:0;116790:89;;2686:87;;;;;;;;;;-1:-1:-1;2732:7:0;2759:6;-1:-1:-1;;;;;2759:6:0;2686:87;;16396:95;;;;;;;;;;;;;:::i;114382:46::-;;;;;;;;;;;;;;;134675:96;;;;;;;;;;-1:-1:-1;134734:4:0;134675:96;;17773:182;;;;;;;;;;-1:-1:-1;17773:182:0;;;;;:::i;:::-;;:::i;95802:23::-;;;;;;;;;;-1:-1:-1;95802:23:0;;;;-1:-1:-1;;;;;95802:23:0;;;78402:158;;;;;;;;;;-1:-1:-1;78402:158:0;;;;;:::i;:::-;;:::i;58747:48::-;;;;;;;;;;-1:-1:-1;58747:48:0;;;;;:::i;:::-;;;;;;;;;;;;;;80556:1003;;;;;;;;;;-1:-1:-1;80556:1003:0;;;;;:::i;:::-;;:::i;96971:1358::-;;;;;;:::i;:::-;;:::i;121023:296::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;61493:107::-;;;;;;;;;;-1:-1:-1;61493:107:0;;;;;:::i;:::-;;:::i;98991:419::-;;;;;;:::i;:::-;;:::i;96360:142::-;;;;;;;;;;-1:-1:-1;96360:142:0;;;;;:::i;:::-;;:::i;18018:::-;;;;;;;;;;-1:-1:-1;18018:142:0;;;;;:::i;:::-;-1:-1:-1;;;;;18125:18:0;;;18098:7;18125:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;18018:142;3619:220;;;;;;;;;;-1:-1:-1;3619:220:0;;;;;:::i;:::-;;:::i;71444:151::-;;;;;;;;;;-1:-1:-1;71444:151:0;;;;;:::i;:::-;;:::i;16186:91::-;16231:13;16264:5;16257:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16186:91;:::o;18479:190::-;18552:4;775:10;18608:31;775:10;18624:7;18633:5;18608:8;:31::i;:::-;18657:4;18650:11;;;18479:190;;;;;:::o;117767:1301::-;-1:-1:-1;;;;;;;;;;;;;;;;;117925:35:0;117962:28;-1:-1:-1;;;;;;;;;;;;;;;;;;;117962:28:0;118008:19;118030:1;118008:23;;118083:19;118112:4;-1:-1:-1;;;;;118112:10:0;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;118105:32:0;;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;118202;;;;;;;;;;;;;;;;;;118356:21;;-1:-1:-1;118356:21:0;;;;;;;;;118202:34;;-1:-1:-1;118202:34:0;;-1:-1:-1;118356:21:0;;;;-1:-1:-1;;;;;;;;;;;;;;;;;118356:21:0;;;;;;;;;;;;;;;-1:-1:-1;118340:37:0;-1:-1:-1;118820:20:0;;118870:124;118895:19;;;;118929:22;;;;118966:17;;;;118895:10;118966:17;:::i;:::-;118870:10;:124::i;:::-;119018:42;;;;;;;;;;;;;;;;117767:1301;;;;-1:-1:-1;;;;;;117767:1301:0:o;73073:723::-;73394:8;-1:-1:-1;;;;;73386:31:0;73407:10;73386:31;73382:68;;73426:24;;-1:-1:-1;;;73426:24:0;;73439:10;73426:24;;;3366:51:1;3339:18;;73426:24:0;;;;;;;;73382:68;73589:14;;;;;;73553:32;;73570:14;;73589:7;73570:14;:::i;:::-;73553:16;:32::i;:::-;:50;73549:103;;73621:14;;;;:7;:14;:::i;:::-;73612:40;;-1:-1:-1;;;73612:40:0;;15548:10:1;15536:23;;;73612:40:0;;;15518:42:1;73637:14:0;;;;15576:18:1;;;15569:34;15491:18;;73612:40:0;15346:263:1;73549:103:0;73729:59;73740:7;73749:5;73756:8;;73766:9;73777:10;;73729;:59::i;:::-;73073:723;;;;;;;:::o;19279:249::-;19366:4;775:10;19424:37;19440:4;775:10;19455:5;19424:15;:37::i;:::-;19472:26;19482:4;19488:2;19492:5;19472:9;:26::i;:::-;19516:4;19509:11;;;19279:249;;;;;;:::o;59928:110::-;2572:13;:11;:13::i;:::-;60009:21:::1;60018:4;60024:5;60009:8;:21::i;:::-;59928:110:::0;;:::o;119531:787::-;-1:-1:-1;;;;;;;;;;;;;;;;;119871:24:0;119899:74;119910:19;;;;119931:22;;;;119955:17;;;;119910:10;119955:17;:::i;119899:74::-;119868:105;;;120065:20;120087;120111:49;120131:10;120143:16;120111:19;:49::i;:::-;120064:96;;-1:-1:-1;120064:96:0;-1:-1:-1;120252:58:0;120259:17;;;;:10;:17;:::i;:::-;120278:7;120287;120296:13;120252:6;:58::i;:::-;120245:65;119531:787;-1:-1:-1;;;;;;119531:787:0:o;77537:93::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;117236:166::-;2572:13;:11;:13::i;:::-;117320:12:::1;:28:::0;;-1:-1:-1;;;;;;117320:28:0::1;-1:-1:-1::0;;;;;117320:28:0;::::1;::::0;;::::1;::::0;;;117364:30:::1;::::0;3366:51:1;;;117364:30:0::1;::::0;3354:2:1;3339:18;117364:30:0::1;;;;;;;;117236:166:::0;:::o;3361:103::-;2572:13;:11;:13::i;:::-;3426:30:::1;3453:1;3426:18;:30::i;:::-;3361:103::o:0;70669:222::-;-1:-1:-1;;;;;70859:24:0;;70878:4;70859:24;70669:222;;;;;;;:::o;16396:95::-;16443:13;16476:7;16469:14;;;;;:::i;17773:182::-;17842:4;775:10;17898:27;775:10;17915:2;17919:5;17898:9;:27::i;78402:158::-;2572:13;:11;:13::i;:::-;78515:37:::1;;78535:16:::0;;78515:37:::1;:::i;:::-;:19;:37::i;80556:1003::-:0;80752:21;;;80728;80752;;;:15;:21;;;;;;;;:31;;;;;;;;;;80728:55;;80703:12;;80728:21;80752:31;80728:55;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80915:8;:15;80934:1;80915:20;80911:46;;80944:13;;80937:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;80937:20:0;;-1:-1:-1;80937:20:0;;-1:-1:-1;;;;80937:20:0;80911:46;81045:1;81021:25;;;81017:46;;81055:8;-1:-1:-1;81048:15:0;;81017:46;81213:1;81189:25;;81185:271;;81231:34;81251:13;;81231:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;81231:19:0;;-1:-1:-1;;;81231:34:0:i;:::-;81416:8;81426:17;:13;81440:1;81426:13;;:17;:::i;:::-;81403:41;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;81396:48;;;;;81185:271;81537:13;;81522:29;;-1:-1:-1;;;81522:29:0;;;;;;;;;:::i;96971:1358::-;97073:9;97068:1057;97088:19;;;97068:1057;;;97129:29;97161:8;;97170:1;97161:11;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;97129:43;-1:-1:-1;97258:50:0;97265:20;;;;97129:43;97265:20;:::i;:::-;97287;;;;129071:11;;;;;129047:4;129071:11;;;:5;:11;;;;;;:20;;128965:134;97258:50;97253:65;;97310:8;;;97253:65;97889:4;:22;97920:12;;;;:6;97985:11;;;;98015:14;;;;97920:6;98015:14;:::i;:::-;98048:15;;;;;;;;:::i;:::-;98082:16;;;;:6;:16;:::i;:::-;97889:224;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97114:1011;97068:1057;97109:3;;97068:1057;;;;98285:10;-1:-1:-1;;;;;98275:43:0;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;98275:45:0;;;;;;;;;;;;:::i;:::-;98258:63;;-1:-1:-1;;;98258:63:0;;;;;;;;:::i;121023:296::-;121188:34;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;121272:39:0;121278:10;121290:4;121296:14;121272:5;:39::i;:::-;121265:46;;;;121023:296;;;;;;;:::o;61493:107::-;2572:13;:11;:13::i;:::-;61561:31:::1;::::0;-1:-1:-1;;;61561:31:0;;-1:-1:-1;;;;;3384:32:1;;;61561:31:0::1;::::0;::::1;3366:51:1::0;61561:8:0::1;:20;::::0;::::1;::::0;3339:18:1;;61561:31:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61493:107:::0;:::o;98991:419::-;99278:10;99300:4;99278:27;99274:50;;99314:10;;-1:-1:-1;;;99314:10:0;;;;;;;;;;;99274:50;99335:67;99354:7;99363:5;99370:8;;99380:9;99391:10;;99335:18;:67::i;96360:142::-;2572:13;:11;:13::i;:::-;96436:8:::1;:20:::0;;-1:-1:-1;;;;;;96436:20:0::1;-1:-1:-1::0;;;;;96436:20:0;::::1;::::0;;::::1;::::0;;;96472:22:::1;::::0;3366:51:1;;;96472:22:0::1;::::0;3354:2:1;3339:18;96472:22:0::1;3220:203:1::0;3619:220:0;2572:13;:11;:13::i;:::-;-1:-1:-1;;;;;3704:22:0;::::1;3700:93;;3750:31;::::0;-1:-1:-1;;;3750:31:0;;3778:1:::1;3750:31;::::0;::::1;3366:51:1::0;3339:18;;3750:31:0::1;3220:203:1::0;3700:93:0::1;3803:28;3822:8;3803:18;:28::i;:::-;3619:220:::0;:::o;71444:151::-;71526:4;71574:13;;;;;;71550:5;;71526:4;;71556:13;;71574:6;71556:13;:::i;:::-;71550:20;;;;;;;;;;;;;-1:-1:-1;71550:20:0;;:37;;71444:151;-1:-1:-1;;71444:151:0:o;23338:130::-;23423:37;23432:5;23439:7;23448:5;23455:4;23423:8;:37::i;:::-;23338:130;;;:::o;131026:682::-;131172:20;131194:24;131370:22;131382:9;131370:11;:22::i;:::-;131355:37;;131520:12;131501:31;;131605:12;131586:16;:31;131582:119;;;131641:48;;-1:-1:-1;;;131641:48:0;;;;;22881:25:1;;;22922:18;;;22915:34;;;22854:18;;131641:48:0;22707:248:1;60946:200:0;61051:11;;;61016:7;61051:11;;;:5;:11;;;;;;;61073:43;;61104:12;;-1:-1:-1;;;61104:12:0;;23134:10:1;23122:23;;61104:12:0;;;23104:42:1;23077:18;;61104:12:0;22960:192:1;125693:1837:0;126179:17;126199:36;:17;:8;;:15;:17::i;:::-;110032:2;109920:125;126199:36;126179:56;;126370:24;126397:62;126405:9;126416:26;126422:19;:8;;:17;:19::i;:::-;126416:5;:26::i;:::-;126444:14;;;;:7;:14;:::i;:::-;126397:7;:62::i;:::-;126370:89;-1:-1:-1;107311:2:0;-1:-1:-1;;126472:970:0;;;126578:23;126604:180;126648:13;;;;;;;;:::i;:::-;126680:14;;;;:7;:14;:::i;:::-;126713:16;126748:21;:8;;:19;:21::i;:::-;126604:25;:180::i;:::-;127338:92;;-1:-1:-1;;;127338:92:0;;126578:206;;-1:-1:-1;;;;;;127338:8:0;:20;;;;:92;;127359:9;;127370:5;;127377:1;;126578:206;;127338:92;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;126499:943;126472:970;-1:-1:-1;;;;;127459:63:0;;127471:5;127459:63;127478:14;;;;:7;:14;:::i;:::-;127459:63;;;15548:10:1;15536:23;;;15518:42;;15591:2;15576:18;;15569:34;;;15491:18;127459:63:0;;;;;;;126002:1528;;125693:1837;;;;;;;:::o;25070:487::-;-1:-1:-1;;;;;18125:18:0;;;25170:24;18125:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;-1:-1:-1;;25237:37:0;;25233:317;;25314:5;25295:16;:24;25291:132;;;25347:60;;-1:-1:-1;;;25347:60:0;;-1:-1:-1;;;;;24379:32:1;;25347:60:0;;;24361:51:1;24428:18;;;24421:34;;;24471:18;;;24464:34;;;24334:18;;25347:60:0;24159:345:1;25291:132:0;25466:57;25475:5;25482:7;25510:5;25491:16;:24;25517:5;25466:8;:57::i;:::-;25159:398;25070:487;;;:::o;19913:308::-;-1:-1:-1;;;;;19997:18:0;;19993:88;;20039:30;;-1:-1:-1;;;20039:30:0;;20066:1;20039:30;;;3366:51:1;3339:18;;20039:30:0;3220:203:1;19993:88:0;-1:-1:-1;;;;;20095:16:0;;20091:88;;20135:32;;-1:-1:-1;;;20135:32:0;;20164:1;20135:32;;;3366:51:1;3339:18;;20135:32:0;3220:203:1;20091:88:0;20189:24;20197:4;20203:2;20207:5;20189:7;:24::i;2851:166::-;2732:7;2759:6;-1:-1:-1;;;;;2759:6:0;775:10;2911:23;2907:103;;2958:40;;-1:-1:-1;;;2958:40:0;;775:10;2958:40;;;3366:51:1;3339:18;;2958:40:0;3220:203:1;60503:137:0;60577:11;;;;;;;:5;:11;;;;;;;;;:19;;;60612:20;;15518:42:1;;;15576:18;;15569:34;;;60612:20:0;;15491:18:1;60612:20:0;;;;;;;60503:137;;:::o;123704:1458::-;123839:20;123861;123894:15;124067:330;124100:10;:13;;;124128:16;124134:9;124128:5;:16::i;:::-;124365:21;;;;:10;:21;:::i;:::-;124067:330;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;124067:18:0;;-1:-1:-1;;;124067:330:0:i;:::-;124043:354;;-1:-1:-1;124043:354:0;-1:-1:-1;124479:14:0;124043:354;124496:33;;114723:1;124496:33;;;114770:1;124496:33;124479:50;-1:-1:-1;124653:67:0;124668:17;;;;:10;:17;:::i;:::-;124687:7;124696:23;;;;:10;:23;:::i;124653:67::-;124982:12;;124643:77;;-1:-1:-1;;;;;;124982:12:0;125075:23;;125071:83;;125100:54;;-1:-1:-1;;;125100:54:0;;-1:-1:-1;;;;;125100:36:0;;;;;:54;;125137:7;;125146;;125100:54;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;125071:83;123883:1279;;;123704:1458;;;;;:::o;63444:402::-;-1:-1:-1;;;;;;;;;;;;;;;;;63672:8:0;-1:-1:-1;;;;;63672:14:0;;63705:86;;;;;;;;63721:7;63705:86;;;;;;63730:25;63747:7;63730:16;:25::i;:::-;63705:86;;;;63757:8;63705:86;;;;63767:8;63705:86;;;;63777:13;63705:86;;;;;63818:4;63672:166;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;63652:186;63444:402;-1:-1:-1;;;;;63444:402:0:o;3999:191::-;4073:16;4092:6;;-1:-1:-1;;;;;4109:17:0;;;-1:-1:-1;;;;;;4109:17:0;;;;;;4142:40;;4092:6;;;;;;;4142:40;;4073:16;4142:40;4062:128;3999:191;:::o;79261:522::-;79370:9;79365:358;79389:16;:23;79385:1;:27;79365:358;;;79549:48;79569:16;79586:1;79569:19;;;;;;;;:::i;:::-;;;;;;;:27;;;79549:19;:48::i;:::-;79684:16;79701:1;79684:19;;;;;;;;:::i;:::-;;;;;;;:27;;;79612:15;:40;79628:16;79645:1;79628:19;;;;;;;;:::i;:::-;;;;;;;:23;;;79612:40;;;;;;;;;;;;;;;:69;79653:16;79670:1;79653:19;;;;;;;;:::i;:::-;;;;;;;:27;;;79612:69;;;;;;;;;;;;;;;:99;;;;;;:::i;:::-;-1:-1:-1;79414:3:0;;79365:358;;;;79740:35;79758:16;79740:35;;;;;;:::i;81705:270::-;81878:1;81864:16;;81858:23;81906:28;;;77459:1;81906:28;81902:65;;81958:8;81943:24;;-1:-1:-1;;;81943:24:0;;;;;;;;:::i;122044:1357::-;122202:34;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;122604:20:0;;122654:145;122675:10;122700:19;;;;122734:22;;;;122771:17;;;;122700:10;122771:17;:::i;:::-;122654:6;:145::i;:::-;122603:196;;;;122891:20;122913;122937:49;122957:10;122969:16;122937:19;:49::i;:::-;122890:96;;-1:-1:-1;122890:96:0;-1:-1:-1;123112:66:0;123120:17;;;;:10;:17;:::i;:::-;123139:7;123148;123112:66;;;;;;;123157:4;123112:66;:::i;:::-;123163:14;123112:7;:66::i;:::-;123246:42;;;;;;;;;;;;;;;;;;;123314:15;;123099:79;;-1:-1:-1;123246:42:0;;-1:-1:-1;123350:10:0;;123314:15;123306:87;;123331:17;;;;:10;:17;:::i;:::-;123306:87;;;30642:10:1;30630:23;;;30612:42;;30685:2;30670:18;;30663:34;;;30713:18;;30706:34;;;30600:2;30585:18;123306:87:0;;;;;;;122268:1133;;;;122044:1357;;;;;;:::o;24335:443::-;-1:-1:-1;;;;;24448:19:0;;24444:91;;24491:32;;-1:-1:-1;;;24491:32:0;;24520:1;24491:32;;;3366:51:1;3339:18;;24491:32:0;3220:203:1;24444:91:0;-1:-1:-1;;;;;24549:21:0;;24545:92;;24594:31;;-1:-1:-1;;;24594:31:0;;24622:1;24594:31;;;3366:51:1;3339:18;;24594:31:0;3220:203:1;24545:92:0;-1:-1:-1;;;;;24647:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;:35;;;24693:78;;;;24744:7;-1:-1:-1;;;;;24728:31:0;24737:5;-1:-1:-1;;;;;24728:31:0;;24753:5;24728:31;;;;5978:25:1;;5966:2;5951:18;;5832:177;24728:31:0;;;;;;;;24335:443;;;;:::o;129503:174::-;129574:16;129648:21;129611:33;129648:21;129611:9;:33;:::i;:::-;129610:59;;;;:::i;108677:125::-;108737:7;108772:21;107255:2;108737:7;108772:4;;:21;:::i;:::-;108764:30;;;:::i;108987:154::-;109049:6;109089:42;107311:2;107255;109089:4;;:42;:::i;:::-;109082:50;;;:::i;:::-;109075:58;;;108987:154;-1:-1:-1;;;108987:154:0:o;129908:141::-;129972:16;130008:33;130020:21;-1:-1:-1;;;;;130008:33:0;;;:::i;136189:472::-;136327:24;-1:-1:-1;;;;;136368:19:0;;136364:46;;136403:6;136389:21;;136364:46;136508:21;136514:3;136519:9;136508:5;:21::i;:::-;-1:-1:-1;136644:9:0;;136189:472;-1:-1:-1;;136189:472:0:o;109308:132::-;109372:12;109404:28;:4;107311:2;109404:4;;:28;:::i;:::-;109397:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;109397:35:0;;109308:132;-1:-1:-1;;;;;;109308:132:0:o;110753:291::-;110942:17;110996:6;111004:7;111013:9;111024:11;110979:57;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;110972:64;;110753:291;;;;;;:::o;20545:1135::-;-1:-1:-1;;;;;20635:18:0;;20631:552;;20789:5;20773:12;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;20631:552:0;;-1:-1:-1;20631:552:0;;-1:-1:-1;;;;;20849:15:0;;20827:19;20849:15;;;:9;:15;;;;;;20883:19;;;20879:117;;;20930:50;;-1:-1:-1;;;20930:50:0;;-1:-1:-1;;;;;24379:32:1;;20930:50:0;;;24361:51:1;24428:18;;;24421:34;;;24471:18;;;24464:34;;;24334:18;;20930:50:0;24159:345:1;20879:117:0;-1:-1:-1;;;;;21119:15:0;;;;;;:9;:15;;;;;21137:19;;;;21119:37;;20631:552;-1:-1:-1;;;;;21199:16:0;;21195:435;;21365:12;:21;;;;;;;21195:435;;;-1:-1:-1;;;;;21581:13:0;;;;;;:9;:13;;;;;:22;;;;;;21195:435;21662:2;-1:-1:-1;;;;;21647:25:0;21656:4;-1:-1:-1;;;;;21647:25:0;;21666:5;21647:25;;;;5978::1;;5966:2;5951:18;;5832:177;21647:25:0;;;;;;;;20545:1135;;;:::o;130280:149::-;130345:15;130387:33;130399:21;130387:9;:33;:::i;107676:516::-;107874:18;;107814:17;;107874:22;;;108019:165;;108161:7;108170:13;108144:40;;;;;;;;32656:19:1;;;32731:3;32709:16;-1:-1:-1;;;;;;32705:51:1;32700:2;32691:12;;32684:73;32782:2;32773:12;;32501:290;108144:40:0;;;;;;;;;;;;;108019:165;;;108062:7;108071:13;108103:10;108116:11;108045:83;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;108019:165;108012:172;;107676:516;;;;;;:::o;135265:580::-;135431:20;135453:24;135525:44;135536:9;135547:12;135561:7;135525:10;:44::i;:::-;135490:79;;-1:-1:-1;135490:79:0;-1:-1:-1;135811:26:0;135817:5;135490:79;135811:5;:26::i;:::-;135265:580;;;;;;;:::o;64621:783::-;64828:31;;:::i;:::-;64995:20;65018:26;65029:4;:14;;;65018:10;:26::i;:::-;65059:15;;;;64995:49;;-1:-1:-1;65059:19:0;65055:53;;65080:28;65092:4;:15;;;65080:11;:28::i;:::-;65201:8;-1:-1:-1;;;;;65201:13:0;;65223:12;65256:92;;;;;;;;65272:7;65256:92;;;;;;65281:25;65298:7;65281:16;:25::i;:::-;65256:92;;;;65308:8;65256:92;;;;65318:8;65256:92;;;;65346:1;65328:4;:15;;;:19;65256:92;;;;;65367:14;65201:195;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65121:275;64621:783;-1:-1:-1;;;;;;;64621:783:0:o;22033:213::-;-1:-1:-1;;;;;22104:21:0;;22100:93;;22149:32;;-1:-1:-1;;;22149:32:0;;22178:1;22149:32;;;3366:51:1;3339:18;;22149:32:0;3220:203:1;22100:93:0;22203:35;22219:1;22223:7;22232:5;22203:7;:35::i;22574:211::-;-1:-1:-1;;;;;22645:21:0;;22641:91;;22690:30;;-1:-1:-1;;;22690:30:0;;22717:1;22690:30;;;3366:51:1;3339:18;;22690:30:0;3220:203:1;22641:91:0;22742:35;22750:7;22767:1;22771:5;22742:7;:35::i;66113:194::-;66179:17;66226:10;66213:9;:23;66209:62;;66245:26;;-1:-1:-1;;;66245:26:0;;66261:9;66245:26;;;5978:25:1;5951:18;;66245:26:0;5832:177:1;66209:62:0;-1:-1:-1;66289:10:0;66113:194::o;66693:417::-;66848:15;66866:8;-1:-1:-1;;;;;66866:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66848:36;-1:-1:-1;;;;;;66899:21:0;;66895:54;;66929:20;;-1:-1:-1;;;66929:20:0;;;;;;;;;;;66895:54;40177:53;;;67059:10;40177:53;;;33997:51:1;;;67079:8:0;-1:-1:-1;;;;;34084:32:1;;;34064:18;;;34057:60;34133:18;;;;34126:34;;;40177:53:0;;;;;;;;;;33970:18:1;;;;40177:53:0;;;;;;;;;-1:-1:-1;;;;;40177:53:0;-1:-1:-1;;;40177:53:0;;;46469:11;;67026:76;;:32;;;67090:11;;40150:81;;67026:32;;-1:-1:-1;;;;40177:53:0;;-1:-1:-1;;;67026:32:0;46435:5;46430:60;46544:7;46534:180;;46589:4;46583:11;46635:16;46632:1;46627:3;46612:40;46682:16;46677:3;46670:29;46534:180;-1:-1:-1;;46793:1:0;46787:8;46742:16;;-1:-1:-1;46822:15:0;;:68;;46874:11;46889:1;46874:16;;46822:68;;;-1:-1:-1;;;;;46840:26:0;;;:31;46822:68;46818:148;;;46914:40;;-1:-1:-1;;;46914:40:0;;-1:-1:-1;;;;;3384:32:1;;46914:40:0;;;3366:51:1;3339:18;;46914:40:0;3220:203:1;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:289:1:-;56:3;94:5;88:12;121:6;116:3;109:19;177:6;170:4;163:5;159:16;152:4;147:3;143:14;137:47;229:1;222:4;213:6;208:3;204:16;200:27;193:38;292:4;285:2;281:7;276:2;268:6;264:15;260:29;255:3;251:39;247:50;240:57;;;14:289;;;;:::o;308:220::-;457:2;446:9;439:21;420:4;477:45;518:2;507:9;503:18;495:6;477:45;:::i;533:131::-;-1:-1:-1;;;;;608:31:1;;598:42;;588:70;;654:1;651;644:12;669:367;737:6;745;798:2;786:9;777:7;773:23;769:32;766:52;;;814:1;811;804:12;766:52;853:9;840:23;872:31;897:5;872:31;:::i;:::-;922:5;1000:2;985:18;;;;972:32;;-1:-1:-1;;;669:367:1:o;1233:158::-;1295:5;1340:3;1331:6;1326:3;1322:16;1318:26;1315:46;;;1357:1;1354;1347:12;1315:46;-1:-1:-1;1379:6:1;1233:158;-1:-1:-1;1233:158:1:o;1396:360::-;1484:6;1537:2;1525:9;1516:7;1512:23;1508:32;1505:52;;;1553:1;1550;1543:12;1505:52;1593:9;1580:23;-1:-1:-1;;;;;1618:6:1;1615:30;1612:50;;;1658:1;1655;1648:12;1612:50;1681:69;1742:7;1733:6;1722:9;1718:22;1681:69;:::i;1915:1300::-;1835:12;;1823:25;;1897:4;1886:16;;;1880:23;1864:14;;;1857:47;2281:4;2329:3;2314:19;;2423:3;2418:2;2407:9;2403:18;2396:31;2447:6;2482;2476:13;2513:6;2505;2498:22;2551:3;2540:9;2536:19;2529:26;;2614:3;2604:6;2601:1;2597:14;2586:9;2582:30;2578:40;2564:54;;2653:4;2645:6;2641:17;2676:1;2686:437;2700:6;2697:1;2694:13;2686:437;;;2793:3;2789:8;2777:9;2769:6;2765:22;2761:37;2756:3;2749:50;2828:6;2822:13;2869:2;2863:9;2855:6;2848:25;2920:4;2916:2;2912:13;2906:20;2886:40;;2965:2;2958:4;2950:6;2946:17;2939:29;2991:48;3035:2;3027:6;3023:15;3009:12;2991:48;:::i;:::-;2981:58;-1:-1:-1;;3074:4:1;3099:14;;;;3062:17;;;;;2722:1;2715:9;2686:437;;;-1:-1:-1;;1835:12:1;;3205:2;3190:18;;1823:25;-1:-1:-1;;1897:4:1;1886:16;;1880:23;1864:14;;;1857:47;3140:6;-1:-1:-1;3155:54:1;1761:149;3428:154;3487:5;3532:2;3523:6;3518:3;3514:16;3510:25;3507:45;;;3548:1;3545;3538:12;3587:347;3638:8;3648:6;3702:3;3695:4;3687:6;3683:17;3679:27;3669:55;;3720:1;3717;3710:12;3669:55;-1:-1:-1;3743:20:1;;-1:-1:-1;;;;;3775:30:1;;3772:50;;;3818:1;3815;3808:12;3772:50;3855:4;3847:6;3843:17;3831:29;;3907:3;3900:4;3891:6;3883;3879:19;3875:30;3872:39;3869:59;;;3924:1;3921;3914:12;3869:59;3587:347;;;;;:::o;3939:1095::-;4082:6;4090;4098;4106;4114;4122;4130;4183:3;4171:9;4162:7;4158:23;4154:33;4151:53;;;4200:1;4197;4190:12;4151:53;4223;4268:7;4257:9;4223:53;:::i;:::-;4213:63;-1:-1:-1;4345:2:1;4330:18;;4317:32;;-1:-1:-1;4424:3:1;4409:19;;4396:33;-1:-1:-1;;;;;4441:30:1;;4438:50;;;4484:1;4481;4474:12;4438:50;4523:58;4573:7;4564:6;4553:9;4549:22;4523:58;:::i;:::-;4600:8;;-1:-1:-1;4497:84:1;-1:-1:-1;;4687:3:1;4672:19;;4659:33;4701;4659;4701;:::i;:::-;4753:7;-1:-1:-1;4813:3:1;4798:19;;4785:33;-1:-1:-1;;;;;4830:32:1;;4827:52;;;4875:1;4872;4865:12;4827:52;4914:60;4966:7;4955:8;4944:9;4940:24;4914:60;:::i;:::-;3939:1095;;;;-1:-1:-1;3939:1095:1;;-1:-1:-1;3939:1095:1;;;;4888:86;;-1:-1:-1;;;3939:1095:1:o;6014:508::-;6091:6;6099;6107;6160:2;6148:9;6139:7;6135:23;6131:32;6128:52;;;6176:1;6173;6166:12;6128:52;6215:9;6202:23;6234:31;6259:5;6234:31;:::i;:::-;6284:5;-1:-1:-1;6341:2:1;6326:18;;6313:32;6354:33;6313:32;6354:33;:::i;:::-;6014:508;;6406:7;;-1:-1:-1;;;6486:2:1;6471:18;;;;6458:32;;6014:508::o;6716:163::-;6783:20;;6843:10;6832:22;;6822:33;;6812:61;;6869:1;6866;6859:12;6812:61;6716:163;;;:::o;6884:298::-;6951:6;6959;7012:2;7000:9;6991:7;6987:23;6983:32;6980:52;;;7028:1;7025;7018:12;6980:52;7051:28;7069:9;7051:28;:::i;7187:118::-;7273:5;7266:13;7259:21;7252:5;7249:32;7239:60;;7295:1;7292;7285:12;7310:489;7404:6;7412;7465:2;7453:9;7444:7;7440:23;7436:32;7433:52;;;7481:1;7478;7471:12;7433:52;7521:9;7508:23;-1:-1:-1;;;;;7546:6:1;7543:30;7540:50;;;7586:1;7583;7576:12;7540:50;7609:69;7670:7;7661:6;7650:9;7646:22;7609:69;:::i;:::-;7599:79;;;7728:2;7717:9;7713:18;7700:32;7741:28;7763:5;7741:28;:::i;:::-;7788:5;7778:15;;;7310:489;;;;;:::o;7804:257::-;1835:12;;1823:25;;1897:4;1886:16;;;1880:23;1864:14;;;1857:47;7998:2;7983:18;;8010:45;1761:149;8066:159;8133:20;;8193:6;8182:18;;8172:29;;8162:57;;8215:1;8212;8205:12;8230:256;8296:6;8304;8357:2;8345:9;8336:7;8332:23;8328:32;8325:52;;;8373:1;8370;8363:12;8325:52;8396:28;8414:9;8396:28;:::i;:::-;8386:38;;8443:37;8476:2;8465:9;8461:18;8443:37;:::i;:::-;8433:47;;8230:256;;;;;:::o;8951:247::-;9010:6;9063:2;9051:9;9042:7;9038:23;9034:32;9031:52;;;9079:1;9076;9069:12;9031:52;9118:9;9105:23;9137:31;9162:5;9137:31;:::i;9408:670::-;9522:6;9530;9538;9546;9599:3;9587:9;9578:7;9574:23;9570:33;9567:53;;;9616:1;9613;9606:12;9567:53;9639;9684:7;9673:9;9639:53;:::i;:::-;9629:63;;9743:2;9732:9;9728:18;9715:32;-1:-1:-1;;;;;9762:6:1;9759:30;9756:50;;;9802:1;9799;9792:12;9756:50;9841:58;9891:7;9882:6;9871:9;9867:22;9841:58;:::i;:::-;9918:8;;-1:-1:-1;9815:84:1;-1:-1:-1;;10003:3:1;9988:19;;9975:33;10017:31;9975:33;10017:31;:::i;:::-;9408:670;;;;-1:-1:-1;9408:670:1;;-1:-1:-1;;9408:670:1:o;10083:395::-;10174:8;10184:6;10238:3;10231:4;10223:6;10219:17;10215:27;10205:55;;10256:1;10253;10246:12;10205:55;-1:-1:-1;10279:20:1;;-1:-1:-1;;;;;10311:30:1;;10308:50;;;10354:1;10351;10344:12;10308:50;10391:4;10383:6;10379:17;10367:29;;10451:3;10444:4;10434:6;10431:1;10427:14;10419:6;10415:27;10411:38;10408:47;10405:67;;;10468:1;10465;10458:12;10483:504;10608:6;10616;10669:2;10657:9;10648:7;10644:23;10640:32;10637:52;;;10685:1;10682;10675:12;10637:52;10725:9;10712:23;-1:-1:-1;;;;;10750:6:1;10747:30;10744:50;;;10790:1;10787;10780:12;10744:50;10829:98;10919:7;10910:6;10899:9;10895:22;10829:98;:::i;:::-;10946:8;;10803:124;;-1:-1:-1;10483:504:1;-1:-1:-1;;;;10483:504:1:o;10992:184::-;11050:6;11103:2;11091:9;11082:7;11078:23;11074:32;11071:52;;;11119:1;11116;11109:12;11071:52;11142:28;11160:9;11142:28;:::i;11363:553::-;11449:6;11457;11465;11473;11526:2;11514:9;11505:7;11501:23;11497:32;11494:52;;;11542:1;11539;11532:12;11494:52;11565:28;11583:9;11565:28;:::i;:::-;11555:38;;11612:37;11645:2;11634:9;11630:18;11612:37;:::i;:::-;11602:47;;11700:2;11689:9;11685:18;11672:32;-1:-1:-1;;;;;11719:6:1;11716:30;11713:50;;;11759:1;11756;11749:12;11713:50;11798:58;11848:7;11839:6;11828:9;11824:22;11798:58;:::i;:::-;11363:553;;;;-1:-1:-1;11875:8:1;-1:-1:-1;;;;11363:553:1:o;12424:657::-;12562:6;12570;12578;12622:9;12613:7;12609:23;12652:3;12648:2;12644:12;12641:32;;;12669:1;12666;12659:12;12641:32;12709:9;12696:23;-1:-1:-1;;;;;12734:6:1;12731:30;12728:50;;;12774:1;12771;12764:12;12728:50;12797:69;12858:7;12849:6;12838:9;12834:22;12797:69;:::i;:::-;12787:79;-1:-1:-1;;12900:2:1;-1:-1:-1;;12882:16:1;;12878:25;12875:45;;;12916:1;12913;12906:12;12875:45;;12954:2;12943:9;12939:18;12929:28;;13007:2;12996:9;12992:18;12979:32;13020:31;13045:5;13020:31;:::i;:::-;13070:5;13060:15;;;12424:657;;;;;:::o;13086:613::-;13330:4;13372:3;13361:9;13357:19;13349:27;;13409:6;13403:13;13392:9;13385:32;-1:-1:-1;;;;;13477:4:1;13469:6;13465:17;13459:24;13455:49;13448:4;13437:9;13433:20;13426:79;13552:4;13544:6;13540:17;13534:24;13567:62;13623:4;13612:9;13608:20;13594:12;1835;;1823:25;;1897:4;1886:16;;;1880:23;1864:14;;1857:47;1761:149;13567:62;-1:-1:-1;1835:12:1;;13688:3;13673:19;;1823:25;1897:4;1886:16;;1880:23;1864:14;;;1857:47;13638:55;1761:149;13704:388;13772:6;13780;13833:2;13821:9;13812:7;13808:23;13804:32;13801:52;;;13849:1;13846;13839:12;13801:52;13888:9;13875:23;13907:31;13932:5;13907:31;:::i;:::-;13957:5;-1:-1:-1;14014:2:1;13999:18;;13986:32;14027:33;13986:32;14027:33;:::i;14097:236::-;14182:6;14235:2;14223:9;14214:7;14210:23;14206:32;14203:52;;;14251:1;14248;14241:12;14203:52;14274:53;14319:7;14308:9;14274:53;:::i;14338:380::-;14417:1;14413:12;;;;14460;;;14481:61;;14535:4;14527:6;14523:17;14513:27;;14481:61;14588:2;14580:6;14577:14;14557:18;14554:38;14551:161;;14634:10;14629:3;14625:20;14622:1;14615:31;14669:4;14666:1;14659:15;14697:4;14694:1;14687:15;14723:251;14793:6;14846:2;14834:9;14825:7;14821:23;14817:32;14814:52;;;14862:1;14859;14852:12;14814:52;14894:9;14888:16;14913:31;14938:5;14913:31;:::i;14979:230::-;15049:6;15102:2;15090:9;15081:7;15077:23;15073:32;15070:52;;;15118:1;15115;15108:12;15070:52;-1:-1:-1;15163:16:1;;14979:230;-1:-1:-1;14979:230:1:o;15214:127::-;15275:10;15270:3;15266:20;15263:1;15256:31;15306:4;15303:1;15296:15;15330:4;15327:1;15320:15;15614:253;15686:2;15680:9;15728:4;15716:17;;-1:-1:-1;;;;;15748:34:1;;15784:22;;;15745:62;15742:88;;;15810:18;;:::i;:::-;15846:2;15839:22;15614:253;:::o;15872:257::-;15944:4;15938:11;;;15976:17;;-1:-1:-1;;;;;16008:34:1;;16044:22;;;16005:62;16002:88;;;16070:18;;:::i;16134:275::-;16205:2;16199:9;16270:2;16251:13;;-1:-1:-1;;16247:27:1;16235:40;;-1:-1:-1;;;;;16290:34:1;;16326:22;;;16287:62;16284:88;;;16352:18;;:::i;:::-;16388:2;16381:22;16134:275;;-1:-1:-1;16134:275:1:o;16414:186::-;16462:4;-1:-1:-1;;;;;16487:6:1;16484:30;16481:56;;;16517:18;;:::i;:::-;-1:-1:-1;16583:2:1;16562:15;-1:-1:-1;;16558:29:1;16589:4;16554:40;;16414:186::o;16605:1784::-;16797:9;-1:-1:-1;;;;;16827:6:1;16824:30;16821:56;;;16857:18;;:::i;:::-;16903:6;16900:1;16896:14;16930:30;16954:4;16950:2;16946:13;16930:30;:::i;:::-;16994:19;;;17066:14;;;;17038:4;17029:14;;;17103;17092:26;;17089:46;;;17131:1;17128;17121:12;17089:46;17155:5;17169:1187;17185:6;17180:3;17177:15;17169:1187;;;17273:3;17260:17;-1:-1:-1;;;;;17296:11:1;17293:35;17290:55;;;17341:1;17338;17331:12;17290:55;17368:23;;17436:4;17415:14;17411:23;;;17407:34;17404:54;;;17454:1;17451;17444:12;17404:54;17486:22;;:::i;:::-;17537:21;17555:2;17537:21;:::i;:::-;17528:7;17521:38;17599:32;17625:4;17621:2;17617:13;17599:32;:::i;:::-;17592:4;17583:7;17579:18;17572:60;17680:2;17676;17672:11;17659:25;-1:-1:-1;;;;;17703:6:1;17700:30;17697:50;;;17743:1;17740;17733:12;17697:50;17770:15;;;;;17827:14;17820:4;17812:13;;17808:34;17798:62;;17856:1;17853;17846:12;17798:62;17902:2;17889:16;17933:54;17949:37;17977:8;17949:37;:::i;:::-;17933:54;:::i;:::-;18016:8;18007:7;18000:25;18074:14;18067:4;18056:8;18052:2;18048:17;18044:28;18041:48;18038:68;;;18102:1;18099;18092:12;18038:68;18167:8;18160:4;18156:2;18152:13;18145:4;18136:7;18132:18;18119:57;18231:1;18224:4;18213:8;18204:7;18200:22;18196:33;18189:44;18271:7;18266:2;18257:7;18253:16;18246:33;;;18304:7;18299:3;18292:20;;;18341:4;18336:3;18332:14;18325:21;;17211:4;17206:3;17202:14;17195:21;;17169:1187;;;-1:-1:-1;18378:5:1;16605:1784;-1:-1:-1;;;;;16605:1784:1:o;18394:331::-;18499:9;18510;18552:8;18540:10;18537:24;18534:44;;;18574:1;18571;18564:12;18534:44;18603:6;18593:8;18590:20;18587:40;;;18623:1;18620;18613:12;18587:40;-1:-1:-1;;18649:23:1;;;18694:25;;;;;-1:-1:-1;18394:331:1:o;18730:211::-;18771:3;18809:5;18803:12;18853:6;18846:4;18839:5;18835:16;18830:3;18824:36;18915:1;18879:16;;18904:13;;;-1:-1:-1;18879:16:1;;18730:211;-1:-1:-1;18730:211:1:o;18946:369::-;19137:3;19165:29;19190:3;19182:6;19165:29;:::i;:::-;19228:6;19220;19216:2;19203:32;19289:1;19254:15;;19278:13;;;-1:-1:-1;19254:15:1;;18946:369;-1:-1:-1;;;18946:369:1:o;19320:266::-;19408:6;19403:3;19396:19;19460:6;19453:5;19446:4;19441:3;19437:14;19424:43;-1:-1:-1;19512:1:1;19487:16;;;19505:4;19483:27;;;19476:38;;;;19568:2;19547:15;;;-1:-1:-1;;19543:29:1;19534:39;;;19530:50;;19320:266::o;19591:244::-;19748:2;19737:9;19730:21;19711:4;19768:61;19825:2;19814:9;19810:18;19802:6;19794;19768:61;:::i;19840:127::-;19901:10;19896:3;19892:20;19889:1;19882:31;19932:4;19929:1;19922:15;19956:4;19953:1;19946:15;19972:331;20071:4;20129:11;20116:25;20223:3;20219:8;20208;20192:14;20188:29;20184:44;20164:18;20160:69;20150:97;;20243:1;20240;20233:12;20150:97;20264:33;;;;;19972:331;-1:-1:-1;;19972:331:1:o;20308:521::-;20385:4;20391:6;20451:11;20438:25;20545:2;20541:7;20530:8;20514:14;20510:29;20506:43;20486:18;20482:68;20472:96;;20564:1;20561;20554:12;20472:96;20591:33;;20643:20;;;-1:-1:-1;;;;;;20675:30:1;;20672:50;;;20718:1;20715;20708:12;20672:50;20751:4;20739:17;;-1:-1:-1;20782:14:1;20778:27;;;20768:38;;20765:58;;;20819:1;20816;20809:12;20834:129;-1:-1:-1;;;;;20912:5:1;20908:30;20901:5;20898:41;20888:69;;20953:1;20950;20943:12;20968:1044;21346:10;21319:25;21337:6;21319:25;:::i;:::-;21315:42;21297:61;;21424:4;21412:17;;;21399:31;21446:20;;;21439:35;21278:4;21523;21511:17;;21498:31;21538:32;21498:31;21538:32;:::i;:::-;-1:-1:-1;;;;;21612:7:1;21608:32;21601:4;21590:9;21586:20;21579:62;;21677:6;21672:2;21661:9;21657:18;21650:34;21721:3;21715;21704:9;21700:19;21693:32;21748:62;21805:3;21794:9;21790:19;21782:6;21774;21748:62;:::i;:::-;-1:-1:-1;;;;;21847:32:1;;21867:3;21826:19;;21819:61;21917:22;;;21911:3;21896:19;;21889:51;21957:49;21921:6;21991;21983;21957:49;:::i;:::-;21949:57;20968:1044;-1:-1:-1;;;;;;;;;;20968:1044:1:o;22017:685::-;22096:6;22149:2;22137:9;22128:7;22124:23;22120:32;22117:52;;;22165:1;22162;22155:12;22117:52;22198:9;22192:16;-1:-1:-1;;;;;22223:6:1;22220:30;22217:50;;;22263:1;22260;22253:12;22217:50;22286:22;;22339:4;22331:13;;22327:27;-1:-1:-1;22317:55:1;;22368:1;22365;22358:12;22317:55;22401:2;22395:9;22426:52;22442:35;22470:6;22442:35;:::i;22426:52::-;22501:6;22494:5;22487:21;22549:7;22544:2;22535:6;22531:2;22527:15;22523:24;22520:37;22517:57;;;22570:1;22567;22560:12;22517:57;22618:6;22613:2;22609;22605:11;22600:2;22593:5;22589:14;22583:42;22670:1;22645:18;;;22665:2;22641:27;22634:38;;;;22649:5;22017:685;-1:-1:-1;;;;22017:685:1:o;23157:245::-;23215:6;23268:2;23256:9;23247:7;23243:23;23239:32;23236:52;;;23284:1;23281;23274:12;23236:52;23323:9;23310:23;23342:30;23366:5;23342:30;:::i;23407:479::-;23674:1;23670;23665:3;23661:11;23657:19;23649:6;23645:32;23634:9;23627:51;23714:6;23709:2;23698:9;23694:18;23687:34;23769:6;23761;23757:19;23752:2;23741:9;23737:18;23730:47;23813:3;23808:2;23797:9;23793:18;23786:31;23608:4;23834:46;23875:3;23864:9;23860:19;23852:6;23834:46;:::i;24509:379::-;24702:2;24691:9;24684:21;24665:4;24728:45;24769:2;24758:9;24754:18;24746:6;24728:45;:::i;:::-;24821:9;24813:6;24809:22;24804:2;24793:9;24789:18;24782:50;24849:33;24875:6;24867;24849:33;:::i;24893:245::-;24960:6;25013:2;25001:9;24992:7;24988:23;24984:32;24981:52;;;25029:1;25026;25019:12;24981:52;25061:9;25055:16;25080:28;25102:5;25080:28;:::i;25143:891::-;25366:2;25355:9;25348:21;25424:10;25415:6;25409:13;25405:30;25400:2;25389:9;25385:18;25378:58;25490:4;25482:6;25478:17;25472:24;25467:2;25456:9;25452:18;25445:52;25329:4;25544:2;25536:6;25532:15;25526:22;25585:4;25579:3;25568:9;25564:19;25557:33;25613:52;25660:3;25649:9;25645:19;25631:12;25613:52;:::i;:::-;25599:66;;25714:2;25706:6;25702:15;25696:22;25788:2;25784:7;25772:9;25764:6;25760:22;25756:36;25749:4;25738:9;25734:20;25727:66;25816:41;25850:6;25834:14;25816:41;:::i;:::-;25926:3;25914:16;;;;25908:23;25901:31;25894:39;25888:3;25873:19;;25866:68;-1:-1:-1;;;;;;;;25995:32:1;;;;25988:4;25973:20;;;25966:62;25802:55;25143:891::o;26039:388::-;26109:5;26157:4;26145:9;26140:3;26136:19;26132:30;26129:50;;;26175:1;26172;26165:12;26129:50;26197:22;;:::i;:::-;26264:16;;26289:22;;26377:2;26362:18;;;26356:25;26397:14;;;26390:31;;;;-1:-1:-1;26188:31:1;26039:388;-1:-1:-1;26039:388:1:o;26432:259::-;26532:6;26585:2;26573:9;26564:7;26560:23;26556:32;26553:52;;;26601:1;26598;26591:12;26553:52;26624:61;26677:7;26666:9;26624:61;:::i;26821:517::-;26922:2;26917:3;26914:11;26911:421;;;26958:5;26955:1;26948:16;27002:4;26999:1;26989:18;27072:2;27060:10;27056:19;27053:1;27049:27;27043:4;27039:38;27108:4;27096:10;27093:20;27090:47;;;-1:-1:-1;27131:4:1;27090:47;27186:2;27181:3;27177:12;27174:1;27170:20;27164:4;27160:31;27150:41;;27241:81;27259:2;27252:5;27249:13;27241:81;;;27318:1;27304:16;;27285:1;27274:13;27241:81;;27514:1295;27638:3;27632:10;-1:-1:-1;;;;;27657:6:1;27654:30;27651:56;;;27687:18;;:::i;:::-;27716:96;27805:6;27765:38;27797:4;27791:11;27765:38;:::i;:::-;27759:4;27716:96;:::i;:::-;27861:4;27892:2;27881:14;;27909:1;27904:648;;;;28596:1;28613:6;28610:89;;;-1:-1:-1;28665:19:1;;;28659:26;28610:89;-1:-1:-1;;27471:1:1;27467:11;;;27463:24;27459:29;27449:40;27495:1;27491:11;;;27446:57;28712:81;;27874:929;;27904:648;26768:1;26761:14;;;26805:4;26792:18;;-1:-1:-1;;27940:20:1;;;28057:222;28071:7;28068:1;28065:14;28057:222;;;28153:19;;;28147:26;28132:42;;28260:4;28245:20;;;;28213:1;28201:14;;;;28087:12;28057:222;;;28061:3;28307:6;28298:7;28295:19;28292:201;;;28368:19;;;28362:26;-1:-1:-1;;28451:1:1;28447:14;;;28463:3;28443:24;28439:37;28435:42;28420:58;28405:74;;28292:201;-1:-1:-1;;;;28539:1:1;28523:14;;;28519:22;28506:36;;-1:-1:-1;27514:1295:1:o;28814:1099::-;29030:4;29078:2;29067:9;29063:18;29108:2;29097:9;29090:21;29131:6;29166;29160:13;29197:6;29189;29182:22;29235:2;29224:9;29220:18;29213:25;;29297:2;29287:6;29284:1;29280:14;29269:9;29265:30;29261:39;29247:53;;29335:2;29327:6;29323:15;29356:1;29366:518;29380:6;29377:1;29374:13;29366:518;;;29473:2;29469:7;29457:9;29449:6;29445:22;29441:36;29436:3;29429:49;29507:6;29501:13;29557:10;29552:2;29546:9;29542:26;29534:6;29527:42;29630:6;29624:2;29620;29616:11;29610:18;29606:31;29601:2;29593:6;29589:15;29582:56;29685:2;29681;29677:11;29671:18;29651:38;;29726:4;29721:2;29713:6;29709:15;29702:29;29754:50;29798:4;29790:6;29786:17;29772:12;29754:50;:::i;:::-;29744:60;-1:-1:-1;;29839:2:1;29862:12;;;;29827:15;;;;;29402:1;29395:9;29366:518;;;-1:-1:-1;29901:6:1;;28814:1099;-1:-1:-1;;;;;;28814:1099:1:o;29918:489::-;30007:6;30067:2;30055:9;30046:7;30042:23;30038:32;30082:2;30079:22;;;30097:1;30094;30087:12;30079:22;-1:-1:-1;30139:22:1;;:::i;:::-;30206:23;;30238:22;;30333:2;30318:18;;;30305:32;30353:14;;;30346:31;;;;-1:-1:-1;30245:5:1;29918:489;-1:-1:-1;29918:489:1:o;30751:127::-;30812:10;30807:3;30803:20;30800:1;30793:31;30843:4;30840:1;30833:15;30867:4;30864:1;30857:15;30883:217;30923:1;30949;30939:132;;30993:10;30988:3;30984:20;30981:1;30974:31;31028:4;31025:1;31018:15;31056:4;31053:1;31046:15;30939:132;-1:-1:-1;31085:9:1;;30883:217::o;31105:168::-;31178:9;;;31209;;31226:15;;;31220:22;;31206:37;31196:71;;31247:18;;:::i;31278:255::-;31398:19;;31437:2;31429:11;;31426:101;;;-1:-1:-1;;31498:2:1;31494:12;;;31491:1;31487:20;31483:33;31472:45;31278:255;;;;:::o;31538:362::-;31658:19;;-1:-1:-1;;;;;;31695:37:1;;;31752:1;31744:10;;31741:153;;;-1:-1:-1;;;;;;31813:1:1;31809:11;;;31806:1;31802:19;31798:54;;;31790:63;;31786:98;;-1:-1:-1;31741:153:1;;31538:362;;;;:::o;31905:461::-;32170:3;32148:16;;;-1:-1:-1;;;;;;32144:51:1;32132:64;;32251:3;32229:16;;;-1:-1:-1;;;;;;32225:43:1;32221:1;32212:11;;32205:64;32294:2;32285:12;;32278:28;;;-1:-1:-1;32322:38:1;32356:2;32347:12;;32339:6;32322:38;:::i;32371:125::-;32436:9;;;32457:10;;;32454:36;;;32470:18;;:::i;32796:427::-;33037:6;33032:3;33025:19;-1:-1:-1;;;;;33100:3:1;33096:28;33087:6;33082:3;33078:16;33074:51;33069:2;33064:3;33060:12;33053:73;33156:6;33151:2;33146:3;33142:12;33135:28;33007:3;33179:38;33213:2;33208:3;33204:12;33196:6;33179:38;:::i;33228:562::-;33332:6;33392:3;33380:9;33371:7;33367:23;33363:33;33408:2;33405:22;;;33423:1;33420;33413:12;33405:22;-1:-1:-1;33465:22:1;;:::i;:::-;33516:9;33510:16;33503:5;33496:31;33572:2;33561:9;33557:18;33551:25;33585:32;33609:7;33585:32;:::i;:::-;33644:2;33633:14;;33626:31;33689:70;33751:7;33746:2;33731:18;;33689:70;:::i;:::-;33684:2;33673:14;;33666:94;33677:5;33228:562;-1:-1:-1;;;33228:562:1:o
Swarm Source
ipfs://0619beffdfde08e0ea967bb64cc5966cd86340bd85f617c1f5ba87e5d29e9e92
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.