Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
WFRAXTokenOFTUpgradeable
Compiler Version
v0.8.22+commit.4fc1097e
Contract Source Code (Solidity)
/**
*Submitted for verification at KatanaScan.com on 2025-11-06
*/
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.0 ^0.8.0 ^0.8.1 ^0.8.2 ^0.8.20 ^0.8.22;
// node_modules/@openzeppelin/contracts/utils/Address.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @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.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @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, it is bubbled up by this
* function (like regular Solidity function calls).
*
* 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.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @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`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
// node_modules/@layerzerolabs/lz-evm-protocol-v2/contracts/libs/AddressCast.sol
library AddressCast {
error AddressCast_InvalidSizeForAddress();
error AddressCast_InvalidAddress();
function toBytes32(bytes calldata _addressBytes) internal pure returns (bytes32 result) {
if (_addressBytes.length > 32) revert AddressCast_InvalidAddress();
result = bytes32(_addressBytes);
unchecked {
uint256 offset = 32 - _addressBytes.length;
result = result >> (offset * 8);
}
}
function toBytes32(address _address) internal pure returns (bytes32 result) {
result = bytes32(uint256(uint160(_address)));
}
function toBytes(bytes32 _addressBytes32, uint256 _size) internal pure returns (bytes memory result) {
if (_size == 0 || _size > 32) revert AddressCast_InvalidSizeForAddress();
result = new bytes(_size);
unchecked {
uint256 offset = 256 - _size * 8;
assembly {
mstore(add(result, 32), shl(offset, _addressBytes32))
}
}
}
function toAddress(bytes32 _addressBytes32) internal pure returns (address result) {
result = address(uint160(uint256(_addressBytes32)));
}
function toAddress(bytes calldata _addressBytes) internal pure returns (address result) {
if (_addressBytes.length != 20) revert AddressCast_InvalidAddress();
result = address(bytes20(_addressBytes));
}
}
// node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @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.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @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, it is bubbled up by this
* function (like regular Solidity function calls).
*
* 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.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @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`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
// node_modules/@openzeppelin/contracts/utils/Counters.sol
// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)
/**
* @title Counters
* @author Matt Condon (@shrugs)
* @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
* of elements in a mapping, issuing ERC721 ids, or counting request ids.
*
* Include with `using Counters for Counters.Counter;`
*/
library Counters {
struct Counter {
// This variable should never be directly accessed by users of the library: interactions must be restricted to
// the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
// this feature: see https://github.com/ethereum/solidity/issues/4637
uint256 _value; // default: 0
}
function current(Counter storage counter) internal view returns (uint256) {
return counter._value;
}
function increment(Counter storage counter) internal {
unchecked {
counter._value += 1;
}
}
function decrement(Counter storage counter) internal {
uint256 value = counter._value;
require(value > 0, "Counter: decrement overflow");
unchecked {
counter._value = value - 1;
}
}
function reset(Counter storage counter) internal {
counter._value = 0;
}
}
// node_modules/@openzeppelin/contracts/interfaces/IERC1271.sol
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)
/**
* @dev Interface of the ERC1271 standard signature validation method for
* contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].
*
* _Available since v4.1._
*/
interface IERC1271 {
/**
* @dev Should return whether the signature provided is valid for the provided data
* @param hash Hash of the data to be signed
* @param signature Signature byte array associated with _data
*/
function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);
}
// node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
// node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` 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 amount) 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 `amount` 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 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` 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 amount) external returns (bool);
}
// node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol
// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*
* CAUTION: See Security Considerations above.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
// node_modules/@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20Upgradeable {
/**
* @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 amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` 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 amount) 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 `amount` 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 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` 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 amount) external returns (bool);
}
// node_modules/@openzeppelin/contracts/interfaces/IERC5267.sol
// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol)
interface IERC5267 {
/**
* @dev MAY be emitted to signal that the domain could have changed.
*/
event EIP712DomainChanged();
/**
* @dev returns the fields and values that describe the domain separator used by this contract for EIP-712
* signature.
*/
function eip712Domain()
external
view
returns (
bytes1 fields,
string memory name,
string memory version,
uint256 chainId,
address verifyingContract,
bytes32 salt,
uint256[] memory extensions
);
}
// node_modules/@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessageLibManager.sol
struct SetConfigParam {
uint32 eid;
uint32 configType;
bytes config;
}
interface IMessageLibManager {
struct Timeout {
address lib;
uint256 expiry;
}
event LibraryRegistered(address newLib);
event DefaultSendLibrarySet(uint32 eid, address newLib);
event DefaultReceiveLibrarySet(uint32 eid, address newLib);
event DefaultReceiveLibraryTimeoutSet(uint32 eid, address oldLib, uint256 expiry);
event SendLibrarySet(address sender, uint32 eid, address newLib);
event ReceiveLibrarySet(address receiver, uint32 eid, address newLib);
event ReceiveLibraryTimeoutSet(address receiver, uint32 eid, address oldLib, uint256 timeout);
function registerLibrary(address _lib) external;
function isRegisteredLibrary(address _lib) external view returns (bool);
function getRegisteredLibraries() external view returns (address[] memory);
function setDefaultSendLibrary(uint32 _eid, address _newLib) external;
function defaultSendLibrary(uint32 _eid) external view returns (address);
function setDefaultReceiveLibrary(uint32 _eid, address _newLib, uint256 _gracePeriod) external;
function defaultReceiveLibrary(uint32 _eid) external view returns (address);
function setDefaultReceiveLibraryTimeout(uint32 _eid, address _lib, uint256 _expiry) external;
function defaultReceiveLibraryTimeout(uint32 _eid) external view returns (address lib, uint256 expiry);
function isSupportedEid(uint32 _eid) external view returns (bool);
function isValidReceiveLibrary(address _receiver, uint32 _eid, address _lib) external view returns (bool);
/// ------------------- OApp interfaces -------------------
function setSendLibrary(address _oapp, uint32 _eid, address _newLib) external;
function getSendLibrary(address _sender, uint32 _eid) external view returns (address lib);
function isDefaultSendLibrary(address _sender, uint32 _eid) external view returns (bool);
function setReceiveLibrary(address _oapp, uint32 _eid, address _newLib, uint256 _gracePeriod) external;
function getReceiveLibrary(address _receiver, uint32 _eid) external view returns (address lib, bool isDefault);
function setReceiveLibraryTimeout(address _oapp, uint32 _eid, address _lib, uint256 _expiry) external;
function receiveLibraryTimeout(address _receiver, uint32 _eid) external view returns (address lib, uint256 expiry);
function setConfig(address _oapp, address _lib, SetConfigParam[] calldata _params) external;
function getConfig(
address _oapp,
address _lib,
uint32 _eid,
uint32 _configType
) external view returns (bytes memory config);
}
// node_modules/@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessagingChannel.sol
interface IMessagingChannel {
event InboundNonceSkipped(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce);
event PacketNilified(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash);
event PacketBurnt(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash);
function eid() external view returns (uint32);
// this is an emergency function if a message cannot be verified for some reasons
// required to provide _nextNonce to avoid race condition
function skip(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce) external;
function nilify(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external;
function burn(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external;
function nextGuid(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (bytes32);
function inboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64);
function outboundNonce(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (uint64);
function inboundPayloadHash(
address _receiver,
uint32 _srcEid,
bytes32 _sender,
uint64 _nonce
) external view returns (bytes32);
function lazyInboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64);
}
// node_modules/@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessagingComposer.sol
interface IMessagingComposer {
event ComposeSent(address from, address to, bytes32 guid, uint16 index, bytes message);
event ComposeDelivered(address from, address to, bytes32 guid, uint16 index);
event LzComposeAlert(
address indexed from,
address indexed to,
address indexed executor,
bytes32 guid,
uint16 index,
uint256 gas,
uint256 value,
bytes message,
bytes extraData,
bytes reason
);
function composeQueue(
address _from,
address _to,
bytes32 _guid,
uint16 _index
) external view returns (bytes32 messageHash);
function sendCompose(address _to, bytes32 _guid, uint16 _index, bytes calldata _message) external;
function lzCompose(
address _from,
address _to,
bytes32 _guid,
uint16 _index,
bytes calldata _message,
bytes calldata _extraData
) external payable;
}
// node_modules/@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessagingContext.sol
interface IMessagingContext {
function isSendingMessage() external view returns (bool);
function getSendContext() external view returns (uint32 dstEid, address sender);
}
// node_modules/@fraxfinance/layerzero-v2-upgradeable/oapp/contracts/oapp/interfaces/IOAppMsgInspector.sol
/**
* @title IOAppMsgInspector
* @dev Interface for the OApp Message Inspector, allowing examination of message and options contents.
*/
interface IOAppMsgInspector {
// Custom error message for inspection failure
error InspectionFailed(bytes message, bytes options);
/**
* @notice Allows the inspector to examine LayerZero message contents and optionally throw a revert if invalid.
* @param _message The message payload to be inspected.
* @param _options Additional options or parameters for inspection.
* @return valid A boolean indicating whether the inspection passed (true) or failed (false).
*
* @dev Optionally done as a revert, OR use the boolean provided to handle the failure.
*/
function inspect(bytes calldata _message, bytes calldata _options) external view returns (bool valid);
}
// node_modules/@fraxfinance/layerzero-v2-upgradeable/oapp/contracts/oapp/interfaces/IOAppOptionsType3.sol
/**
* @dev Struct representing enforced option parameters.
*/
struct EnforcedOptionParam {
uint32 eid; // Endpoint ID
uint16 msgType; // Message Type
bytes options; // Additional options
}
/**
* @title IOAppOptionsType3
* @dev Interface for the OApp with Type 3 Options, allowing the setting and combining of enforced options.
*/
interface IOAppOptionsType3 {
// Custom error message for invalid options
error InvalidOptions(bytes options);
// Event emitted when enforced options are set
event EnforcedOptionSet(EnforcedOptionParam[] _enforcedOptions);
/**
* @notice Sets enforced options for specific endpoint and message type combinations.
* @param _enforcedOptions An array of EnforcedOptionParam structures specifying enforced options.
*/
function setEnforcedOptions(EnforcedOptionParam[] calldata _enforcedOptions) external;
/**
* @notice Combines options for a given endpoint and message type.
* @param _eid The endpoint ID.
* @param _msgType The OApp message type.
* @param _extraOptions Additional options passed by the caller.
* @return options The combination of caller specified options AND enforced options.
*/
function combineOptions(
uint32 _eid,
uint16 _msgType,
bytes calldata _extraOptions
) external view returns (bytes memory options);
}
// node_modules/@fraxfinance/layerzero-v2-upgradeable/oapp/contracts/precrime/interfaces/IPreCrime.sol
struct PreCrimePeer {
uint32 eid;
bytes32 preCrime;
bytes32 oApp;
}
// TODO not done yet
interface IPreCrime {
error OnlyOffChain();
// for simulate()
error PacketOversize(uint256 max, uint256 actual);
error PacketUnsorted();
error SimulationFailed(bytes reason);
// for preCrime()
error SimulationResultNotFound(uint32 eid);
error InvalidSimulationResult(uint32 eid, bytes reason);
error CrimeFound(bytes crime);
function getConfig(bytes[] calldata _packets, uint256[] calldata _packetMsgValues) external returns (bytes memory);
function simulate(
bytes[] calldata _packets,
uint256[] calldata _packetMsgValues
) external payable returns (bytes memory);
function buildSimulationResult() external view returns (bytes memory);
function preCrime(
bytes[] calldata _packets,
uint256[] calldata _packetMsgValues,
bytes[] calldata _simulations
) external;
function version() external view returns (uint64 major, uint8 minor);
}
// node_modules/@openzeppelin/contracts/utils/math/Math.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1, "Math: mulDiv overflow");
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 256, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}
// node_modules/@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library MathUpgradeable {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1, "Math: mulDiv overflow");
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 256, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}
// node_modules/@fraxfinance/layerzero-v2-upgradeable/oapp/contracts/oft/libs/OFTComposeMsgCodec.sol
library OFTComposeMsgCodec {
// Offset constants for decoding composed messages
uint8 private constant NONCE_OFFSET = 8;
uint8 private constant SRC_EID_OFFSET = 12;
uint8 private constant AMOUNT_LD_OFFSET = 44;
uint8 private constant COMPOSE_FROM_OFFSET = 76;
/**
* @dev Encodes a OFT composed message.
* @param _nonce The nonce value.
* @param _srcEid The source endpoint ID.
* @param _amountLD The amount in local decimals.
* @param _composeMsg The composed message.
* @return _msg The encoded Composed message.
*/
function encode(
uint64 _nonce,
uint32 _srcEid,
uint256 _amountLD,
bytes memory _composeMsg // 0x[composeFrom][composeMsg]
) internal pure returns (bytes memory _msg) {
_msg = abi.encodePacked(_nonce, _srcEid, _amountLD, _composeMsg);
}
/**
* @dev Retrieves the nonce from the composed message.
* @param _msg The message.
* @return The nonce value.
*/
function nonce(bytes calldata _msg) internal pure returns (uint64) {
return uint64(bytes8(_msg[:NONCE_OFFSET]));
}
/**
* @dev Retrieves the source endpoint ID from the composed message.
* @param _msg The message.
* @return The source endpoint ID.
*/
function srcEid(bytes calldata _msg) internal pure returns (uint32) {
return uint32(bytes4(_msg[NONCE_OFFSET:SRC_EID_OFFSET]));
}
/**
* @dev Retrieves the amount in local decimals from the composed message.
* @param _msg The message.
* @return The amount in local decimals.
*/
function amountLD(bytes calldata _msg) internal pure returns (uint256) {
return uint256(bytes32(_msg[SRC_EID_OFFSET:AMOUNT_LD_OFFSET]));
}
/**
* @dev Retrieves the composeFrom value from the composed message.
* @param _msg The message.
* @return The composeFrom value.
*/
function composeFrom(bytes calldata _msg) internal pure returns (bytes32) {
return bytes32(_msg[AMOUNT_LD_OFFSET:COMPOSE_FROM_OFFSET]);
}
/**
* @dev Retrieves the composed message.
* @param _msg The message.
* @return The composed message.
*/
function composeMsg(bytes calldata _msg) internal pure returns (bytes memory) {
return _msg[COMPOSE_FROM_OFFSET:];
}
/**
* @dev Converts an address to bytes32.
* @param _addr The address to convert.
* @return The bytes32 representation of the address.
*/
function addressToBytes32(address _addr) internal pure returns (bytes32) {
return bytes32(uint256(uint160(_addr)));
}
/**
* @dev Converts bytes32 to an address.
* @param _b The bytes32 value to convert.
* @return The address representation of bytes32.
*/
function bytes32ToAddress(bytes32 _b) internal pure returns (address) {
return address(uint160(uint256(_b)));
}
}
// node_modules/@fraxfinance/layerzero-v2-upgradeable/oapp/contracts/oft/libs/OFTMsgCodec.sol
library OFTMsgCodec {
// Offset constants for encoding and decoding OFT messages
uint8 private constant SEND_TO_OFFSET = 32;
uint8 private constant SEND_AMOUNT_SD_OFFSET = 40;
/**
* @dev Encodes an OFT LayerZero message.
* @param _sendTo The recipient address.
* @param _amountShared The amount in shared decimals.
* @param _composeMsg The composed message.
* @return _msg The encoded message.
* @return hasCompose A boolean indicating whether the message has a composed payload.
*/
function encode(
bytes32 _sendTo,
uint64 _amountShared,
bytes memory _composeMsg
) internal view returns (bytes memory _msg, bool hasCompose) {
hasCompose = _composeMsg.length > 0;
// @dev Remote chains will want to know the composed function caller ie. msg.sender on the src.
_msg = hasCompose
? abi.encodePacked(_sendTo, _amountShared, addressToBytes32(msg.sender), _composeMsg)
: abi.encodePacked(_sendTo, _amountShared);
}
/**
* @dev Checks if the OFT message is composed.
* @param _msg The OFT message.
* @return A boolean indicating whether the message is composed.
*/
function isComposed(bytes calldata _msg) internal pure returns (bool) {
return _msg.length > SEND_AMOUNT_SD_OFFSET;
}
/**
* @dev Retrieves the recipient address from the OFT message.
* @param _msg The OFT message.
* @return The recipient address.
*/
function sendTo(bytes calldata _msg) internal pure returns (bytes32) {
return bytes32(_msg[:SEND_TO_OFFSET]);
}
/**
* @dev Retrieves the amount in shared decimals from the OFT message.
* @param _msg The OFT message.
* @return The amount in shared decimals.
*/
function amountSD(bytes calldata _msg) internal pure returns (uint64) {
return uint64(bytes8(_msg[SEND_TO_OFFSET:SEND_AMOUNT_SD_OFFSET]));
}
/**
* @dev Retrieves the composed message from the OFT message.
* @param _msg The OFT message.
* @return The composed message.
*/
function composeMsg(bytes calldata _msg) internal pure returns (bytes memory) {
return _msg[SEND_AMOUNT_SD_OFFSET:];
}
/**
* @dev Converts an address to bytes32.
* @param _addr The address to convert.
* @return The bytes32 representation of the address.
*/
function addressToBytes32(address _addr) internal pure returns (bytes32) {
return bytes32(uint256(uint160(_addr)));
}
/**
* @dev Converts bytes32 to an address.
* @param _b The bytes32 value to convert.
* @return The address representation of bytes32.
*/
function bytes32ToAddress(bytes32 _b) internal pure returns (address) {
return address(uint160(uint256(_b)));
}
}
// node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)
/**
* @dev Standard signed math utilities missing in the Solidity language.
*/
library SignedMath {
/**
* @dev Returns the largest of two signed numbers.
*/
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two signed numbers.
*/
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two signed numbers without overflow.
* The result is rounded towards zero.
*/
function average(int256 a, int256 b) internal pure returns (int256) {
// Formula from the book "Hacker's Delight"
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
/**
* @dev Returns the absolute unsigned value of a signed value.
*/
function abs(int256 n) internal pure returns (uint256) {
unchecked {
// must be unchecked in order to support `n = type(int256).min`
return uint256(n >= 0 ? n : -n);
}
}
}
// node_modules/@openzeppelin/contracts-upgradeable/utils/math/SignedMathUpgradeable.sol
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)
/**
* @dev Standard signed math utilities missing in the Solidity language.
*/
library SignedMathUpgradeable {
/**
* @dev Returns the largest of two signed numbers.
*/
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two signed numbers.
*/
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two signed numbers without overflow.
* The result is rounded towards zero.
*/
function average(int256 a, int256 b) internal pure returns (int256) {
// Formula from the book "Hacker's Delight"
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
/**
* @dev Returns the absolute unsigned value of a signed value.
*/
function abs(int256 n) internal pure returns (uint256) {
unchecked {
// must be unchecked in order to support `n = type(int256).min`
return uint256(n >= 0 ? n : -n);
}
}
}
// node_modules/@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20MetadataUpgradeable is IERC20Upgradeable {
/**
* @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);
}
// node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```solidity
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
*
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
* @custom:oz-retyped-from bool
*/
uint8 private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint8 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
* constructor.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
bool isTopLevelCall = !_initializing;
require(
(isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
"Initializable: contract is already initialized"
);
_initialized = 1;
if (isTopLevelCall) {
_initializing = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: setting the version to 255 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint8 version) {
require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
_initialized = version;
_initializing = true;
_;
_initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized != type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint8) {
return _initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _initializing;
}
}
// node_modules/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
}
function __Context_init_unchained() internal onlyInitializing {
}
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;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}
// node_modules/@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessageLib.sol
enum MessageLibType {
Send,
Receive,
SendAndReceive
}
interface IMessageLib is IERC165 {
function setConfig(address _oapp, SetConfigParam[] calldata _config) external;
function getConfig(uint32 _eid, address _oapp, uint32 _configType) external view returns (bytes memory config);
function isSupportedEid(uint32 _eid) external view returns (bool);
// message libs of same major version are compatible
function version() external view returns (uint64 major, uint8 minor, uint8 endpointVersion);
function messageLibType() external view returns (MessageLibType);
}
// node_modules/@openzeppelin/contracts/utils/Strings.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `int256` to its ASCII `string` decimal representation.
*/
function toString(int256 value) internal pure returns (string memory) {
return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
/**
* @dev Returns true if the two strings are equal.
*/
function equal(string memory a, string memory b) internal pure returns (bool) {
return keccak256(bytes(a)) == keccak256(bytes(b));
}
}
// node_modules/@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)
/**
* @dev String operations.
*/
library StringsUpgradeable {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = MathUpgradeable.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `int256` to its ASCII `string` decimal representation.
*/
function toString(int256 value) internal pure returns (string memory) {
return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMathUpgradeable.abs(value))));
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, MathUpgradeable.log256(value) + 1);
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
/**
* @dev Returns true if the two strings are equal.
*/
function equal(string memory a, string memory b) internal pure returns (bool) {
return keccak256(bytes(a)) == keccak256(bytes(b));
}
}
// node_modules/@openzeppelin/contracts/utils/cryptography/ECDSA.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)
/**
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
*
* These functions can be used to verify that a message was signed by the holder
* of the private keys of a given address.
*/
library ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS,
InvalidSignatureV // Deprecated in v4.8
}
function _throwError(RecoverError error) private pure {
if (error == RecoverError.NoError) {
return; // no error: do nothing
} else if (error == RecoverError.InvalidSignature) {
revert("ECDSA: invalid signature");
} else if (error == RecoverError.InvalidSignatureLength) {
revert("ECDSA: invalid signature length");
} else if (error == RecoverError.InvalidSignatureS) {
revert("ECDSA: invalid signature 's' value");
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature` or error string. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*
* Documentation for signature generation:
* - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
* - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
*
* _Available since v4.3._
*/
function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
/// @solidity memory-safe-assembly
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else {
return (address(0), RecoverError.InvalidSignatureLength);
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature`. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*/
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, signature);
_throwError(error);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
*
* See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
*
* _Available since v4.3._
*/
function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {
bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
uint8 v = uint8((uint256(vs) >> 255) + 27);
return tryRecover(hash, v, r, s);
}
/**
* @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
*
* _Available since v4.2._
*/
function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, r, vs);
_throwError(error);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `v`,
* `r` and `s` signature fields separately.
*
* _Available since v4.3._
*/
function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
// the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
// signatures from current libraries generate a unique signature with an s-value in the lower half order.
//
// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
// these malleable signatures as well.
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS);
}
// If the signature is valid (and not malleable), return the signer address
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature);
}
return (signer, RecoverError.NoError);
}
/**
* @dev Overload of {ECDSA-recover} that receives the `v`,
* `r` and `s` signature fields separately.
*/
function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, v, r, s);
_throwError(error);
return recovered;
}
/**
* @dev Returns an Ethereum Signed Message, created from a `hash`. This
* produces hash corresponding to the one signed with the
* https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
* JSON-RPC method as part of EIP-191.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {
// 32 is the length in bytes of hash,
// enforced by the type signature above
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, "\x19Ethereum Signed Message:\n32")
mstore(0x1c, hash)
message := keccak256(0x00, 0x3c)
}
}
/**
* @dev Returns an Ethereum Signed Message, created from `s`. This
* produces hash corresponding to the one signed with the
* https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
* JSON-RPC method as part of EIP-191.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
}
/**
* @dev Returns an Ethereum Signed Typed Data, created from a
* `domainSeparator` and a `structHash`. This produces hash corresponding
* to the one signed with the
* https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
* JSON-RPC method as part of EIP-712.
*
* See {recover}.
*/
function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {
/// @solidity memory-safe-assembly
assembly {
let ptr := mload(0x40)
mstore(ptr, "\x19\x01")
mstore(add(ptr, 0x02), domainSeparator)
mstore(add(ptr, 0x22), structHash)
data := keccak256(ptr, 0x42)
}
}
/**
* @dev Returns an Ethereum Signed Data with intended validator, created from a
* `validator` and `data` according to the version 0 of EIP-191.
*
* See {recover}.
*/
function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x00", validator, data));
}
}
// node_modules/@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)
/**
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
*
* These functions can be used to verify that a message was signed by the holder
* of the private keys of a given address.
*/
library ECDSAUpgradeable {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS,
InvalidSignatureV // Deprecated in v4.8
}
function _throwError(RecoverError error) private pure {
if (error == RecoverError.NoError) {
return; // no error: do nothing
} else if (error == RecoverError.InvalidSignature) {
revert("ECDSA: invalid signature");
} else if (error == RecoverError.InvalidSignatureLength) {
revert("ECDSA: invalid signature length");
} else if (error == RecoverError.InvalidSignatureS) {
revert("ECDSA: invalid signature 's' value");
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature` or error string. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*
* Documentation for signature generation:
* - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
* - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
*
* _Available since v4.3._
*/
function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
/// @solidity memory-safe-assembly
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else {
return (address(0), RecoverError.InvalidSignatureLength);
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature`. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*/
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, signature);
_throwError(error);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
*
* See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
*
* _Available since v4.3._
*/
function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {
bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
uint8 v = uint8((uint256(vs) >> 255) + 27);
return tryRecover(hash, v, r, s);
}
/**
* @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
*
* _Available since v4.2._
*/
function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, r, vs);
_throwError(error);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `v`,
* `r` and `s` signature fields separately.
*
* _Available since v4.3._
*/
function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
// the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
// signatures from current libraries generate a unique signature with an s-value in the lower half order.
//
// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
// these malleable signatures as well.
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS);
}
// If the signature is valid (and not malleable), return the signer address
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature);
}
return (signer, RecoverError.NoError);
}
/**
* @dev Overload of {ECDSA-recover} that receives the `v`,
* `r` and `s` signature fields separately.
*/
function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, v, r, s);
_throwError(error);
return recovered;
}
/**
* @dev Returns an Ethereum Signed Message, created from a `hash`. This
* produces hash corresponding to the one signed with the
* https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
* JSON-RPC method as part of EIP-191.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {
// 32 is the length in bytes of hash,
// enforced by the type signature above
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, "\x19Ethereum Signed Message:\n32")
mstore(0x1c, hash)
message := keccak256(0x00, 0x3c)
}
}
/**
* @dev Returns an Ethereum Signed Message, created from `s`. This
* produces hash corresponding to the one signed with the
* https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
* JSON-RPC method as part of EIP-191.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", StringsUpgradeable.toString(s.length), s));
}
/**
* @dev Returns an Ethereum Signed Typed Data, created from a
* `domainSeparator` and a `structHash`. This produces hash corresponding
* to the one signed with the
* https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
* JSON-RPC method as part of EIP-712.
*
* See {recover}.
*/
function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {
/// @solidity memory-safe-assembly
assembly {
let ptr := mload(0x40)
mstore(ptr, "\x19\x01")
mstore(add(ptr, 0x02), domainSeparator)
mstore(add(ptr, 0x22), structHash)
data := keccak256(ptr, 0x42)
}
}
/**
* @dev Returns an Ethereum Signed Data with intended validator, created from a
* `validator` and `data` according to the version 0 of EIP-191.
*
* See {recover}.
*/
function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x00", validator, data));
}
}
// node_modules/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. 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 OwnableUpgradeable is Initializable, ContextUpgradeable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
function __Ownable_init() internal onlyInitializing {
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal onlyInitializing {
_transferOwnership(_msgSender());
}
/**
* @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 {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @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 {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_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);
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}
// node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
/**
* @dev 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.encodeWithSelector(token.transfer.selector, 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.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
* Revert on invalid signature.
*/
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}
// node_modules/@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol
struct MessagingParams {
uint32 dstEid;
bytes32 receiver;
bytes message;
bytes options;
bool payInLzToken;
}
struct MessagingReceipt {
bytes32 guid;
uint64 nonce;
MessagingFee fee;
}
struct MessagingFee {
uint256 nativeFee;
uint256 lzTokenFee;
}
struct Origin {
uint32 srcEid;
bytes32 sender;
uint64 nonce;
}
interface ILayerZeroEndpointV2 is IMessageLibManager, IMessagingComposer, IMessagingChannel, IMessagingContext {
event PacketSent(bytes encodedPayload, bytes options, address sendLibrary);
event PacketVerified(Origin origin, address receiver, bytes32 payloadHash);
event PacketDelivered(Origin origin, address receiver);
event LzReceiveAlert(
address indexed receiver,
address indexed executor,
Origin origin,
bytes32 guid,
uint256 gas,
uint256 value,
bytes message,
bytes extraData,
bytes reason
);
event LzTokenSet(address token);
event DelegateSet(address sender, address delegate);
function quote(MessagingParams calldata _params, address _sender) external view returns (MessagingFee memory);
function send(
MessagingParams calldata _params,
address _refundAddress
) external payable returns (MessagingReceipt memory);
function verify(Origin calldata _origin, address _receiver, bytes32 _payloadHash) external;
function verifiable(Origin calldata _origin, address _receiver) external view returns (bool);
function initializable(Origin calldata _origin, address _receiver) external view returns (bool);
function lzReceive(
Origin calldata _origin,
address _receiver,
bytes32 _guid,
bytes calldata _message,
bytes calldata _extraData
) external payable;
// oapp can burn messages partially by calling this function with its own business logic if messages are verified in order
function clear(address _oapp, Origin calldata _origin, bytes32 _guid, bytes calldata _message) external;
function setLzToken(address _lzToken) external;
function lzToken() external view returns (address);
function nativeToken() external view returns (address);
function setDelegate(address _delegate) external;
}
// contracts/modules/signatureModule/EIP712Upgradeable.sol
// OpenZeppelin Contracts (last updated v5.3.0) (utils/cryptography/EIP712.sol)
/**
@notice This contract is a blend of OZ 4 and 5 to
- Utilize 4.x, as utilized by LZ
- Utilize 5.x namespaced storage, protecting from storage clashes
@dev Starting at OZ 5.3, key changes are
- Initializable removed
- MessageHashUtils (5.x) replaced with ECDSAUpgradeable (4.x)
*/
/**
* @dev https://eips.ethereum.org/EIPS/eip-712[EIP-712] is a standard for hashing and signing of typed structured data.
*
* The encoding scheme specified in the EIP requires a domain separator and a hash of the typed structured data, whose
* encoding is very generic and therefore its implementation in Solidity is not feasible, thus this contract
* does not implement the encoding itself. Protocols need to implement the type-specific encoding they need in order to
* produce the hash of their typed data using a combination of `abi.encode` and `keccak256`.
*
* This contract implements the EIP-712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
* scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
* ({_hashTypedDataV4}).
*
* The implementation of the domain separator was designed to be as efficient as possible while still properly updating
* the chain id to protect against replay attacks on an eventual fork of the chain.
*
* NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
* https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
*
* NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain
* separator of the implementation contract. This will cause the {_domainSeparatorV4} function to always rebuild the
* separator from the immutable values, which is cheaper than accessing a cached version in cold storage.
*/
abstract contract EIP712Upgradeable is IERC5267 {
bytes32 private constant TYPE_HASH =
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
/// @custom:storage-location erc7201:openzeppelin.storage.EIP712
struct EIP712Storage {
/// @custom:oz-renamed-from _HASHED_NAME
bytes32 _hashedName;
/// @custom:oz-renamed-from _HASHED_VERSION
bytes32 _hashedVersion;
string _name;
string _version;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.EIP712")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant EIP712StorageLocation = 0xa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100;
function _getEIP712Storage() private pure returns (EIP712Storage storage $) {
assembly {
$.slot := EIP712StorageLocation
}
}
/**
* @dev Initializes the domain separator and parameter caches.
*
* The meaning of `name` and `version` is specified in
* https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP-712]:
*
* - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
* - `version`: the current major version of the signing domain.
*
* NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
* contract upgrade].
*/
function __EIP712_init(string memory name, string memory version) internal {
__EIP712_init_unchained(name, version);
}
function __EIP712_init_unchained(string memory name, string memory version) internal {
EIP712Storage storage $ = _getEIP712Storage();
$._name = name;
$._version = version;
// Reset prior values in storage if upgrading
$._hashedName = 0;
$._hashedVersion = 0;
}
/**
* @dev Returns the domain separator for the current chain.
*/
function _domainSeparatorV4() internal view returns (bytes32) {
return _buildDomainSeparator();
}
function _buildDomainSeparator() private view returns (bytes32) {
return keccak256(abi.encode(TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), block.chainid, address(this)));
}
/**
* @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
* function returns the hash of the fully encoded EIP712 message for this domain.
*
* This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
*
* ```solidity
* bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
* keccak256("Mail(address to,strAing contents)"),
* mailTo,
* keccak256(bytes(mailContents))
* )));
* address signer = ECDSA.recover(digest, signature);
* ```
*/
function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);
}
/**
* @inheritdoc IERC5267
*/
function eip712Domain()
public
view
virtual
returns (
bytes1 fields,
string memory name,
string memory version,
uint256 chainId,
address verifyingContract,
bytes32 salt,
uint256[] memory extensions
)
{
EIP712Storage storage $ = _getEIP712Storage();
// If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized
// and the EIP712 domain is not reliable, as it will be missing name and version.
require($._hashedName == 0 && $._hashedVersion == 0, "EIP712: Uninitialized");
return (
hex"0f", // 01111
_EIP712Name(),
_EIP712Version(),
block.chainid,
address(this),
bytes32(0),
new uint256[](0)
);
}
/**
* @dev The name parameter for the EIP712 domain.
*
* NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs
* are a concern.
*/
function _EIP712Name() internal view virtual returns (string memory) {
EIP712Storage storage $ = _getEIP712Storage();
return $._name;
}
/**
* @dev The version parameter for the EIP712 domain.
*
* NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs
* are a concern.
*/
function _EIP712Version() internal view virtual returns (string memory) {
EIP712Storage storage $ = _getEIP712Storage();
return $._version;
}
/**
* @dev The hash of the name parameter for the EIP712 domain.
*
* NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead.
*/
function _EIP712NameHash() internal view returns (bytes32) {
EIP712Storage storage $ = _getEIP712Storage();
string memory name = _EIP712Name();
if (bytes(name).length > 0) {
return keccak256(bytes(name));
} else {
// If the name is empty, the contract may have been upgraded without initializing the new storage.
// We return the name hash in storage if non-zero, otherwise we assume the name is empty by design.
bytes32 hashedName = $._hashedName;
if (hashedName != 0) {
return hashedName;
} else {
return keccak256("");
}
}
}
/**
* @dev The hash of the version parameter for the EIP712 domain.
*
* NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead.
*/
function _EIP712VersionHash() internal view returns (bytes32) {
EIP712Storage storage $ = _getEIP712Storage();
string memory version = _EIP712Version();
if (bytes(version).length > 0) {
return keccak256(bytes(version));
} else {
// If the version is empty, the contract may have been upgraded without initializing the new storage.
// We return the version hash in storage if non-zero, otherwise we assume the version is empty by design.
bytes32 hashedVersion = $._hashedVersion;
if (hashedVersion != 0) {
return hashedVersion;
} else {
return keccak256("");
}
}
}
}
// node_modules/@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* The default value of {decimals} is 18. To change this, you should override
* this function so it returns a different value.
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => 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.
*/
function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {
__ERC20_init_unchained(name_, symbol_);
}
function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override 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 override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override 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 `amount`.
*/
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `amount` 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 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
* - the caller must have allowance for ``from``'s tokens of at least
* `amount`.
*/
function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `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.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
*/
function _transfer(address from, address to, uint256 amount) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
// Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
// decrementing then incrementing.
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
unchecked {
// Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
// Overflow not possible: amount <= accountBalance <= totalSupply.
_totalSupply -= amount;
}
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev Sets `amount` 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.
*/
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `amount`.
*
* Does not update the allowance amount in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Might emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[45] private __gap;
}
// node_modules/@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroReceiver.sol
interface ILayerZeroReceiver {
function allowInitializePath(Origin calldata _origin) external view returns (bool);
function nextNonce(uint32 _eid, bytes32 _sender) external view returns (uint64);
function lzReceive(
Origin calldata _origin,
bytes32 _guid,
bytes calldata _message,
address _executor,
bytes calldata _extraData
) external payable;
}
// node_modules/@fraxfinance/layerzero-v2-upgradeable/oapp/contracts/oapp/interfaces/IOAppCore.sol
/**
* @title IOAppCore
*/
interface IOAppCore {
// Custom error messages
error OnlyPeer(uint32 eid, bytes32 sender);
error NoPeer(uint32 eid);
error InvalidEndpointCall();
error InvalidDelegate();
// Event emitted when a peer (OApp) is set for a corresponding endpoint
event PeerSet(uint32 eid, bytes32 peer);
/**
* @notice Retrieves the OApp version information.
* @return senderVersion The version of the OAppSender.sol contract.
* @return receiverVersion The version of the OAppReceiver.sol contract.
*/
function oAppVersion() external view returns (uint64 senderVersion, uint64 receiverVersion);
/**
* @notice Retrieves the LayerZero endpoint associated with the OApp.
* @return iEndpoint The LayerZero endpoint as an interface.
*/
function endpoint() external view returns (ILayerZeroEndpointV2 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;
}
// node_modules/@fraxfinance/layerzero-v2-upgradeable/oapp/contracts/oapp/libs/OAppOptionsType3Upgradeable.sol
/**
* @title OAppOptionsType3
* @dev Abstract contract implementing the IOAppOptionsType3 interface with type 3 options.
*/
abstract contract OAppOptionsType3Upgradeable is IOAppOptionsType3, OwnableUpgradeable {
struct OAppOptionsType3Storage {
// @dev The "msgType" should be defined in the child contract.
mapping(uint32 => mapping(uint16 => bytes)) enforcedOptions;
}
// keccak256(abi.encode(uint256(keccak256("layerzerov2.storage.oappoptionstype3")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant OAppOptionsType3StorageLocation =
0x8d2bda5d9f6ffb5796910376005392955773acee5548d0fcdb10e7c264ea0000;
uint16 internal constant OPTION_TYPE_3 = 3;
function _getOAppOptionsType3Storage() internal pure returns (OAppOptionsType3Storage storage $) {
assembly {
$.slot := OAppOptionsType3StorageLocation
}
}
/**
* @dev Ownable is not initialized here on purpose. It should be initialized in the child contract to
* accommodate the different version of Ownable.
*/
function __OAppOptionsType3_init() internal onlyInitializing {}
function __OAppOptionsType3_init_unchained() internal onlyInitializing {}
function enforcedOptions(uint32 _eid, uint16 _msgType) public view returns (bytes memory) {
OAppOptionsType3Storage storage $ = _getOAppOptionsType3Storage();
return $.enforcedOptions[_eid][_msgType];
}
/**
* @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 {
OAppOptionsType3Storage storage $ = _getOAppOptionsType3Storage();
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) {
OAppOptionsType3Storage storage $ = _getOAppOptionsType3Storage();
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 calldata _options) internal pure virtual {
uint16 optionsType = uint16(bytes2(_options[0:2]));
if (optionsType != OPTION_TYPE_3) revert InvalidOptions(_options);
}
}
// node_modules/@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)
/**
* @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA
* signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like
* Argent and Gnosis Safe.
*
* _Available since v4.1._
*/
library SignatureChecker {
/**
* @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the
* signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.
*
* NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus
* change through time. It could return true at block N and false at block N+1 (or the opposite).
*/
function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {
(address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);
return
(error == ECDSA.RecoverError.NoError && recovered == signer) ||
isValidERC1271SignatureNow(signer, hash, signature);
}
/**
* @dev Checks if a signature is valid for a given signer and data hash. The signature is validated
* against the signer smart contract using ERC1271.
*
* NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus
* change through time. It could return true at block N and false at block N+1 (or the opposite).
*/
function isValidERC1271SignatureNow(
address signer,
bytes32 hash,
bytes memory signature
) internal view returns (bool) {
(bool success, bytes memory result) = signer.staticcall(
abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)
);
return (success &&
result.length >= 32 &&
abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));
}
}
// node_modules/@fraxfinance/layerzero-v2-upgradeable/oapp/contracts/oapp/interfaces/IOAppReceiver.sol
interface IOAppReceiver is ILayerZeroReceiver {
/**
* @notice Retrieves the address responsible for 'sending' composeMsg's to the Endpoint.
* @return sender The address responsible for 'sending' composeMsg's to the Endpoint.
*
* @dev Applications can optionally choose to implement a separate composeMsg sender that is NOT the bridging layer.
* @dev The default sender IS the OApp implementer.
*/
function composeMsgSender() external view returns (address sender);
}
// node_modules/@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ISendLib.sol
struct Packet {
uint64 nonce;
uint32 srcEid;
address sender;
uint32 dstEid;
bytes32 receiver;
bytes32 guid;
bytes message;
}
interface ISendLib is IMessageLib {
function send(
Packet calldata _packet,
bytes calldata _options,
bool _payInLzToken
) external returns (MessagingFee 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;
}
// node_modules/@layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/libs/PacketV1Codec.sol
library PacketV1Codec {
using AddressCast for address;
using AddressCast for bytes32;
uint8 internal constant PACKET_VERSION = 1;
// header (version + nonce + path)
// version
uint256 private constant PACKET_VERSION_OFFSET = 0;
// nonce
uint256 private constant NONCE_OFFSET = 1;
// path
uint256 private constant SRC_EID_OFFSET = 9;
uint256 private constant SENDER_OFFSET = 13;
uint256 private constant DST_EID_OFFSET = 45;
uint256 private constant RECEIVER_OFFSET = 49;
// payload (guid + message)
uint256 private constant GUID_OFFSET = 81; // keccak256(nonce + path)
uint256 private constant MESSAGE_OFFSET = 113;
function encode(Packet memory _packet) internal pure returns (bytes memory encodedPacket) {
encodedPacket = abi.encodePacked(
PACKET_VERSION,
_packet.nonce,
_packet.srcEid,
_packet.sender.toBytes32(),
_packet.dstEid,
_packet.receiver,
_packet.guid,
_packet.message
);
}
function encodePacketHeader(Packet memory _packet) internal pure returns (bytes memory) {
return
abi.encodePacked(
PACKET_VERSION,
_packet.nonce,
_packet.srcEid,
_packet.sender.toBytes32(),
_packet.dstEid,
_packet.receiver
);
}
function encodePayload(Packet memory _packet) internal pure returns (bytes memory) {
return abi.encodePacked(_packet.guid, _packet.message);
}
function header(bytes calldata _packet) internal pure returns (bytes calldata) {
return _packet[0:GUID_OFFSET];
}
function version(bytes calldata _packet) internal pure returns (uint8) {
return uint8(bytes1(_packet[PACKET_VERSION_OFFSET:NONCE_OFFSET]));
}
function nonce(bytes calldata _packet) internal pure returns (uint64) {
return uint64(bytes8(_packet[NONCE_OFFSET:SRC_EID_OFFSET]));
}
function srcEid(bytes calldata _packet) internal pure returns (uint32) {
return uint32(bytes4(_packet[SRC_EID_OFFSET:SENDER_OFFSET]));
}
function sender(bytes calldata _packet) internal pure returns (bytes32) {
return bytes32(_packet[SENDER_OFFSET:DST_EID_OFFSET]);
}
function senderAddressB20(bytes calldata _packet) internal pure returns (address) {
return sender(_packet).toAddress();
}
function dstEid(bytes calldata _packet) internal pure returns (uint32) {
return uint32(bytes4(_packet[DST_EID_OFFSET:RECEIVER_OFFSET]));
}
function receiver(bytes calldata _packet) internal pure returns (bytes32) {
return bytes32(_packet[RECEIVER_OFFSET:GUID_OFFSET]);
}
function receiverB20(bytes calldata _packet) internal pure returns (address) {
return receiver(_packet).toAddress();
}
function guid(bytes calldata _packet) internal pure returns (bytes32) {
return bytes32(_packet[GUID_OFFSET:MESSAGE_OFFSET]);
}
function message(bytes calldata _packet) internal pure returns (bytes calldata) {
return bytes(_packet[MESSAGE_OFFSET:]);
}
function payload(bytes calldata _packet) internal pure returns (bytes calldata) {
return bytes(_packet[GUID_OFFSET:]);
}
function payloadHash(bytes calldata _packet) internal pure returns (bytes32) {
return keccak256(payload(_packet));
}
}
// node_modules/@fraxfinance/layerzero-v2-upgradeable/oapp/contracts/oapp/OAppCoreUpgradeable.sol
/**
* @title OAppCore
* @dev Abstract contract implementing the IOAppCore interface with basic OApp configurations.
*/
abstract contract OAppCoreUpgradeable is IOAppCore, OwnableUpgradeable {
struct OAppCoreStorage {
mapping(uint32 => bytes32) peers;
}
// keccak256(abi.encode(uint256(keccak256("layerzerov2.storage.oappcore")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant OAppCoreStorageLocation =
0x72ab1bc1039b79dc4724ffca13de82c96834302d3c7e0d4252232d4b2dd8f900;
function _getOAppCoreStorage() internal pure returns (OAppCoreStorage storage $) {
assembly {
$.slot := OAppCoreStorageLocation
}
}
// The LayerZero endpoint associated with the given OApp
ILayerZeroEndpointV2 public immutable endpoint;
/**
* @dev Constructor to initialize the OAppCore with the provided endpoint and delegate.
* @param _endpoint The address of the LOCAL Layer Zero endpoint.
*/
constructor(address _endpoint) {
endpoint = ILayerZeroEndpointV2(_endpoint);
}
/**
* @dev Initializes the OAppCore with the provided delegate.
* @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.
* @dev Ownable is not initialized here on purpose. It should be initialized in the child contract to
* accommodate the different version of Ownable.
*/
function __OAppCore_init(address _delegate) internal onlyInitializing {
__OAppCore_init_unchained(_delegate);
}
function __OAppCore_init_unchained(address _delegate) internal onlyInitializing {
if (_delegate == address(0)) revert InvalidDelegate();
endpoint.setDelegate(_delegate);
}
/**
* @notice Returns the peer address (OApp instance) associated with a specific endpoint.
* @param _eid The endpoint ID.
* @return peer The address of the peer associated with the specified endpoint.
*/
function peers(uint32 _eid) public view override returns (bytes32) {
OAppCoreStorage storage $ = _getOAppCoreStorage();
return $.peers[_eid];
}
/**
* @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 {
OAppCoreStorage storage $ = _getOAppCoreStorage();
$.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) {
OAppCoreStorage storage $ = _getOAppCoreStorage();
bytes32 peer = $.peers[_eid];
if (peer == bytes32(0)) revert NoPeer(_eid);
return peer;
}
/**
* @notice Sets the delegate address for the OApp.
* @param _delegate The address of the delegate to be set.
*
* @dev Only the owner/admin of the OApp can call this function.
* @dev Provides the ability for a delegate to set configs, on behalf of the OApp, directly on the Endpoint contract.
*/
function setDelegate(address _delegate) public onlyOwner {
endpoint.setDelegate(_delegate);
}
}
// node_modules/@fraxfinance/layerzero-v2-upgradeable/oapp/contracts/precrime/libs/Packet.sol
/**
* @title InboundPacket
* @dev Structure representing an inbound packet received by the contract.
*/
struct InboundPacket {
Origin origin; // Origin information of the packet.
uint32 dstEid; // Destination endpointId of the packet.
address receiver; // Receiver address for the packet.
bytes32 guid; // Unique identifier of the packet.
uint256 value; // msg.value of the packet.
address executor; // Executor address for the packet.
bytes message; // Message payload of the packet.
bytes extraData; // Additional arbitrary data for the packet.
}
/**
* @title PacketDecoder
* @dev Library for decoding LayerZero packets.
*/
library PacketDecoder {
using PacketV1Codec for bytes;
/**
* @dev Decode an inbound packet from the given packet data.
* @param _packet The packet data to decode.
* @return packet An InboundPacket struct representing the decoded packet.
*/
function decode(bytes calldata _packet) internal pure returns (InboundPacket memory packet) {
packet.origin = Origin(_packet.srcEid(), _packet.sender(), _packet.nonce());
packet.dstEid = _packet.dstEid();
packet.receiver = _packet.receiverB20();
packet.guid = _packet.guid();
packet.message = _packet.message();
}
/**
* @dev Decode multiple inbound packets from the given packet data and associated message values.
* @param _packets An array of packet data to decode.
* @param _packetMsgValues An array of associated message values for each packet.
* @return packets An array of InboundPacket structs representing the decoded packets.
*/
function decode(
bytes[] calldata _packets,
uint256[] memory _packetMsgValues
) internal pure returns (InboundPacket[] memory packets) {
packets = new InboundPacket[](_packets.length);
for (uint256 i = 0; i < _packets.length; i++) {
bytes calldata packet = _packets[i];
packets[i] = PacketDecoder.decode(packet);
// @dev Allows the verifier to specify the msg.value that gets passed in lzReceive.
packets[i].value = _packetMsgValues[i];
}
}
}
// node_modules/@fraxfinance/layerzero-v2-upgradeable/oapp/contracts/precrime/interfaces/IOAppPreCrimeSimulator.sol
// @dev Import the Origin so it's exposed to OAppPreCrimeSimulator implementers.
// solhint-disable-next-line no-unused-import
/**
* @title IOAppPreCrimeSimulator Interface
* @dev Interface for the preCrime simulation functionality in an OApp.
*/
interface IOAppPreCrimeSimulator {
// @dev simulation result used in PreCrime implementation
error SimulationResult(bytes result);
error OnlySelf();
/**
* @dev Emitted when the preCrime contract address is set.
* @param preCrimeAddress The address of the preCrime contract.
*/
event PreCrimeSet(address preCrimeAddress);
/**
* @dev Retrieves the address of the preCrime contract implementation.
* @return The address of the preCrime contract.
*/
function preCrime() external view returns (address);
/**
* @dev Retrieves the address of the OApp contract.
* @return The address of the OApp contract.
*/
function oApp() external view returns (address);
/**
* @dev Sets the preCrime contract address.
* @param _preCrime The address of the preCrime contract.
*/
function setPreCrime(address _preCrime) external;
/**
* @dev Mocks receiving a packet, then reverts with a series of data to infer the state/result.
* @param _packets An array of LayerZero InboundPacket objects representing received packets.
*/
function lzReceiveAndRevert(InboundPacket[] calldata _packets) external payable;
/**
* @dev checks if the specified peer is considered 'trusted' by the OApp.
* @param _eid The endpoint Id to check.
* @param _peer The peer to check.
* @return Whether the peer passed is considered 'trusted' by the OApp.
*/
function isPeer(uint32 _eid, bytes32 _peer) external view returns (bool);
}
// contracts/modules/signatureModule/SignatureModule.sol
abstract contract SignatureModule is EIP712Upgradeable {
/// @notice Error thrown when a signature is invalid
error InvalidSignature();
/// @dev Added supportive function to check if the signature is valid
function _requireIsValidSignatureNow(address signer, bytes32 structHash, bytes memory signature) internal view {
if (
!SignatureChecker.isValidSignatureNow({
signer: signer,
hash: _hashTypedDataV4({structHash: structHash}),
signature: signature
}) || signer == address(0)
) revert InvalidSignature();
}
}
// contracts/modules/EIP3009Module.sol
/// @title Eip3009
/// @notice Eip3009 provides internal implementations for gas-abstracted transfers under Eip3009 guidelines
/// @author Frax Finance, inspired by Agora (thanks Drake)
abstract contract EIP3009Module is SignatureModule {
/// @notice keccak256("TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)")
bytes32 internal constant TRANSFER_WITH_AUTHORIZATION_TYPEHASH =
0x7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267;
/// @notice keccak256("ReceiveWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)")
bytes32 internal constant RECEIVE_WITH_AUTHORIZATION_TYPEHASH =
0xd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de8;
/// @notice keccak256("CancelAuthorization(address authorizer,bytes32 nonce)")
bytes32 internal constant CANCEL_AUTHORIZATION_TYPEHASH =
0x158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a1597429;
//==============================================================================
// Storage
//==============================================================================
struct EIP3009ModuleStorage {
mapping(address authorizer => mapping(bytes32 nonce => bool used)) isAuthorizationUsed;
}
// keccak256(abi.encode(uint256(keccak256("frax.storage.EIP3009Module")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant EIP3009ModuleStorageLocation = 0x6607eb842e76408d8b3956685dc6b9da5897a1d9b47edcc993ce266e603fa500;
function _getEIP3009ModuleStorage() private pure returns (EIP3009ModuleStorage storage $) {
assembly {
$.slot := EIP3009ModuleStorageLocation
}
}
//==============================================================================
// Functions
//==============================================================================
/// @notice The ```transferWithAuthorization``` function executes a transfer with a signed authorization according to Eip3009
/// @dev EOA wallet signatures should be packed in the order of r, s, v
/// @dev added in v1.1.0
/// @param from Payer's address (Authorizer)
/// @param to Payee's address
/// @param value Amount to be transferred
/// @param validAfter The block.timestamp after which the authorization is valid
/// @param validBefore The block.timestamp before which the authorization is valid
/// @param nonce Unique nonce
/// @param v ECDSA signature parameter v
/// @param r ECDSA signature parameters r
/// @param s ECDSA signature parameters s
function transferWithAuthorization(
address from,
address to,
uint256 value,
uint256 validAfter,
uint256 validBefore,
bytes32 nonce,
uint8 v,
bytes32 r,
bytes32 s
) external {
// Packs signature pieces into bytes
transferWithAuthorization({
from: from,
to: to,
value: value,
validAfter: validAfter,
validBefore: validBefore,
nonce: nonce,
signature: abi.encodePacked(r, s, v)
});
}
/// @notice The ```transferWithAuthorization``` function executes a transfer with a signed authorization
/// @dev EOA wallet signatures should be packed in the order of r, s, v
/// @param from Payer's address (Authorizer)
/// @param to Payee's address
/// @param value Amount to be transferred
/// @param validAfter The time after which this is valid (unix time)
/// @param validBefore The time before which this is valid (unix time)
/// @param nonce Unique nonce
/// @param signature Signature byte array produced by an EOA wallet or a contract wallet
function transferWithAuthorization(
address from,
address to,
uint256 value,
uint256 validAfter,
uint256 validBefore,
bytes32 nonce,
bytes memory signature
) public {
// Checks: authorization validity
if (block.timestamp <= validAfter) revert InvalidAuthorization();
if (block.timestamp >= validBefore) revert ExpiredAuthorization();
_requireUnusedAuthorization({ authorizer: from, nonce: nonce });
// Checks: valid signature
_requireIsValidSignatureNow({
signer: from,
structHash: keccak256(
abi.encode(TRANSFER_WITH_AUTHORIZATION_TYPEHASH, from, to, value, validAfter, validBefore, nonce)
),
signature: signature
});
// Effects: mark authorization as used and transfer
_markAuthorizationAsUsed({ authorizer: from, nonce: nonce });
_transfer({ from: from, to: to, amount: value });
}
/// @notice The ```receiveWithAuthorization``` function receives a transfer with a signed authorization from the payer
/// @dev This has an additional check to ensure that the payee's address matches the caller of this function to prevent front-running attacks
/// @dev EOA wallet signatures should be packed in the order of r, s, v
/// @param from Payer's address (Authorizer)
/// @param to Payee's address
/// @param value Amount to be transferred
/// @param validAfter The block.timestamp after which the authorization is valid
/// @param validBefore The block.timestamp before which the authorization is valid
/// @param nonce Unique nonce
/// @param v ECDSA signature parameter v
/// @param r ECDSA signature parameters r
/// @param s ECDSA signature parameters s
function receiveWithAuthorization(
address from,
address to,
uint256 value,
uint256 validAfter,
uint256 validBefore,
bytes32 nonce,
uint8 v,
bytes32 r,
bytes32 s
) external {
// Packs signature pieces into bytes
receiveWithAuthorization({
from: from,
to: to,
value: value,
validAfter: validAfter,
validBefore: validBefore,
nonce: nonce,
signature: abi.encodePacked(r, s, v)
});
}
/// @notice The ```receiveWithAuthorization``` function receives a transfer with a signed authorization from the payer
/// @dev This has an additional check to ensure that the payee's address matches the caller of this function to prevent front-running attacks
/// @dev EOA wallet signatures should be packed in the order of r, s, v
/// @param from Payer's address (Authorizer)
/// @param to Payee's address
/// @param value Amount to be transferred
/// @param validAfter The block.timestamp after which the authorization is valid
/// @param validBefore The block.timestamp before which the authorization is valid
/// @param nonce Unique nonce
/// @param signature Signature byte array produced by an EOA wallet or a contract wallet
function receiveWithAuthorization(
address from,
address to,
uint256 value,
uint256 validAfter,
uint256 validBefore,
bytes32 nonce,
bytes memory signature
) public {
// Checks: authorization validity
if (to != msg.sender) revert InvalidPayee({ caller: msg.sender, payee: to });
if (block.timestamp <= validAfter) revert InvalidAuthorization();
if (block.timestamp >= validBefore) revert ExpiredAuthorization();
_requireUnusedAuthorization({ authorizer: from, nonce: nonce });
// Checks: valid signature
_requireIsValidSignatureNow({
signer: from,
structHash: keccak256(
abi.encode(RECEIVE_WITH_AUTHORIZATION_TYPEHASH, from, to, value, validAfter, validBefore, nonce)
),
signature: signature
});
// Effects: mark authorization as used and transfer
_markAuthorizationAsUsed({ authorizer: from, nonce: nonce });
_transfer({ from: from, to: to, amount: value });
}
/// @notice The ```cancelAuthorization``` function cancels an authorization nonce
/// @dev EOA wallet signatures should be packed in the order of r, s, v
/// @param authorizer Authorizer's address
/// @param nonce Nonce of the authorization
/// @param v ECDSA signature v value
/// @param r ECDSA signature r value
/// @param s ECDSA signature s value
function cancelAuthorization(address authorizer, bytes32 nonce, uint8 v, bytes32 r, bytes32 s) external {
cancelAuthorization({ authorizer: authorizer, nonce: nonce, signature: abi.encodePacked(r, s, v) });
}
/// @notice The ```cancelAuthorization``` function cancels an authorization nonce
/// @dev EOA wallet signatures should be packed in the order of r, s, v
/// @param authorizer Authorizer's address
/// @param nonce Nonce of the authorization
/// @param signature Signature byte array produced by an EOA wallet or a contract wallet
function cancelAuthorization(address authorizer, bytes32 nonce, bytes memory signature) public {
_requireUnusedAuthorization({ authorizer: authorizer, nonce: nonce });
_requireIsValidSignatureNow({
signer: authorizer,
structHash: keccak256(abi.encode(CANCEL_AUTHORIZATION_TYPEHASH, authorizer, nonce)),
signature: signature
});
_getEIP3009ModuleStorage().isAuthorizationUsed[authorizer][nonce] = true;
emit AuthorizationCanceled({ authorizer: authorizer, nonce: nonce });
}
//==============================================================================
// Internal Checks Functions
//==============================================================================
/// @notice The ```_requireUnusedAuthorization``` checks that an authorization nonce is unused
/// @param authorizer Authorizer's address
/// @param nonce Nonce of the authorization
function _requireUnusedAuthorization(address authorizer, bytes32 nonce) private view {
if (_getEIP3009ModuleStorage().isAuthorizationUsed[authorizer][nonce])
revert UsedOrCanceledAuthorization();
}
//==============================================================================
// Internal Effects Functions
//==============================================================================
/// @notice The ```_markAuthorizationAsUsed``` function marks an authorization nonce as used
/// @param authorizer Authorizer's address
/// @param nonce Nonce of the authorization
function _markAuthorizationAsUsed(address authorizer, bytes32 nonce) private {
_getEIP3009ModuleStorage().isAuthorizationUsed[authorizer][nonce] = true;
emit AuthorizationUsed({ authorizer: authorizer, nonce: nonce });
}
//==============================================================================
// Views
//==============================================================================
/**
* @notice Returns the state of an authorization
* @dev Nonces are randomly generated 32-byte data unique to the authorizer's
* address
* @param authorizer Authorizer's address
* @param nonce Nonce of the authorization
* @return True if the nonce is used
*/
function authorizationState(
address authorizer,
bytes32 nonce
) external view returns (bool) {
return _getEIP3009ModuleStorage().isAuthorizationUsed[authorizer][nonce];
}
//==============================================================================
// Overridden methods
//==============================================================================
function _transfer(address from, address to, uint256 amount) internal virtual {}
//==============================================================================
// Events
//==============================================================================
/// @notice ```AuthorizationUsed``` event is emitted when an authorization is used
/// @param authorizer Authorizer's address
/// @param nonce Nonce of the authorization
event AuthorizationUsed(address indexed authorizer, bytes32 indexed nonce);
/// @notice ```AuthorizationCanceled``` event is emitted when an authorization is canceled
/// @param authorizer Authorizer's address
/// @param nonce Nonce of the authorization
event AuthorizationCanceled(address indexed authorizer, bytes32 indexed nonce);
//==============================================================================
// Errors
//==============================================================================
/// @notice The ```InvalidPayee``` error is emitted when the payee does not match sender in receiveWithAuthorization
/// @param caller The caller of the function
/// @param payee The expected payee in the function
error InvalidPayee(address caller, address payee);
/// @notice The ```InvalidAuthorization``` error is emitted when the authorization is invalid because its too early
error InvalidAuthorization();
/// @notice The ```ExpiredAuthorization``` error is emitted when the authorization is expired
error ExpiredAuthorization();
/// @notice The ```UsedOrCanceledAuthorization``` error is emitted when the authorization nonce is already used or canceled
error UsedOrCanceledAuthorization();
}
// node_modules/@fraxfinance/layerzero-v2-upgradeable/oapp/contracts/oapp/OAppReceiverUpgradeable.sol
/**
* @title OAppReceiver
* @dev Abstract contract implementing the ILayerZeroReceiver interface and extending OAppCore for OApp receivers.
*/
abstract contract OAppReceiverUpgradeable is IOAppReceiver, OAppCoreUpgradeable {
// 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 = 1;
/**
* @dev Ownable is not initialized here on purpose. It should be initialized in the child contract to
* accommodate the different version of Ownable.
*/
function __OAppReceiver_init() internal onlyInitializing {}
function __OAppReceiver_init_unchained() internal onlyInitializing {}
/**
* @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 Retrieves the address responsible for 'sending' composeMsg's to the Endpoint.
* @return sender The address responsible for 'sending' composeMsg's to the Endpoint.
*
* @dev Applications can optionally choose to implement a separate composeMsg sender that is NOT the bridging layer.
* @dev The default sender IS the OApp implementer.
*/
function composeMsgSender() public view virtual returns (address sender) {
return 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;
}
// contracts/modules/PermitModule.sol
/// @dev Ripped from OZ 4.9.4 ERC20Permit.sol with namespaced storage and support of ERC1271 signatures
abstract contract PermitModule is SignatureModule {
using Counters for Counters.Counter;
//==============================================================================
// Storage
//==============================================================================
bytes32 private constant PERMIT_TYPEHASH =
keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
struct PermitModuleStorage {
mapping(address => Counters.Counter) nonces;
}
// keccak256(abi.encode(uint256(keccak256("frax.storage.PermitModule")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant PermitModuleStorageLocation = 0xb39b43abb0b115e0a59dece28477e279ee5f8e2fd55fbe200557c3ab864a0300;
function _getPermitModuleStorage() private pure returns (PermitModuleStorage storage $) {
assembly {
$.slot := PermitModuleStorageLocation
}
}
//==============================================================================
// Functions
//==============================================================================
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external virtual {
permit({
owner: owner,
spender: spender,
value: value,
deadline: deadline,
signature: abi.encodePacked(r, s, v)
});
}
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
bytes memory signature
) public virtual {
require(block.timestamp <= deadline, "ERC20Permit: expired deadline");
_requireIsValidSignatureNow({
signer: owner,
structHash: keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline)),
signature: signature
});
_approve(owner, spender, value);
}
function nonces(address owner) public view virtual returns (uint256) {
PermitModuleStorage storage $ = _getPermitModuleStorage();
return $.nonces[owner].current();
}
function DOMAIN_SEPARATOR() external view returns (bytes32) {
return _domainSeparatorV4();
}
function _useNonce(address owner) internal virtual returns (uint256 current) {
PermitModuleStorage storage $ = _getPermitModuleStorage();
current = $.nonces[owner].current();
$.nonces[owner].increment();
}
//==============================================================================
// Virtual overriden methods
//==============================================================================
function _approve(address owner, address spender, uint256 amount) internal virtual {}
}
// node_modules/@fraxfinance/layerzero-v2-upgradeable/oapp/contracts/oapp/OAppSenderUpgradeable.sol
/**
* @title OAppSender
* @dev Abstract contract implementing the OAppSender functionality for sending messages to a LayerZero endpoint.
*/
abstract contract OAppSenderUpgradeable is OAppCoreUpgradeable {
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;
/**
* @dev Ownable is not initialized here on purpose. It should be initialized in the child contract to
* accommodate the different version of Ownable.
*/
function __OAppSender_init() internal onlyInitializing {}
function __OAppSender_init_unchained() internal onlyInitializing {}
/**
* @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
endpoint.send{ value: messageValue }(
// solhint-disable-next-line check-send-result
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);
}
}
// node_modules/@fraxfinance/layerzero-v2-upgradeable/oapp/contracts/oft/interfaces/IOFT.sol
/**
* @dev Struct representing token parameters for the OFT send() operation.
*/
struct SendParam {
uint32 dstEid; // Destination endpoint ID.
bytes32 to; // Recipient address.
uint256 amountLD; // Amount to send in local decimals.
uint256 minAmountLD; // Minimum amount to send in local decimals.
bytes extraOptions; // Additional options supplied by the caller to be used in the LayerZero message.
bytes composeMsg; // The composed message for the send() operation.
bytes oftCmd; // The OFT command to be executed, unused in default OFT implementations.
}
/**
* @dev Struct representing OFT limit information.
* @dev These amounts can change dynamically and are up the 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(
// GUID of the OFT message.
// Destination Endpoint ID.
// Address of the sender on the src chain.
// Amount of tokens sent in local decimals.
// Amount of tokens received in local decimals.
bytes32 indexed guid,
uint32 dstEid,
address indexed fromAddress,
uint256 amountSentLD,
uint256 amountReceivedLD
);
event OFTReceived(
// GUID of the OFT message.
// Source Endpoint ID.
// Address of the recipient on the dst chain.
// Amount of tokens received in local decimals.
bytes32 indexed guid,
uint32 srcEid,
address indexed toAddress,
uint256 amountReceivedLD
);
/**
* @notice Retrieves interfaceID and the version of the OFT.
* @return interfaceId The interface ID.
* @return version The version.
*
* @dev interfaceId: This specific interface ID is '0x02e49c2c'.
* @dev version: Indicates a cross-chain compatible msg encoding with other OFTs.
* @dev If a new feature is added to the OFT cross-chain msg encoding, the version will be incremented.
* ie. localOFT version(x,1) CAN send messages to remoteOFT version(x,1)
*/
function oftVersion() external view returns (bytes4 interfaceId, uint64 version);
/**
* @notice Retrieves the address of the token associated with the OFT.
* @return token The address of the ERC20 token implementation.
*/
function token() external view returns (address);
/**
* @notice Indicates whether the OFT contract requires approval of the 'token()' to send.
* @return requiresApproval Needs approval of the underlying token implementation.
*
* @dev Allows things like wallet implementers to determine integration requirements,
* without understanding the underlying token implementation.
*/
function approvalRequired() external view returns (bool);
/**
* @notice Retrieves the shared decimals of the OFT.
* @return sharedDecimals The shared decimals of the OFT.
*/
function sharedDecimals() external view returns (uint8);
/**
* @notice Provides a quote for OFT-related operations.
* @param _sendParam The parameters for the send operation.
* @return limit The OFT limit information.
* @return oftFeeDetails The details of OFT fees.
* @return receipt The OFT receipt information.
*/
function quoteOFT(
SendParam calldata _sendParam
) external view returns (OFTLimit memory, OFTFeeDetail[] memory oftFeeDetails, OFTReceipt memory);
/**
* @notice Provides a quote for the send() operation.
* @param _sendParam The parameters for the send() operation.
* @param _payInLzToken Flag indicating whether the caller is paying in the LZ token.
* @return fee The calculated LayerZero messaging fee from the send() operation.
*
* @dev MessagingFee: LayerZero msg fee
* - nativeFee: The native fee.
* - lzTokenFee: The lzToken fee.
*/
function quoteSend(SendParam calldata _sendParam, bool _payInLzToken) external view returns (MessagingFee memory);
/**
* @notice Executes the send() operation.
* @param _sendParam The parameters for the send operation.
* @param _fee The fee information supplied by the caller.
* - nativeFee: The native fee.
* - lzTokenFee: The lzToken fee.
* @param _refundAddress The address to receive any excess funds from fees etc. on the src.
* @return receipt The LayerZero messaging receipt from the send() operation.
* @return oftReceipt The OFT receipt information.
*
* @dev MessagingReceipt: LayerZero msg receipt
* - guid: The unique identifier for the sent message.
* - nonce: The nonce of the sent message.
* - fee: The LayerZero fee incurred for the message.
*/
function send(
SendParam calldata _sendParam,
MessagingFee calldata _fee,
address _refundAddress
) external payable returns (MessagingReceipt memory, OFTReceipt memory);
}
// node_modules/@fraxfinance/layerzero-v2-upgradeable/oapp/contracts/precrime/OAppPreCrimeSimulatorUpgradeable.sol
/**
* @title OAppPreCrimeSimulator
* @dev Abstract contract serving as the base for preCrime simulation functionality in an OApp.
*/
abstract contract OAppPreCrimeSimulatorUpgradeable is IOAppPreCrimeSimulator, OwnableUpgradeable {
struct OAppPreCrimeSimulatorStorage {
// The address of the preCrime implementation.
address preCrime;
}
// keccak256(abi.encode(uint256(keccak256("layerzerov2.storage.oappprecrimesimulator")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant OAppPreCrimeSimulatorStorageLocation =
0xefb041d771d6daaa55702fff6eb740d63ba559a75d2d1d3e151c78ff2480b600;
function _getOAppPreCrimeSimulatorStorage() internal pure returns (OAppPreCrimeSimulatorStorage storage $) {
assembly {
$.slot := OAppPreCrimeSimulatorStorageLocation
}
}
/**
* @dev Ownable is not initialized here on purpose. It should be initialized in the child contract to
* accommodate the different version of Ownable.
*/
function __OAppPreCrimeSimulator_init() internal onlyInitializing {}
function __OAppPreCrimeSimulator_init_unchained() internal onlyInitializing {}
function preCrime() external view override returns (address) {
OAppPreCrimeSimulatorStorage storage $ = _getOAppPreCrimeSimulatorStorage();
return $.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 {
OAppPreCrimeSimulatorStorage storage $ = _getOAppPreCrimeSimulatorStorage();
$.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);
}
// node_modules/@fraxfinance/layerzero-v2-upgradeable/oapp/contracts/oapp/OAppUpgradeable.sol
// @dev Import the 'MessagingFee' and 'MessagingReceipt' so it's exposed to OApp implementers
// solhint-disable-next-line no-unused-import
// @dev Import the 'Origin' so it's exposed to OApp implementers
// solhint-disable-next-line no-unused-import
/**
* @title OApp
* @dev Abstract contract serving as the base for OApp implementation, combining OAppSender and OAppReceiver functionality.
*/
abstract contract OAppUpgradeable is OAppSenderUpgradeable, OAppReceiverUpgradeable {
/**
* @dev Constructor to initialize the OApp with the provided endpoint and owner.
* @param _endpoint The address of the LOCAL LayerZero endpoint.
*/
constructor(address _endpoint) OAppCoreUpgradeable(_endpoint) {}
/**
* @dev Initializes the OApp with the provided delegate.
* @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.
* @dev Ownable is not initialized here on purpose. It should be initialized in the child contract to
* accommodate the different version of Ownable.
*/
function __OApp_init(address _delegate) internal onlyInitializing {
__OAppCore_init(_delegate);
}
function __OApp_init_unchained() internal onlyInitializing {}
/**
* @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(OAppSenderUpgradeable, OAppReceiverUpgradeable)
returns (uint64 senderVersion, uint64 receiverVersion)
{
return (SENDER_VERSION, RECEIVER_VERSION);
}
}
// node_modules/@fraxfinance/layerzero-v2-upgradeable/oapp/contracts/oft/OFTCoreUpgradeable.sol
/**
* @title OFTCore
* @dev Abstract contract for the OftChain (OFT) token.
*/
abstract contract OFTCoreUpgradeable is
IOFT,
OAppUpgradeable,
OAppPreCrimeSimulatorUpgradeable,
OAppOptionsType3Upgradeable
{
using OFTMsgCodec for bytes;
using OFTMsgCodec for bytes32;
struct OFTCoreStorage {
// Address of an optional contract to inspect both 'message' and 'options'
address msgInspector;
}
// keccak256(abi.encode(uint256(keccak256("layerzerov2.storage.oftcore")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant OFTCoreStorageLocation =
0x41db8a78b0206aba5c54bcbfc2bda0d84082a84eb88e680379a57b9e9f653c00;
// @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;
event MsgInspectorSet(address inspector);
function _getOFTCoreStorage() internal pure returns (OFTCoreStorage storage $) {
assembly {
$.slot := OFTCoreStorageLocation
}
}
/**
* @dev Constructor.
* @param _localDecimals The decimals of the token on the local chain (this chain).
* @param _endpoint The address of the LayerZero endpoint.
*/
constructor(uint8 _localDecimals, address _endpoint) OAppUpgradeable(_endpoint) {
if (_localDecimals < sharedDecimals()) revert InvalidLocalDecimals();
decimalConversionRate = 10 ** (_localDecimals - sharedDecimals());
}
/**
* @dev Initializes the OFTCore contract.
* @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.
* @dev Ownable is not initialized here on purpose. It should be initialized in the child contract to
* accommodate the different version of Ownable.
*/
function __OFTCore_init(address _delegate) internal onlyInitializing {
__OAppCore_init(_delegate);
}
function __OFTCore_init_unchained() internal onlyInitializing {}
function msgInspector() public view returns (address) {
OFTCoreStorage storage $ = _getOFTCoreStorage();
return $.msgInspector;
}
/**
* @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 pure 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 {
OFTCoreStorage storage $ = _getOFTCoreStorage();
$.msgInspector = _msgInspector;
emit MsgInspectorSet(_msgInspector);
}
/**
* @notice Provides a quote for OFT-related operations.
* @param _sendParam The parameters for the send operation.
* @return oftLimit The OFT limit information.
* @return oftFeeDetails The details of OFT fees.
* @return oftReceipt The OFT receipt information.
*/
function quoteOFT(
SendParam calldata _sendParam
)
external
view
virtual
returns (OFTLimit memory oftLimit, OFTFeeDetail[] memory oftFeeDetails, OFTReceipt memory oftReceipt)
{
uint256 minAmountLD = 0; // Unused in the default implementation.
uint256 maxAmountLD = type(uint64).max; // Unused in the default implementation.
oftLimit = OFTLimit(minAmountLD, maxAmountLD);
// Unused in the default implementation; reserved for future complex fee details.
oftFeeDetails = new OFTFeeDetail[](0);
// @dev This is the same as the send() operation, but without the actual send.
// - amountSentLD is the amount in local decimals that would be sent from the sender.
// - amountReceivedLD is the amount in local decimals that will be credited to the recipient on the remote OFT instance.
// @dev The amountSentLD MIGHT not equal the amount the user actually receives. HOWEVER, the default does.
(uint256 amountSentLD, uint256 amountReceivedLD) = _debitView(
_sendParam.amountLD,
_sendParam.minAmountLD,
_sendParam.dstEid
);
oftReceipt = OFTReceipt(amountSentLD, amountReceivedLD);
}
/**
* @notice Provides a quote for the send() operation.
* @param _sendParam The parameters for the send() operation.
* @param _payInLzToken Flag indicating whether the caller is paying in the LZ token.
* @return msgFee The calculated LayerZero messaging fee from the send() operation.
*
* @dev MessagingFee: LayerZero msg fee
* - nativeFee: The native fee.
* - lzTokenFee: The lzToken fee.
*/
function quoteSend(
SendParam calldata _sendParam,
bool _payInLzToken
) external view virtual returns (MessagingFee memory msgFee) {
// @dev mock the amount to receive, this is the same operation used in the send().
// The quote is as similar as possible to the actual send() operation.
(, uint256 amountReceivedLD) = _debitView(_sendParam.amountLD, _sendParam.minAmountLD, _sendParam.dstEid);
// @dev Builds the options and OFT message to quote in the endpoint.
(bytes memory message, bytes memory options) = _buildMsgAndOptions(_sendParam, amountReceivedLD);
// @dev Calculates the LayerZero fee for the send() operation.
return _quote(_sendParam.dstEid, message, options, _payInLzToken);
}
/**
* @dev Executes the send operation.
* @param _sendParam The parameters for the send operation.
* @param _fee The calculated fee for the send() operation.
* - nativeFee: The native fee.
* - lzTokenFee: The lzToken fee.
* @param _refundAddress The address to receive any excess funds.
* @return msgReceipt The receipt for the send operation.
* @return oftReceipt The OFT receipt information.
*
* @dev MessagingReceipt: LayerZero msg receipt
* - guid: The unique identifier for the sent message.
* - nonce: The nonce of the sent message.
* - fee: The LayerZero fee incurred for the message.
*/
function send(
SendParam calldata _sendParam,
MessagingFee calldata _fee,
address _refundAddress
) external payable virtual returns (MessagingReceipt memory msgReceipt, OFTReceipt memory oftReceipt) {
// @dev Applies the token transfers regarding this send() operation.
// - amountSentLD is the amount in local decimals that was ACTUALLY sent/debited from the sender.
// - amountReceivedLD is the amount in local decimals that will be received/credited to the recipient on the remote OFT instance.
(uint256 amountSentLD, uint256 amountReceivedLD) = _debit(
_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);
OFTCoreStorage storage $ = _getOFTCoreStorage();
// @dev Optionally inspect the message and options depending if the OApp owner has set a msg inspector.
// @dev If it fails inspection, needs to revert in the implementation. ie. does not rely on return boolean
if ($.msgInspector != address(0)) IOAppMsgInspector($.msgInspector).inspect(message, options);
}
/**
* @dev Internal function to handle the receive on the LayerZero endpoint.
* @param _origin The origin information.
* - srcEid: The source chain endpoint ID.
* - sender: The sender address from the src chain.
* - nonce: The nonce of the LayerZero message.
* @param _guid The unique identifier for the received LayerZero message.
* @param _message The encoded message.
* @dev _executor The address of the executor.
* @dev _extraData Additional data.
*/
function _lzReceive(
Origin calldata _origin,
bytes32 _guid,
bytes calldata _message,
address /*_executor*/, // @dev unused in the default implementation.
bytes calldata /*_extraData*/ // @dev unused in the default implementation.
) internal virtual override {
// @dev The src sending chain doesnt know the address length on this chain (potentially non-evm)
// Thus everything is bytes32() encoded in flight.
address toAddress = _message.sendTo().bytes32ToAddress();
// @dev Credit the amountLD to the recipient and return the ACTUAL amount the recipient received in local decimals
uint256 amountReceivedLD = _credit(toAddress, _toLD(_message.amountSD()), _origin.srcEid);
if (_message.isComposed()) {
// @dev Proprietary composeMsg format for the OFT.
bytes memory composeMsg = OFTComposeMsgCodec.encode(
_origin.nonce,
_origin.srcEid,
amountReceivedLD,
_message.composeMsg()
);
// @dev Stores the lzCompose payload that will be executed in a separate tx.
// Standardizes functionality for executing arbitrary contract invocation on some non-evm chains.
// @dev The off-chain executor will listen and process the msg based on the src-chain-callers compose options passed.
// @dev The index is used when a OApp needs to compose multiple msgs on lzReceive.
// For default OFT implementation there is only 1 compose msg per lzReceive, thus its always 0.
endpoint.sendCompose(toAddress, _guid, 0, /* the index of the composed message*/ composeMsg);
}
emit OFTReceived(_guid, _origin.srcEid, toAddress, amountReceivedLD);
}
/**
* @dev Internal function to handle the OAppPreCrimeSimulator simulated receive.
* @param _origin The origin information.
* - srcEid: The source chain endpoint ID.
* - sender: The sender address from the src chain.
* - nonce: The nonce of the LayerZero message.
* @param _guid The unique identifier for the received LayerZero message.
* @param _message The LayerZero message.
* @param _executor The address of the off-chain executor.
* @param _extraData Arbitrary data passed by the msg executor.
*
* @dev Enables the preCrime simulator to mock sending lzReceive() messages,
* routes the msg down from the OAppPreCrimeSimulator, and back up to the OAppReceiver.
*/
function _lzReceiveSimulate(
Origin calldata _origin,
bytes32 _guid,
bytes calldata _message,
address _executor,
bytes calldata _extraData
) internal virtual override {
_lzReceive(_origin, _guid, _message, _executor, _extraData);
}
/**
* @dev Check if the peer is considered 'trusted' by the OApp.
* @param _eid The endpoint ID to check.
* @param _peer The peer to check.
* @return Whether the peer passed is considered 'trusted' by the OApp.
*
* @dev Enables OAppPreCrimeSimulator to check whether a potential Inbound Packet is from a trusted source.
*/
function isPeer(uint32 _eid, bytes32 _peer) public view virtual override returns (bool) {
return peers(_eid) == _peer;
}
/**
* @dev Internal function to remove dust from the given local decimal amount.
* @param _amountLD The amount in local decimals.
* @return amountLD The amount after removing dust.
*
* @dev Prevents the loss of dust when moving amounts between chains with different decimals.
* @dev eg. uint(123) with a conversion rate of 100 becomes uint(100).
*/
function _removeDust(uint256 _amountLD) internal view virtual returns (uint256 amountLD) {
return (_amountLD / decimalConversionRate) * decimalConversionRate;
}
/**
* @dev Internal function to convert an amount from shared decimals into local decimals.
* @param _amountSD The amount in shared decimals.
* @return amountLD The amount in local decimals.
*/
function _toLD(uint64 _amountSD) internal view virtual returns (uint256 amountLD) {
return _amountSD * decimalConversionRate;
}
/**
* @dev Internal function to convert an amount from local decimals into shared decimals.
* @param _amountLD The amount in local decimals.
* @return amountSD The amount in shared decimals.
*/
function _toSD(uint256 _amountLD) internal view virtual returns (uint64 amountSD) {
return uint64(_amountLD / decimalConversionRate);
}
/**
* @dev Internal function to mock the amount mutation from a OFT debit() operation.
* @param _amountLD The amount to send in local decimals.
* @param _minAmountLD The minimum amount to send in local decimals.
* @dev _dstEid The destination endpoint ID.
* @return amountSentLD The amount sent, in local decimals.
* @return amountReceivedLD The amount to be received on the remote chain, in local decimals.
*
* @dev This is where things like fees would be calculated and deducted from the amount to be received on the remote.
*/
function _debitView(
uint256 _amountLD,
uint256 _minAmountLD,
uint32 /*_dstEid*/
) internal view virtual returns (uint256 amountSentLD, uint256 amountReceivedLD) {
// @dev Remove the dust so nothing is lost on the conversion between chains with different decimals for the token.
amountSentLD = _removeDust(_amountLD);
// @dev The amount to send is the same as amount received in the default implementation.
amountReceivedLD = amountSentLD;
// @dev Check for slippage.
if (amountReceivedLD < _minAmountLD) {
revert SlippageExceeded(amountReceivedLD, _minAmountLD);
}
}
/**
* @dev Internal function to perform a debit operation.
* @param _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(
uint256 _amountLD,
uint256 _minAmountLD,
uint32 _dstEid
) internal virtual returns (uint256 amountSentLD, uint256 amountReceivedLD);
/**
* @dev Internal function to perform a credit operation.
* @param _to The address to credit.
* @param _amountLD The amount to credit in local decimals.
* @param _srcEid The source endpoint ID.
* @return amountReceivedLD The amount ACTUALLY received in local decimals.
*
* @dev Defined here but are intended to be overriden depending on the OFT implementation.
* @dev Depending on OFT implementation the _amountLD could differ from the amountReceivedLD.
*/
function _credit(
address _to,
uint256 _amountLD,
uint32 _srcEid
) internal virtual returns (uint256 amountReceivedLD);
}
// node_modules/@fraxfinance/layerzero-v2-upgradeable/oapp/contracts/oft/OFTUpgradeable.sol
/**
* @title OFT Contract
* @dev OFT is an ERC-20 token that extends the functionality of the OFTCore contract.
*/
abstract contract OFTUpgradeable is OFTCoreUpgradeable, ERC20Upgradeable {
/**
* @dev Constructor for the OFT contract.
* @param _lzEndpoint The LayerZero endpoint address.
*/
constructor(address _lzEndpoint) OFTCoreUpgradeable(decimals(), _lzEndpoint) {}
/**
* @dev Initializes the OFT with the provided name, symbol, and delegate.
* @param _name The name of the OFT.
* @param _symbol The symbol of the OFT.
* @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.
* @dev Ownable is not initialized here on purpose. It should be initialized in the child contract to
* accommodate the different version of Ownable.
*/
function __OFT_init(string memory _name, string memory _symbol, address _delegate) internal onlyInitializing {
__ERC20_init(_name, _symbol);
__OFTCore_init(_delegate);
}
function __OFT_init_unchained() internal onlyInitializing {}
/**
* @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 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() external 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 _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(
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(msg.sender, amountSentLD);
}
/**
* @dev Credits tokens to the specified address.
* @param _to The address to credit the tokens to.
* @param _amountLD The amount of tokens to credit in local decimals.
* @dev _srcEid The source chain ID.
* @return amountReceivedLD The amount of tokens ACTUALLY received in local decimals.
*/
function _credit(
address _to,
uint256 _amountLD,
uint32 /*_srcEid*/
) internal virtual override returns (uint256 amountReceivedLD) {
// @dev Default OFT mints on dst.
_mint(_to, _amountLD);
// @dev In the case of NON-default OFT, the _amountLD MIGHT not be == amountReceivedLD.
return _amountLD;
}
}
// contracts/WFRAXTokenOFTUpgradeable.sol
contract WFRAXTokenOFTUpgradeable is OFTUpgradeable, EIP3009Module, PermitModule {
constructor(address _lzEndpoint) OFTUpgradeable(_lzEndpoint) {
_disableInitializers();
}
function version() public pure returns (string memory) {
return "1.1.0";
}
/// @dev This method is called specifically when upgrading an existing OFT
function initializeV110() external reinitializer(3) {
__EIP712_init(name(), version());
}
function name() public pure override returns (string memory) {
return "Wrapped Frax";
}
function symbol() public pure override returns (string memory) {
return "WFRAX";
}
// Helper views
function toLD(uint64 _amountSD) external view returns (uint256 amountLD) {
return _toLD(_amountSD);
}
function toSD(uint256 _amountLD) external view returns (uint64 amountSD) {
return _toSD(_amountLD);
}
function removeDust(uint256 _amountLD) public view returns (uint256 amountLD) {
return _removeDust(_amountLD);
}
function debitView(uint256 _amountLD, uint256 _minAmountLD, uint32 _dstEid) external view returns (uint256 amountSentLD, uint256 amountReceivedLD) {
/// @dev: _dstEid is unused in _debitView
return _debitView(_amountLD, _minAmountLD, _dstEid);
}
function buildMsgAndOptions(
SendParam calldata _sendParam,
uint256 _amountLD
) external view returns (bytes memory message, bytes memory options) {
return _buildMsgAndOptions(_sendParam, _amountLD);
}
//==============================================================================
// Overrides
//==============================================================================
/// @dev supports EIP3009
function _transfer(address from, address to, uint256 amount) internal override(EIP3009Module, ERC20Upgradeable) {
return ERC20Upgradeable._transfer(from, to, amount);
}
/// @dev supports EIP2612
function _approve(address owner, address spender, uint256 amount) internal override(PermitModule, ERC20Upgradeable) {
return ERC20Upgradeable._approve(owner, spender, amount);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_lzEndpoint","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ExpiredAuthorization","type":"error"},{"inputs":[],"name":"InvalidAuthorization","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":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"payee","type":"address"}],"name":"InvalidPayee","type":"error"},{"inputs":[],"name":"InvalidSignature","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":"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"},{"inputs":[],"name":"UsedOrCanceledAuthorization","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":[{"indexed":true,"internalType":"address","name":"authorizer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"AuthorizationCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorizer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"AuthorizationUsed","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","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":"uint8","name":"version","type":"uint8"}],"name":"Initialized","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":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"authorizer","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"authorizationState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"uint256","name":"_amountLD","type":"uint256"}],"name":"buildMsgAndOptions","outputs":[{"internalType":"bytes","name":"message","type":"bytes"},{"internalType":"bytes","name":"options","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"authorizer","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"cancelAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"authorizer","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"cancelAuthorization","outputs":[],"stateMutability":"nonpayable","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":"composeMsgSender","outputs":[{"internalType":"address","name":"sender","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountLD","type":"uint256"},{"internalType":"uint256","name":"_minAmountLD","type":"uint256"},{"internalType":"uint32","name":"_dstEid","type":"uint32"}],"name":"debitView","outputs":[{"internalType":"uint256","name":"amountSentLD","type":"uint256"},{"internalType":"uint256","name":"amountReceivedLD","type":"uint256"}],"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":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endpoint","outputs":[{"internalType":"contract ILayerZeroEndpointV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_eid","type":"uint32"},{"internalType":"uint16","name":"_msgType","type":"uint16"}],"name":"enforcedOptions","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initializeV110","outputs":[],"stateMutability":"nonpayable","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":"pure","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":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","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":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"receiveWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"receiveWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountLD","type":"uint256"}],"name":"removeDust","outputs":[{"internalType":"uint256","name":"amountLD","type":"uint256"}],"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":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint64","name":"_amountSD","type":"uint64"}],"name":"toLD","outputs":[{"internalType":"uint256","name":"amountLD","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountLD","type":"uint256"}],"name":"toSD","outputs":[{"internalType":"uint64","name":"amountSD","type":"uint64"}],"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":"amount","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":"amount","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"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"transferWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"transferWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"}]Contract Creation Code
60c060405234801562000010575f80fd5b5060405162004c8b38038062004c8b833981016040819052620000339162000134565b6001600160a01b038116608052806012816200005160068362000177565b6200005e90600a62000292565b60a052506200006f91505062000076565b50620002a2565b5f54610100900460ff1615620000e25760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b5f5460ff9081161462000132575f805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b5f6020828403121562000145575f80fd5b81516001600160a01b03811681146200015c575f80fd5b9392505050565b634e487b7160e01b5f52601160045260245ffd5b60ff828116828216039081111562000193576200019362000163565b92915050565b600181815b80851115620001d957815f1904821115620001bd57620001bd62000163565b80851615620001cb57918102915b93841c93908002906200019e565b509250929050565b5f82620001f15750600162000193565b81620001ff57505f62000193565b8160018114620002185760028114620002235762000243565b600191505062000193565b60ff84111562000237576200023762000163565b50506001821b62000193565b5060208310610133831016604e8410600b841016171562000268575081810a62000193565b62000274838362000199565b805f19048211156200028a576200028a62000163565b029392505050565b5f6200015c60ff841683620001e1565b60805160a0516149816200030a5f395f81816108b101528181612072015281816126a7015261271901525f818161073401528181610d4d01528181611be401528181612172015281816123470152818161279901528181612f220152612fd901526149815ff3fe6080604052600436106103a8575f3560e01c8063857749b0116101e9578063bd815db011610108578063dd62ed3e1161009d578063f01630231161006d578063f016302314610b9e578063f2fde38b14610bd2578063fc0c546a14610665578063ff7bd03d14610bf1575f80fd5b8063dd62ed3e14610af1578063e3ee160e14610b10578063e94a010214610b2f578063ef55bec614610b7f575f80fd5b8063cf092995116100d8578063cf09299514610a81578063d045a0dc14610aa0578063d424388514610ab3578063d505accf14610ad2575f80fd5b8063bd815db014610a0f578063c077998814610a22578063c7c7f5b314610a41578063ca5eb5e114610a62575f80fd5b8063a9059cbb1161017e578063b92d0eff1161014e578063b92d0eff14610665578063b98bd07014610994578063bb0b6a53146109b3578063bc70b354146109f0575f80fd5b8063a9059cbb14610923578063b3a5abeb14610942578063b731ea0a14610961578063b7b7289914610975575f80fd5b8063963efcaa116101b9578063963efcaa146108a05780639f68b964146108d35780639fd5a6cf146108e5578063a457c2d714610904575f80fd5b8063857749b01461082457806388b7ab63146108375780638da5cb5b1461085657806395d89b4114610873575f80fd5b80633644e515116102d55780635a0dfe4d1161026a578063715018a61161023a578063715018a6146107a95780637d25a05e146107bd5780637ecebe00146107de57806384b0196e146107fd575f80fd5b80635a0dfe4d146106e25780635e280f11146107235780636fc1b31e1461075657806370a0823114610775575f80fd5b806352ae2879116102a557806352ae28791461066557806354fd4d50146106775780635535d461146106a45780635a049a70146106c3575f80fd5b80633644e515146105f25780633714fffa14610606578063395093511461061a5780633b6f743b14610639575f80fd5b8063134d4f251161034b5780631f5e13341161031b5780631f5e13341461057f57806323b872dd14610593578063313ce567146105b25780633400288b146105d3575f80fd5b8063134d4f25146104f4578063156a0d0f1461051b57806317442b701461054157806318160ddd14610561575f80fd5b80630d35b415116103865780630d35b4151461044e5780630e78842c1461047c578063111ecdad146104b357806313137d65146104df575f80fd5b8063056d62de146103ac57806306fdde03146103e2578063095ea7b31461041f575b5f80fd5b3480156103b7575f80fd5b506103cb6103c63660046135d7565b610c10565b6040516103d9929190613665565b60405180910390f35b3480156103ed575f80fd5b5060408051808201909152600c81526b0aee4c2e0e0cac8408ce4c2f60a31b60208201525b6040516103d99190613689565b34801561042a575f80fd5b5061043e6104393660046136af565b610c29565b60405190151581526020016103d9565b348015610459575f80fd5b5061046d6104683660046136d9565b610c42565b6040516103d99392919061370a565b348015610487575f80fd5b5061049b6104963660046137a1565b610d0d565b6040516001600160401b0390911681526020016103d9565b3480156104be575f80fd5b506104c7610d17565b6040516001600160a01b0390911681526020016103d9565b6104f26104ed366004613805565b610d4b565b005b3480156104ff575f80fd5b50610508600281565b60405161ffff90911681526020016103d9565b348015610526575f80fd5b506040805162b9270b60e21b815260016020820152016103d9565b34801561054c575f80fd5b506040805160018082526020820152016103d9565b34801561056c575f80fd5b506067545b6040519081526020016103d9565b34801561058a575f80fd5b50610508600181565b34801561059e575f80fd5b5061043e6105ad36600461389d565b610e0b565b3480156105bd575f80fd5b5060125b60405160ff90911681526020016103d9565b3480156105de575f80fd5b506104f26105ed3660046138f3565b610e30565b3480156105fd575f80fd5b50610571610e9b565b348015610611575f80fd5b506104f2610ea9565b348015610625575f80fd5b5061043e6106343660046136af565b610fcf565b348015610644575f80fd5b5061065861065336600461391a565b610ff0565b6040516103d99190613968565b348015610670575f80fd5b50306104c7565b348015610682575f80fd5b506040805180820190915260058152640312e312e360dc1b6020820152610412565b3480156106af575f80fd5b506104126106be366004613990565b611054565b3480156106ce575f80fd5b506104f26106dd3660046139d1565b61112c565b3480156106ed575f80fd5b5061043e6106fc3660046138f3565b63ffffffff919091165f9081525f805160206148ec83398151915260205260409020541490565b34801561072e575f80fd5b506104c77f000000000000000000000000000000000000000000000000000000000000000081565b348015610761575f80fd5b506104f2610770366004613a1d565b611161565b348015610780575f80fd5b5061057161078f366004613a1d565b6001600160a01b03165f9081526065602052604090205490565b3480156107b4575f80fd5b506104f26111dd565b3480156107c8575f80fd5b5061049b6107d73660046138f3565b5f92915050565b3480156107e9575f80fd5b506105716107f8366004613a1d565b6111f0565b348015610808575f80fd5b5061081161122e565b6040516103d99796959493929190613a38565b34801561082f575f80fd5b5060066105c1565b348015610842575f80fd5b506104f2610851366004613bb3565b6112d7565b348015610861575f80fd5b506033546001600160a01b03166104c7565b34801561087e575f80fd5b506040805180820190915260058152640ae8ca482b60db1b6020820152610412565b3480156108ab575f80fd5b506105717f000000000000000000000000000000000000000000000000000000000000000081565b3480156108de575f80fd5b505f61043e565b3480156108f0575f80fd5b506104f26108ff366004613c35565b6113cf565b34801561090f575f80fd5b5061043e61091e3660046136af565b611498565b34801561092e575f80fd5b5061043e61093d3660046136af565b61151d565b34801561094d575f80fd5b5061057161095c366004613cb9565b61152a565b34801561096c575f80fd5b506104c7611534565b348015610980575f80fd5b506104f261098f366004613cd4565b61155c565b34801561099f575f80fd5b506104f26109ae366004613d68565b61161c565b3480156109be575f80fd5b506105716109cd366004613da6565b63ffffffff165f9081525f805160206148ec833981519152602052604090205490565b3480156109fb575f80fd5b50610412610a0a366004613dbf565b611798565b6104f2610a1d366004613d68565b611930565b348015610a2d575f80fd5b50610571610a3c3660046137a1565b611abc565b610a54610a4f366004613e1b565b611ac6565b6040516103d9929190613e83565b348015610a6d575f80fd5b506104f2610a7c366004613a1d565b611bbd565b348015610a8c575f80fd5b506104f2610a9b366004613bb3565b611c37565b6104f2610aae366004613805565b611cc4565b348015610abe575f80fd5b506104f2610acd366004613a1d565b611cf3565b348015610add575f80fd5b506104f2610aec366004613ed4565b611d67565b348015610afc575f80fd5b50610571610b0b366004613f3d565b611d97565b348015610b1b575f80fd5b506104f2610b2a366004613f69565b611dc1565b348015610b3a575f80fd5b5061043e610b493660046136af565b6001600160a01b03919091165f9081525f8051602061490c83398151915260209081526040808320938352929052205460ff1690565b348015610b8a575f80fd5b506104f2610b99366004613f69565b611dfe565b348015610ba9575f80fd5b50610bbd610bb8366004613fe5565b611e30565b604080519283526020830191909152016103d9565b348015610bdd575f80fd5b506104f2610bec366004613a1d565b611e4a565b348015610bfc575f80fd5b5061043e610c0b366004614017565b611ec3565b606080610c1d8484611ee0565b915091505b9250929050565b5f33610c36818585612021565b60019150505b92915050565b604080518082019091525f80825260208201526060610c7260405180604001604052805f81526020015f81525090565b6040805180820182525f8082526001600160401b03602080840182905284518381529081019094529195509182610ccb565b604080518082019091525f815260606020820152815260200190600190039081610ca45790505b5093505f80610cef604089013560608a0135610cea60208c018c613da6565b612031565b60408051808201909152918252602082015296989597505050505050565b5f610c3c8261206c565b5f807f41db8a78b0206aba5c54bcbfc2bda0d84082a84eb88e680379a57b9e9f653c005b546001600160a01b031692915050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163314610d9b576040516391ac5e4f60e01b81523360048201526024015b60405180910390fd5b60208701803590610db590610db0908a613da6565b612097565b14610df357610dc76020880188613da6565b60405163309afaf360e21b815263ffffffff909116600482015260208801356024820152604401610d92565b610e02878787878787876120e0565b50505050505050565b5f33610e1885828561223e565b610e238585856122b6565b60019150505b9392505050565b610e386122c1565b63ffffffff82165f8181525f805160206148ec833981519152602081815260409283902085905582519384528301849052917f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b91015b60405180910390a1505050565b5f610ea461231b565b905090565b5f54600390610100900460ff16158015610ec957505f5460ff8083169116105b610f2c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610d92565b5f805461ffff191660ff831617610100179055610f8c610f6b60408051808201909152600c81526b0aee4c2e0e0cac8408ce4c2f60a31b602082015290565b6040805180820190915260058152640312e312e360dc1b6020820152612324565b5f805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b5f33610c36818585610fe18383611d97565b610feb9190614045565b612021565b604080518082019091525f80825260208201525f61101e60408501356060860135610cea6020880188613da6565b9150505f8061102d8684611ee0565b909250905061104a6110426020880188613da6565b838388612332565b9695505050505050565b63ffffffff82165f9081527f8d2bda5d9f6ffb5796910376005392955773acee5548d0fcdb10e7c264ea00006020818152604080842061ffff86168552909152909120805460609291906110a790614058565b80601f01602080910402602001604051908101604052809291908181526020018280546110d390614058565b801561111e5780601f106110f55761010080835404028352916020019161111e565b820191905f5260205f20905b81548152906001019060200180831161110157829003601f168201915b505050505091505092915050565b61115a85858484876040516020016111469392919061408a565b60405160208183030381529060405261155c565b5050505050565b6111696122c1565b7f41db8a78b0206aba5c54bcbfc2bda0d84082a84eb88e680379a57b9e9f653c0080546001600160a01b0319166001600160a01b03831690811782556040519081527ff0be4f1e87349231d80c36b33f9e8639658eeaf474014dee15a3e6a4d4414197906020015b60405180910390a15050565b6111e56122c1565b6111ee5f612410565b565b6001600160a01b0381165f9081527fb39b43abb0b115e0a59dece28477e279ee5f8e2fd55fbe200557c3ab864a030060208190526040822054610e29565b5f60608082808083815f8051602061492c833981519152805490915015801561125957506001810154155b61129d5760405162461bcd60e51b81526020600482015260156024820152741152540dcc4c8e88155b9a5b9a5d1a585b1a5e9959605a1b6044820152606401610d92565b6112a5612461565b6112ad612521565b604080515f80825260208201909252600f60f81b9c939b5091995046985030975095509350915050565b6001600160a01b038616331461131157604051637f54a22160e11b81523360048201526001600160a01b0387166024820152604401610d92565b83421161133157604051632ce87eeb60e01b815260040160405180910390fd5b8242106113515760405163a899ef9360e01b815260040160405180910390fd5b61135b878361255f565b6113ba877fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de85f1b89898989898960405160200161139e97969594939291906140ad565b60405160208183030381529060405280519060200120836125ae565b6113c487836125f2565b610e028787876122b6565b8142111561141f5760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610d92565b61148d857f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98787876114508b612657565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810185905260e00161139e565b61115a858585612021565b5f33816114a58286611d97565b9050838110156115055760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610d92565b6115128286868403612021565b506001949350505050565b5f33610c368185856122b6565b5f610c3c826126a1565b5f807fefb041d771d6daaa55702fff6eb740d63ba559a75d2d1d3e151c78ff2480b600610d3b565b611566838361255f565b604080517f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a159742960208201526001600160a01b03851691810191909152606081018390526115b690849060800161139e565b6001600160a01b0383165f8181525f8051602061490c83398151915260209081526040808320868452909152808220805460ff19166001179055518492917f1cdd46ff242716cdaa72d159d339a485b3438398348d68f09d7c8c0a59353d8191a3505050565b6116246122c1565b7f8d2bda5d9f6ffb5796910376005392955773acee5548d0fcdb10e7c264ea00005f5b8281101561176657611689848483818110611664576116646140e9565b905060200281019061167691906140fd565b61168490604081019061411b565b6126d5565b83838281811061169b5761169b6140e9565b90506020028101906116ad91906140fd565b6116bb90604081019061411b565b835f8787868181106116cf576116cf6140e9565b90506020028101906116e191906140fd565b6116ef906020810190613da6565b63ffffffff1663ffffffff1681526020019081526020015f205f87878681811061171b5761171b6140e9565b905060200281019061172d91906140fd565b61173e90604081019060200161415d565b61ffff16815260208101919091526040015f209161175d9190836141ba565b50600101611647565b507fbe4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b6748383604051610e8e92919061429b565b63ffffffff84165f9081527f8d2bda5d9f6ffb5796910376005392955773acee5548d0fcdb10e7c264ea00006020818152604080842061ffff881685529091528220805460609391906117ea90614058565b80601f016020809104026020016040519081016040528092919081815260200182805461181690614058565b80156118615780601f1061183857610100808354040283529160200191611861565b820191905f5260205f20905b81548152906001019060200180831161184457829003601f168201915b5050505050905080515f036118b05784848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250929550611928945050505050565b5f8490036118c15791506119289050565b6002841061190b576118d385856126d5565b806118e1856002818961437a565b6040516020016118f3939291906143a1565b60405160208183030381529060405292505050611928565b8484604051639a6d49cd60e01b8152600401610d929291906143c7565b949350505050565b5f5b81811015611a3f573683838381811061194d5761194d6140e9565b905060200281019061195f91906143da565b905061199d6119716020830183613da6565b602083013563ffffffff919091165f9081525f805160206148ec83398151915260205260409020541490565b6119a75750611a37565b3063d045a0dc60c08301358360a08101356119c661010083018361411b565b6119d7610100890160e08a01613a1d565b6119e56101208a018a61411b565b6040518963ffffffff1660e01b8152600401611a0797969594939291906143ef565b5f604051808303818588803b158015611a1e575f80fd5b505af1158015611a30573d5f803e3d5ffd5b5050505050505b600101611932565b50336001600160a01b0316638e9e70996040518163ffffffff1660e01b81526004015f60405180830381865afa158015611a7b573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611aa29190810190614474565b604051638351eea760e01b8152600401610d929190613689565b5f610c3c82612716565b611ace613584565b604080518082019091525f80825260208201525f80611b0260408801356060890135611afd60208b018b613da6565b61274c565b915091505f80611b128984611ee0565b9092509050611b3e611b2760208b018b613da6565b8383611b38368d90038d018d6144dc565b8b612768565b60408051808201909152858152602080820186905282519298509096503391907f85496b760a4b7f8d66384b9df21b381f5d1b1e79f229a47aaf4c232edc2fe59a90611b8c908d018d613da6565b6040805163ffffffff909216825260208201899052810187905260600160405180910390a350505050935093915050565b611bc56122c1565b60405163ca5eb5e160e01b81526001600160a01b0382811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063ca5eb5e1906024015f604051808303815f87803b158015611c25575f80fd5b505af115801561115a573d5f803e3d5ffd5b834211611c5757604051632ce87eeb60e01b815260040160405180910390fd5b824210611c775760405163a899ef9360e01b815260040160405180910390fd5b611c81878361255f565b6113ba877f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a22675f1b89898989898960405160200161139e97969594939291906140ad565b333014611ce45760405163029a949d60e31b815260040160405180910390fd5b610e0287878787878787610df3565b611cfb6122c1565b7fefb041d771d6daaa55702fff6eb740d63ba559a75d2d1d3e151c78ff2480b60080546001600160a01b0319166001600160a01b03831690811782556040519081527fd48d879cef83a1c0bdda516f27b13ddb1b3f8bbac1c9e1511bb2a659c2427760906020016111d1565b610e0287878787868689604051602001611d839392919061408a565b6040516020818303038152906040526113cf565b6001600160a01b039182165f90815260666020908152604080832093909416825291909152205490565b611df389898989898988888b604051602001611ddf9392919061408a565b604051602081830303815290604052611c37565b505050505050505050565b611df389898989898988888b604051602001611e1c9392919061408a565b6040516020818303038152906040526112d7565b5f80611e3d858585612031565b915091505b935093915050565b611e526122c1565b6001600160a01b038116611eb75760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610d92565b611ec081612410565b50565b5f60208201803590611ed9906109cd9085613da6565b1492915050565b6060805f611f3b8560200135611ef58661206c565b611f0260a089018961411b565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061286e92505050565b90935090505f81611f4d576001611f50565b60025b9050611f70611f626020880188613da6565b82610a0a60808a018a61411b565b7f41db8a78b0206aba5c54bcbfc2bda0d84082a84eb88e680379a57b9e9f653c008054919450906001600160a01b03161561201757805460405163043a78eb60e01b81526001600160a01b039091169063043a78eb90611fd69088908890600401613665565b602060405180830381865afa158015611ff1573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612015919061450c565b505b5050509250929050565b61202c8383836128e8565b505050565b5f8061203c85612716565b915081905083811015611e42576040516371c4efed60e01b81526004810182905260248101859052604401610d92565b5f610c3c7f000000000000000000000000000000000000000000000000000000000000000083614527565b63ffffffff81165f9081525f805160206148ec8339815191526020819052604082205480610e295760405163f6ff4fb760e01b815263ffffffff85166004820152602401610d92565b5f6120f16120ee8787612a0b565b90565b90505f61211c8261210a6121058a8a612a22565b6126a1565b61211760208d018d613da6565b612a44565b905060288611156121dc575f61215861213b60608c0160408d01613cb9565b61214860208d018d613da6565b846121538c8c612a57565b612aa1565b604051633e5ac80960e11b81529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690637cb59012906121ad9086908d905f908790600401614546565b5f604051808303815f87803b1580156121c4575f80fd5b505af11580156121d6573d5f803e3d5ffd5b50505050505b6001600160a01b038216887fefed6d3500546b29533b128a29e3a94d70788727f0507505ac12eaf2e578fd9c61221560208d018d613da6565b6040805163ffffffff9092168252602082018690520160405180910390a3505050505050505050565b5f6122498484611d97565b90505f1981146122b057818110156122a35760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610d92565b6122b08484848403612021565b50505050565b61202c838383612ad3565b6033546001600160a01b031633146111ee5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610d92565b5f610ea4612c7c565b61232e8282612cef565b5050565b604080518082019091525f80825260208201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ddc28c586040518060a001604052808863ffffffff16815260200161239489612097565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b81526004016123c9929190614576565b6040805180830381865afa1580156123e3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612407919061461c565b95945050505050565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10280546060915f8051602061492c8339815191529161249f90614058565b80601f01602080910402602001604051908101604052809291908181526020018280546124cb90614058565b80156125165780601f106124ed57610100808354040283529160200191612516565b820191905f5260205f20905b8154815290600101906020018083116124f957829003601f168201915b505050505091505090565b7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10380546060915f8051602061492c8339815191529161249f90614058565b5f8051602061490c8339815191526001600160a01b0383165f90815260209182526040808220848352909252205460ff161561232e5760405163076f007560e21b815260040160405180910390fd5b6125c1836125bb84612d46565b83612d72565b15806125d457506001600160a01b038316155b1561202c57604051638baa579f60e01b815260040160405180910390fd5b6001600160a01b0382165f8181525f8051602061490c83398151915260209081526040808320858452909152808220805460ff19166001179055518392917f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a591a35050565b6001600160a01b0381165f9081527fb39b43abb0b115e0a59dece28477e279ee5f8e2fd55fbe200557c3ab864a030060208190526040909120805460018101909155905b50919050565b5f610c3c7f00000000000000000000000000000000000000000000000000000000000000006001600160401b038416614636565b5f6126e3600282848661437a565b6126ec9161464d565b60f01c90506003811461202c578282604051639a6d49cd60e01b8152600401610d929291906143c7565b5f7f00000000000000000000000000000000000000000000000000000000000000006127428184614527565b610c3c9190614636565b5f80612759858585612031565b9092509050611e423383612dc6565b612770613584565b5f61277d845f0151612ef8565b602085015190915015612797576127978460200151612f1f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632637a450826040518060a001604052808b63ffffffff1681526020016127e78c612097565b81526020018a81526020018981526020015f8960200151111515815250866040518463ffffffff1660e01b8152600401612822929190614576565b60806040518083038185885af115801561283e573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190612863919061467d565b979650505050505050565b80516060901515806128b75784846040516020016128a392919091825260c01b6001600160c01b031916602082015260280190565b6040516020818303038152906040526128de565b848433856040516020016128ce94939291906146e2565b6040516020818303038152906040525b9150935093915050565b6001600160a01b03831661294a5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610d92565b6001600160a01b0382166129ab5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610d92565b6001600160a01b038381165f8181526066602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b5f612a19602082848661437a565b610e2991614724565b5f612a3160286020848661437a565b612a3a91614741565b60c01c9392505050565b5f612a4f8484612ffe565b509092915050565b6060612a66826028818661437a565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250929695505050505050565b606084848484604051602001612aba949392919061476f565b6040516020818303038152906040529050949350505050565b6001600160a01b038316612b375760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610d92565b6001600160a01b038216612b995760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610d92565b6001600160a01b0383165f9081526065602052604090205481811015612c105760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610d92565b6001600160a01b038085165f8181526065602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90612c6f9086815260200190565b60405180910390a36122b0565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f612ca66130bd565b612cae613125565b60408051602081019490945283019190915260608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b5f8051602061492c8339815191527fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d102612d2884826147bd565b5060038101612d3783826147bd565b505f8082556001909101555050565b5f610c3c612d5261231b565b8360405161190160f01b8152600281019290925260228201526042902090565b5f805f612d7f8585613167565b90925090505f816004811115612d9757612d9761487c565b148015612db55750856001600160a01b0316826001600160a01b0316145b8061104a575061104a8686866131a6565b6001600160a01b038216612e265760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610d92565b6001600160a01b0382165f9081526065602052604090205481811015612e995760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610d92565b6001600160a01b0383165f8181526065602090815260408083208686039055606780548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b5f813414612f1b576040516304fb820960e51b8152346004820152602401610d92565b5090565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f7c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fa09190614890565b90506001600160a01b038116612fc9576040516329b99a9560e11b815260040160405180910390fd5b61232e6001600160a01b038216337f00000000000000000000000000000000000000000000000000000000000000008561328d565b6001600160a01b0382166130545760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610d92565b8060675f8282546130659190614045565b90915550506001600160a01b0382165f818152606560209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b5f5f8051602061492c833981519152816130d5612461565b8051909150156130ed57805160209091012092915050565b815480156130fc579392505050565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470935050505090565b5f5f8051602061492c8339815191528161313d612521565b80519091501561315557805160209091012092915050565b600182015480156130fc579392505050565b5f80825160410361319b576020830151604084015160608501515f1a61318f878285856132e7565b94509450505050610c22565b505f90506002610c22565b5f805f856001600160a01b0316631626ba7e60e01b86866040516024016131ce9291906148ab565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161320c91906148c3565b5f60405180830381855afa9150503d805f8114613244576040519150601f19603f3d011682016040523d82523d5f602084013e613249565b606091505b509150915081801561325d57506020815110155b801561104a57508051630b135d3f60e11b9061328290830160209081019084016148d4565b149695505050505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526122b09085906133a4565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561331c57505f9050600361339b565b604080515f8082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561336d573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b038116613395575f6001925092505061339b565b91505f90505b94509492505050565b5f6133f8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166134779092919063ffffffff16565b905080515f1480613418575080806020019051810190613418919061450c565b61202c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610d92565b606061192884845f85855f80866001600160a01b0316858760405161349c91906148c3565b5f6040518083038185875af1925050503d805f81146134d6576040519150601f19603f3d011682016040523d82523d5f602084013e6134db565b606091505b509150915061286387838387606083156135555782515f0361354e576001600160a01b0385163b61354e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d92565b5081611928565b611928838381511561356a5781518083602001fd5b8060405162461bcd60e51b8152600401610d929190613689565b60405180606001604052805f80191681526020015f6001600160401b031681526020016135c260405180604001604052805f81526020015f81525090565b905290565b5f60e0828403121561269b575f80fd5b5f80604083850312156135e8575f80fd5b82356001600160401b038111156135fd575f80fd5b613609858286016135c7565b95602094909401359450505050565b5f5b8381101561363257818101518382015260200161361a565b50505f910152565b5f8151808452613651816020860160208601613618565b601f01601f19169290920160200192915050565b604081525f613677604083018561363a565b8281036020840152612407818561363a565b602081525f610e29602083018461363a565b6001600160a01b0381168114611ec0575f80fd5b5f80604083850312156136c0575f80fd5b82356136cb8161369b565b946020939093013593505050565b5f602082840312156136e9575f80fd5b81356001600160401b038111156136fe575f80fd5b611928848285016135c7565b83518152602080850151908201525f60a08201604060a0604085015281865180845260c08601915060c08160051b870101935060208089015f5b838110156137835788870360bf190185528151805188528301518388018790526137708789018261363a565b9750509382019390820190600101613744565b50508751606088015250505060208501516080850152509050611928565b5f602082840312156137b1575f80fd5b5035919050565b5f6060828403121561269b575f80fd5b5f8083601f8401126137d8575f80fd5b5081356001600160401b038111156137ee575f80fd5b602083019150836020828501011115610c22575f80fd5b5f805f805f805f60e0888a03121561381b575f80fd5b61382589896137b8565b96506060880135955060808801356001600160401b0380821115613847575f80fd5b6138538b838c016137c8565b909750955060a08a013591506138688261369b565b90935060c0890135908082111561387d575f80fd5b5061388a8a828b016137c8565b989b979a50959850939692959293505050565b5f805f606084860312156138af575f80fd5b83356138ba8161369b565b925060208401356138ca8161369b565b929592945050506040919091013590565b803563ffffffff811681146138ee575f80fd5b919050565b5f8060408385031215613904575f80fd5b6136cb836138db565b8015158114611ec0575f80fd5b5f806040838503121561392b575f80fd5b82356001600160401b03811115613940575f80fd5b61394c858286016135c7565b925050602083013561395d8161390d565b809150509250929050565b815181526020808301519082015260408101610c3c565b803561ffff811681146138ee575f80fd5b5f80604083850312156139a1575f80fd5b6139aa836138db565b91506139b86020840161397f565b90509250929050565b803560ff811681146138ee575f80fd5b5f805f805f60a086880312156139e5575f80fd5b85356139f08161369b565b945060208601359350613a05604087016139c1565b94979396509394606081013594506080013592915050565b5f60208284031215613a2d575f80fd5b8135610e298161369b565b60ff60f81b881681525f602060e06020840152613a5860e084018a61363a565b8381036040850152613a6a818a61363a565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825260208088019350909101905f5b81811015613abd57835183529284019291840191600101613aa1565b50909c9b505050505050505050505050565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b0381118282101715613b0557613b05613acf565b60405290565b604051601f8201601f191681016001600160401b0381118282101715613b3357613b33613acf565b604052919050565b5f6001600160401b03821115613b5357613b53613acf565b50601f01601f191660200190565b5f82601f830112613b70575f80fd5b8135613b83613b7e82613b3b565b613b0b565b818152846020838601011115613b97575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f805f805f60e0888a031215613bc9575f80fd5b8735613bd48161369b565b96506020880135613be48161369b565b955060408801359450606088013593506080880135925060a0880135915060c08801356001600160401b03811115613c1a575f80fd5b613c268a828b01613b61565b91505092959891949750929550565b5f805f805f60a08688031215613c49575f80fd5b8535613c548161369b565b94506020860135613c648161369b565b9350604086013592506060860135915060808601356001600160401b03811115613c8c575f80fd5b613c9888828901613b61565b9150509295509295909350565b6001600160401b0381168114611ec0575f80fd5b5f60208284031215613cc9575f80fd5b8135610e2981613ca5565b5f805f60608486031215613ce6575f80fd5b8335613cf18161369b565b92506020840135915060408401356001600160401b03811115613d12575f80fd5b613d1e86828701613b61565b9150509250925092565b5f8083601f840112613d38575f80fd5b5081356001600160401b03811115613d4e575f80fd5b6020830191508360208260051b8501011115610c22575f80fd5b5f8060208385031215613d79575f80fd5b82356001600160401b03811115613d8e575f80fd5b613d9a85828601613d28565b90969095509350505050565b5f60208284031215613db6575f80fd5b610e29826138db565b5f805f8060608587031215613dd2575f80fd5b613ddb856138db565b9350613de96020860161397f565b925060408501356001600160401b03811115613e03575f80fd5b613e0f878288016137c8565b95989497509550505050565b5f805f8385036080811215613e2e575f80fd5b84356001600160401b03811115613e43575f80fd5b613e4f878288016135c7565b9450506040601f1982011215613e63575f80fd5b506020840191506060840135613e788161369b565b809150509250925092565b5f60c082019050835182526001600160401b0360208501511660208301526040840151613ebd604084018280518252602090810151910152565b5082516080830152602083015160a0830152610e29565b5f805f805f805f60e0888a031215613eea575f80fd5b8735613ef58161369b565b96506020880135613f058161369b565b95506040880135945060608801359350613f21608089016139c1565b925060a0880135915060c0880135905092959891949750929550565b5f8060408385031215613f4e575f80fd5b8235613f598161369b565b9150602083013561395d8161369b565b5f805f805f805f805f6101208a8c031215613f82575f80fd5b8935613f8d8161369b565b985060208a0135613f9d8161369b565b975060408a0135965060608a0135955060808a0135945060a08a01359350613fc760c08b016139c1565b925060e08a013591506101008a013590509295985092959850929598565b5f805f60608486031215613ff7575f80fd5b833592506020840135915061400e604085016138db565b90509250925092565b5f60608284031215614027575f80fd5b610e2983836137b8565b634e487b7160e01b5f52601160045260245ffd5b80820180821115610c3c57610c3c614031565b600181811c9082168061406c57607f821691505b60208210810361269b57634e487b7160e01b5f52602260045260245ffd5b928352602083019190915260f81b6001600160f81b031916604082015260410190565b9687526001600160a01b0395861660208801529390941660408601526060850191909152608084015260a083019190915260c082015260e00190565b634e487b7160e01b5f52603260045260245ffd5b5f8235605e19833603018112614111575f80fd5b9190910192915050565b5f808335601e19843603018112614130575f80fd5b8301803591506001600160401b03821115614149575f80fd5b602001915036819003821315610c22575f80fd5b5f6020828403121561416d575f80fd5b610e298261397f565b601f82111561202c57805f5260205f20601f840160051c8101602085101561419b5750805b601f840160051c820191505b8181101561115a575f81556001016141a7565b6001600160401b038311156141d1576141d1613acf565b6141e5836141df8354614058565b83614176565b5f601f841160018114614216575f85156141ff5750838201355b5f19600387901b1c1916600186901b17835561115a565b5f83815260208120601f198716915b828110156142455786850135825560209485019460019092019101614225565b5086821015614261575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60208082528181018390525f906040808401600586901b8501820187855b8881101561436c57878303603f190184528135368b9003605e190181126142de575f80fd5b8a01606063ffffffff6142f0836138db565b16855261ffff61430189840161397f565b168886015286820135601e1983360301811261431b575f80fd5b9091018781019190356001600160401b03811115614337575f80fd5b803603831315614345575f80fd5b81888701526143578287018285614273565b968901969550505091860191506001016142b9565b509098975050505050505050565b5f8085851115614388575f80fd5b83861115614394575f80fd5b5050820193919092039150565b5f84516143b2818460208901613618565b8201838582375f930192835250909392505050565b602081525f611928602083018486614273565b5f823561013e19833603018112614111575f80fd5b63ffffffff6143fd896138db565b168152602088013560208201525f604089013561441981613ca5565b6001600160401b03811660408401525087606083015260e0608083015261444460e083018789614273565b6001600160a01b03861660a084015282810360c0840152614466818587614273565b9a9950505050505050505050565b5f60208284031215614484575f80fd5b81516001600160401b03811115614499575f80fd5b8201601f810184136144a9575f80fd5b80516144b7613b7e82613b3b565b8181528560208385010111156144cb575f80fd5b612407826020830160208601613618565b5f604082840312156144ec575f80fd5b6144f4613ae3565b82358152602083013560208201528091505092915050565b5f6020828403121561451c575f80fd5b8151610e298161390d565b5f8261454157634e487b7160e01b5f52601260045260245ffd5b500490565b60018060a01b038516815283602082015261ffff83166040820152608060608201525f61104a608083018461363a565b6040815263ffffffff8351166040820152602083015160608201525f604084015160a060808401526145ab60e084018261363a565b90506060850151603f198483030160a08501526145c8828261363a565b60809690960151151560c08501525050506001600160a01b039190911660209091015290565b5f604082840312156145fe575f80fd5b614606613ae3565b9050815181526020820151602082015292915050565b5f6040828403121561462c575f80fd5b610e2983836145ee565b8082028115828204841417610c3c57610c3c614031565b6001600160f01b031981358181169160028510156146755780818660020360031b1b83161692505b505092915050565b5f6080828403121561468d575f80fd5b604051606081018181106001600160401b03821117156146af576146af613acf565b6040528251815260208301516146c481613ca5565b60208201526146d684604085016145ee565b60408201529392505050565b8481526001600160401b0360c01b8460c01b1660208201528260288201525f8251614714816048850160208701613618565b9190910160480195945050505050565b80356020831015610c3c575f19602084900360031b1b1692915050565b6001600160c01b031981358181169160088510156146755760089490940360031b84901b1690921692915050565b6001600160401b0360c01b8560c01b16815263ffffffff60e01b8460e01b16600882015282600c8201525f82516147ad81602c850160208701613618565b91909101602c0195945050505050565b81516001600160401b038111156147d6576147d6613acf565b6147ea816147e48454614058565b84614176565b602080601f83116001811461481d575f84156148065750858301515b5f19600386901b1c1916600185901b178555614874565b5f85815260208120601f198616915b8281101561484b5788860151825594840194600190910190840161482c565b508582101561486857878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b634e487b7160e01b5f52602160045260245ffd5b5f602082840312156148a0575f80fd5b8151610e298161369b565b828152604060208201525f611928604083018461363a565b5f8251614111818460208701613618565b5f602082840312156148e4575f80fd5b505191905056fe72ab1bc1039b79dc4724ffca13de82c96834302d3c7e0d4252232d4b2dd8f9006607eb842e76408d8b3956685dc6b9da5897a1d9b47edcc993ce266e603fa500a16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100a26469706673582212202cbc8a4f9fd16988bd0a9095653f95f32a504363376aae6eabeea052d198d2f464736f6c634300081600330000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b
Deployed Bytecode
0x6080604052600436106103a8575f3560e01c8063857749b0116101e9578063bd815db011610108578063dd62ed3e1161009d578063f01630231161006d578063f016302314610b9e578063f2fde38b14610bd2578063fc0c546a14610665578063ff7bd03d14610bf1575f80fd5b8063dd62ed3e14610af1578063e3ee160e14610b10578063e94a010214610b2f578063ef55bec614610b7f575f80fd5b8063cf092995116100d8578063cf09299514610a81578063d045a0dc14610aa0578063d424388514610ab3578063d505accf14610ad2575f80fd5b8063bd815db014610a0f578063c077998814610a22578063c7c7f5b314610a41578063ca5eb5e114610a62575f80fd5b8063a9059cbb1161017e578063b92d0eff1161014e578063b92d0eff14610665578063b98bd07014610994578063bb0b6a53146109b3578063bc70b354146109f0575f80fd5b8063a9059cbb14610923578063b3a5abeb14610942578063b731ea0a14610961578063b7b7289914610975575f80fd5b8063963efcaa116101b9578063963efcaa146108a05780639f68b964146108d35780639fd5a6cf146108e5578063a457c2d714610904575f80fd5b8063857749b01461082457806388b7ab63146108375780638da5cb5b1461085657806395d89b4114610873575f80fd5b80633644e515116102d55780635a0dfe4d1161026a578063715018a61161023a578063715018a6146107a95780637d25a05e146107bd5780637ecebe00146107de57806384b0196e146107fd575f80fd5b80635a0dfe4d146106e25780635e280f11146107235780636fc1b31e1461075657806370a0823114610775575f80fd5b806352ae2879116102a557806352ae28791461066557806354fd4d50146106775780635535d461146106a45780635a049a70146106c3575f80fd5b80633644e515146105f25780633714fffa14610606578063395093511461061a5780633b6f743b14610639575f80fd5b8063134d4f251161034b5780631f5e13341161031b5780631f5e13341461057f57806323b872dd14610593578063313ce567146105b25780633400288b146105d3575f80fd5b8063134d4f25146104f4578063156a0d0f1461051b57806317442b701461054157806318160ddd14610561575f80fd5b80630d35b415116103865780630d35b4151461044e5780630e78842c1461047c578063111ecdad146104b357806313137d65146104df575f80fd5b8063056d62de146103ac57806306fdde03146103e2578063095ea7b31461041f575b5f80fd5b3480156103b7575f80fd5b506103cb6103c63660046135d7565b610c10565b6040516103d9929190613665565b60405180910390f35b3480156103ed575f80fd5b5060408051808201909152600c81526b0aee4c2e0e0cac8408ce4c2f60a31b60208201525b6040516103d99190613689565b34801561042a575f80fd5b5061043e6104393660046136af565b610c29565b60405190151581526020016103d9565b348015610459575f80fd5b5061046d6104683660046136d9565b610c42565b6040516103d99392919061370a565b348015610487575f80fd5b5061049b6104963660046137a1565b610d0d565b6040516001600160401b0390911681526020016103d9565b3480156104be575f80fd5b506104c7610d17565b6040516001600160a01b0390911681526020016103d9565b6104f26104ed366004613805565b610d4b565b005b3480156104ff575f80fd5b50610508600281565b60405161ffff90911681526020016103d9565b348015610526575f80fd5b506040805162b9270b60e21b815260016020820152016103d9565b34801561054c575f80fd5b506040805160018082526020820152016103d9565b34801561056c575f80fd5b506067545b6040519081526020016103d9565b34801561058a575f80fd5b50610508600181565b34801561059e575f80fd5b5061043e6105ad36600461389d565b610e0b565b3480156105bd575f80fd5b5060125b60405160ff90911681526020016103d9565b3480156105de575f80fd5b506104f26105ed3660046138f3565b610e30565b3480156105fd575f80fd5b50610571610e9b565b348015610611575f80fd5b506104f2610ea9565b348015610625575f80fd5b5061043e6106343660046136af565b610fcf565b348015610644575f80fd5b5061065861065336600461391a565b610ff0565b6040516103d99190613968565b348015610670575f80fd5b50306104c7565b348015610682575f80fd5b506040805180820190915260058152640312e312e360dc1b6020820152610412565b3480156106af575f80fd5b506104126106be366004613990565b611054565b3480156106ce575f80fd5b506104f26106dd3660046139d1565b61112c565b3480156106ed575f80fd5b5061043e6106fc3660046138f3565b63ffffffff919091165f9081525f805160206148ec83398151915260205260409020541490565b34801561072e575f80fd5b506104c77f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b81565b348015610761575f80fd5b506104f2610770366004613a1d565b611161565b348015610780575f80fd5b5061057161078f366004613a1d565b6001600160a01b03165f9081526065602052604090205490565b3480156107b4575f80fd5b506104f26111dd565b3480156107c8575f80fd5b5061049b6107d73660046138f3565b5f92915050565b3480156107e9575f80fd5b506105716107f8366004613a1d565b6111f0565b348015610808575f80fd5b5061081161122e565b6040516103d99796959493929190613a38565b34801561082f575f80fd5b5060066105c1565b348015610842575f80fd5b506104f2610851366004613bb3565b6112d7565b348015610861575f80fd5b506033546001600160a01b03166104c7565b34801561087e575f80fd5b506040805180820190915260058152640ae8ca482b60db1b6020820152610412565b3480156108ab575f80fd5b506105717f000000000000000000000000000000000000000000000000000000e8d4a5100081565b3480156108de575f80fd5b505f61043e565b3480156108f0575f80fd5b506104f26108ff366004613c35565b6113cf565b34801561090f575f80fd5b5061043e61091e3660046136af565b611498565b34801561092e575f80fd5b5061043e61093d3660046136af565b61151d565b34801561094d575f80fd5b5061057161095c366004613cb9565b61152a565b34801561096c575f80fd5b506104c7611534565b348015610980575f80fd5b506104f261098f366004613cd4565b61155c565b34801561099f575f80fd5b506104f26109ae366004613d68565b61161c565b3480156109be575f80fd5b506105716109cd366004613da6565b63ffffffff165f9081525f805160206148ec833981519152602052604090205490565b3480156109fb575f80fd5b50610412610a0a366004613dbf565b611798565b6104f2610a1d366004613d68565b611930565b348015610a2d575f80fd5b50610571610a3c3660046137a1565b611abc565b610a54610a4f366004613e1b565b611ac6565b6040516103d9929190613e83565b348015610a6d575f80fd5b506104f2610a7c366004613a1d565b611bbd565b348015610a8c575f80fd5b506104f2610a9b366004613bb3565b611c37565b6104f2610aae366004613805565b611cc4565b348015610abe575f80fd5b506104f2610acd366004613a1d565b611cf3565b348015610add575f80fd5b506104f2610aec366004613ed4565b611d67565b348015610afc575f80fd5b50610571610b0b366004613f3d565b611d97565b348015610b1b575f80fd5b506104f2610b2a366004613f69565b611dc1565b348015610b3a575f80fd5b5061043e610b493660046136af565b6001600160a01b03919091165f9081525f8051602061490c83398151915260209081526040808320938352929052205460ff1690565b348015610b8a575f80fd5b506104f2610b99366004613f69565b611dfe565b348015610ba9575f80fd5b50610bbd610bb8366004613fe5565b611e30565b604080519283526020830191909152016103d9565b348015610bdd575f80fd5b506104f2610bec366004613a1d565b611e4a565b348015610bfc575f80fd5b5061043e610c0b366004614017565b611ec3565b606080610c1d8484611ee0565b915091505b9250929050565b5f33610c36818585612021565b60019150505b92915050565b604080518082019091525f80825260208201526060610c7260405180604001604052805f81526020015f81525090565b6040805180820182525f8082526001600160401b03602080840182905284518381529081019094529195509182610ccb565b604080518082019091525f815260606020820152815260200190600190039081610ca45790505b5093505f80610cef604089013560608a0135610cea60208c018c613da6565b612031565b60408051808201909152918252602082015296989597505050505050565b5f610c3c8261206c565b5f807f41db8a78b0206aba5c54bcbfc2bda0d84082a84eb88e680379a57b9e9f653c005b546001600160a01b031692915050565b7f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b6001600160a01b03163314610d9b576040516391ac5e4f60e01b81523360048201526024015b60405180910390fd5b60208701803590610db590610db0908a613da6565b612097565b14610df357610dc76020880188613da6565b60405163309afaf360e21b815263ffffffff909116600482015260208801356024820152604401610d92565b610e02878787878787876120e0565b50505050505050565b5f33610e1885828561223e565b610e238585856122b6565b60019150505b9392505050565b610e386122c1565b63ffffffff82165f8181525f805160206148ec833981519152602081815260409283902085905582519384528301849052917f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b91015b60405180910390a1505050565b5f610ea461231b565b905090565b5f54600390610100900460ff16158015610ec957505f5460ff8083169116105b610f2c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610d92565b5f805461ffff191660ff831617610100179055610f8c610f6b60408051808201909152600c81526b0aee4c2e0e0cac8408ce4c2f60a31b602082015290565b6040805180820190915260058152640312e312e360dc1b6020820152612324565b5f805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b5f33610c36818585610fe18383611d97565b610feb9190614045565b612021565b604080518082019091525f80825260208201525f61101e60408501356060860135610cea6020880188613da6565b9150505f8061102d8684611ee0565b909250905061104a6110426020880188613da6565b838388612332565b9695505050505050565b63ffffffff82165f9081527f8d2bda5d9f6ffb5796910376005392955773acee5548d0fcdb10e7c264ea00006020818152604080842061ffff86168552909152909120805460609291906110a790614058565b80601f01602080910402602001604051908101604052809291908181526020018280546110d390614058565b801561111e5780601f106110f55761010080835404028352916020019161111e565b820191905f5260205f20905b81548152906001019060200180831161110157829003601f168201915b505050505091505092915050565b61115a85858484876040516020016111469392919061408a565b60405160208183030381529060405261155c565b5050505050565b6111696122c1565b7f41db8a78b0206aba5c54bcbfc2bda0d84082a84eb88e680379a57b9e9f653c0080546001600160a01b0319166001600160a01b03831690811782556040519081527ff0be4f1e87349231d80c36b33f9e8639658eeaf474014dee15a3e6a4d4414197906020015b60405180910390a15050565b6111e56122c1565b6111ee5f612410565b565b6001600160a01b0381165f9081527fb39b43abb0b115e0a59dece28477e279ee5f8e2fd55fbe200557c3ab864a030060208190526040822054610e29565b5f60608082808083815f8051602061492c833981519152805490915015801561125957506001810154155b61129d5760405162461bcd60e51b81526020600482015260156024820152741152540dcc4c8e88155b9a5b9a5d1a585b1a5e9959605a1b6044820152606401610d92565b6112a5612461565b6112ad612521565b604080515f80825260208201909252600f60f81b9c939b5091995046985030975095509350915050565b6001600160a01b038616331461131157604051637f54a22160e11b81523360048201526001600160a01b0387166024820152604401610d92565b83421161133157604051632ce87eeb60e01b815260040160405180910390fd5b8242106113515760405163a899ef9360e01b815260040160405180910390fd5b61135b878361255f565b6113ba877fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de85f1b89898989898960405160200161139e97969594939291906140ad565b60405160208183030381529060405280519060200120836125ae565b6113c487836125f2565b610e028787876122b6565b8142111561141f5760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610d92565b61148d857f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98787876114508b612657565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810185905260e00161139e565b61115a858585612021565b5f33816114a58286611d97565b9050838110156115055760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610d92565b6115128286868403612021565b506001949350505050565b5f33610c368185856122b6565b5f610c3c826126a1565b5f807fefb041d771d6daaa55702fff6eb740d63ba559a75d2d1d3e151c78ff2480b600610d3b565b611566838361255f565b604080517f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a159742960208201526001600160a01b03851691810191909152606081018390526115b690849060800161139e565b6001600160a01b0383165f8181525f8051602061490c83398151915260209081526040808320868452909152808220805460ff19166001179055518492917f1cdd46ff242716cdaa72d159d339a485b3438398348d68f09d7c8c0a59353d8191a3505050565b6116246122c1565b7f8d2bda5d9f6ffb5796910376005392955773acee5548d0fcdb10e7c264ea00005f5b8281101561176657611689848483818110611664576116646140e9565b905060200281019061167691906140fd565b61168490604081019061411b565b6126d5565b83838281811061169b5761169b6140e9565b90506020028101906116ad91906140fd565b6116bb90604081019061411b565b835f8787868181106116cf576116cf6140e9565b90506020028101906116e191906140fd565b6116ef906020810190613da6565b63ffffffff1663ffffffff1681526020019081526020015f205f87878681811061171b5761171b6140e9565b905060200281019061172d91906140fd565b61173e90604081019060200161415d565b61ffff16815260208101919091526040015f209161175d9190836141ba565b50600101611647565b507fbe4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b6748383604051610e8e92919061429b565b63ffffffff84165f9081527f8d2bda5d9f6ffb5796910376005392955773acee5548d0fcdb10e7c264ea00006020818152604080842061ffff881685529091528220805460609391906117ea90614058565b80601f016020809104026020016040519081016040528092919081815260200182805461181690614058565b80156118615780601f1061183857610100808354040283529160200191611861565b820191905f5260205f20905b81548152906001019060200180831161184457829003601f168201915b5050505050905080515f036118b05784848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250929550611928945050505050565b5f8490036118c15791506119289050565b6002841061190b576118d385856126d5565b806118e1856002818961437a565b6040516020016118f3939291906143a1565b60405160208183030381529060405292505050611928565b8484604051639a6d49cd60e01b8152600401610d929291906143c7565b949350505050565b5f5b81811015611a3f573683838381811061194d5761194d6140e9565b905060200281019061195f91906143da565b905061199d6119716020830183613da6565b602083013563ffffffff919091165f9081525f805160206148ec83398151915260205260409020541490565b6119a75750611a37565b3063d045a0dc60c08301358360a08101356119c661010083018361411b565b6119d7610100890160e08a01613a1d565b6119e56101208a018a61411b565b6040518963ffffffff1660e01b8152600401611a0797969594939291906143ef565b5f604051808303818588803b158015611a1e575f80fd5b505af1158015611a30573d5f803e3d5ffd5b5050505050505b600101611932565b50336001600160a01b0316638e9e70996040518163ffffffff1660e01b81526004015f60405180830381865afa158015611a7b573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611aa29190810190614474565b604051638351eea760e01b8152600401610d929190613689565b5f610c3c82612716565b611ace613584565b604080518082019091525f80825260208201525f80611b0260408801356060890135611afd60208b018b613da6565b61274c565b915091505f80611b128984611ee0565b9092509050611b3e611b2760208b018b613da6565b8383611b38368d90038d018d6144dc565b8b612768565b60408051808201909152858152602080820186905282519298509096503391907f85496b760a4b7f8d66384b9df21b381f5d1b1e79f229a47aaf4c232edc2fe59a90611b8c908d018d613da6565b6040805163ffffffff909216825260208201899052810187905260600160405180910390a350505050935093915050565b611bc56122c1565b60405163ca5eb5e160e01b81526001600160a01b0382811660048301527f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b169063ca5eb5e1906024015f604051808303815f87803b158015611c25575f80fd5b505af115801561115a573d5f803e3d5ffd5b834211611c5757604051632ce87eeb60e01b815260040160405180910390fd5b824210611c775760405163a899ef9360e01b815260040160405180910390fd5b611c81878361255f565b6113ba877f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a22675f1b89898989898960405160200161139e97969594939291906140ad565b333014611ce45760405163029a949d60e31b815260040160405180910390fd5b610e0287878787878787610df3565b611cfb6122c1565b7fefb041d771d6daaa55702fff6eb740d63ba559a75d2d1d3e151c78ff2480b60080546001600160a01b0319166001600160a01b03831690811782556040519081527fd48d879cef83a1c0bdda516f27b13ddb1b3f8bbac1c9e1511bb2a659c2427760906020016111d1565b610e0287878787868689604051602001611d839392919061408a565b6040516020818303038152906040526113cf565b6001600160a01b039182165f90815260666020908152604080832093909416825291909152205490565b611df389898989898988888b604051602001611ddf9392919061408a565b604051602081830303815290604052611c37565b505050505050505050565b611df389898989898988888b604051602001611e1c9392919061408a565b6040516020818303038152906040526112d7565b5f80611e3d858585612031565b915091505b935093915050565b611e526122c1565b6001600160a01b038116611eb75760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610d92565b611ec081612410565b50565b5f60208201803590611ed9906109cd9085613da6565b1492915050565b6060805f611f3b8560200135611ef58661206c565b611f0260a089018961411b565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061286e92505050565b90935090505f81611f4d576001611f50565b60025b9050611f70611f626020880188613da6565b82610a0a60808a018a61411b565b7f41db8a78b0206aba5c54bcbfc2bda0d84082a84eb88e680379a57b9e9f653c008054919450906001600160a01b03161561201757805460405163043a78eb60e01b81526001600160a01b039091169063043a78eb90611fd69088908890600401613665565b602060405180830381865afa158015611ff1573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612015919061450c565b505b5050509250929050565b61202c8383836128e8565b505050565b5f8061203c85612716565b915081905083811015611e42576040516371c4efed60e01b81526004810182905260248101859052604401610d92565b5f610c3c7f000000000000000000000000000000000000000000000000000000e8d4a5100083614527565b63ffffffff81165f9081525f805160206148ec8339815191526020819052604082205480610e295760405163f6ff4fb760e01b815263ffffffff85166004820152602401610d92565b5f6120f16120ee8787612a0b565b90565b90505f61211c8261210a6121058a8a612a22565b6126a1565b61211760208d018d613da6565b612a44565b905060288611156121dc575f61215861213b60608c0160408d01613cb9565b61214860208d018d613da6565b846121538c8c612a57565b612aa1565b604051633e5ac80960e11b81529091506001600160a01b037f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b1690637cb59012906121ad9086908d905f908790600401614546565b5f604051808303815f87803b1580156121c4575f80fd5b505af11580156121d6573d5f803e3d5ffd5b50505050505b6001600160a01b038216887fefed6d3500546b29533b128a29e3a94d70788727f0507505ac12eaf2e578fd9c61221560208d018d613da6565b6040805163ffffffff9092168252602082018690520160405180910390a3505050505050505050565b5f6122498484611d97565b90505f1981146122b057818110156122a35760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610d92565b6122b08484848403612021565b50505050565b61202c838383612ad3565b6033546001600160a01b031633146111ee5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610d92565b5f610ea4612c7c565b61232e8282612cef565b5050565b604080518082019091525f80825260208201527f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b6001600160a01b031663ddc28c586040518060a001604052808863ffffffff16815260200161239489612097565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b81526004016123c9929190614576565b6040805180830381865afa1580156123e3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612407919061461c565b95945050505050565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10280546060915f8051602061492c8339815191529161249f90614058565b80601f01602080910402602001604051908101604052809291908181526020018280546124cb90614058565b80156125165780601f106124ed57610100808354040283529160200191612516565b820191905f5260205f20905b8154815290600101906020018083116124f957829003601f168201915b505050505091505090565b7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10380546060915f8051602061492c8339815191529161249f90614058565b5f8051602061490c8339815191526001600160a01b0383165f90815260209182526040808220848352909252205460ff161561232e5760405163076f007560e21b815260040160405180910390fd5b6125c1836125bb84612d46565b83612d72565b15806125d457506001600160a01b038316155b1561202c57604051638baa579f60e01b815260040160405180910390fd5b6001600160a01b0382165f8181525f8051602061490c83398151915260209081526040808320858452909152808220805460ff19166001179055518392917f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a591a35050565b6001600160a01b0381165f9081527fb39b43abb0b115e0a59dece28477e279ee5f8e2fd55fbe200557c3ab864a030060208190526040909120805460018101909155905b50919050565b5f610c3c7f000000000000000000000000000000000000000000000000000000e8d4a510006001600160401b038416614636565b5f6126e3600282848661437a565b6126ec9161464d565b60f01c90506003811461202c578282604051639a6d49cd60e01b8152600401610d929291906143c7565b5f7f000000000000000000000000000000000000000000000000000000e8d4a510006127428184614527565b610c3c9190614636565b5f80612759858585612031565b9092509050611e423383612dc6565b612770613584565b5f61277d845f0151612ef8565b602085015190915015612797576127978460200151612f1f565b7f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b6001600160a01b0316632637a450826040518060a001604052808b63ffffffff1681526020016127e78c612097565b81526020018a81526020018981526020015f8960200151111515815250866040518463ffffffff1660e01b8152600401612822929190614576565b60806040518083038185885af115801561283e573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190612863919061467d565b979650505050505050565b80516060901515806128b75784846040516020016128a392919091825260c01b6001600160c01b031916602082015260280190565b6040516020818303038152906040526128de565b848433856040516020016128ce94939291906146e2565b6040516020818303038152906040525b9150935093915050565b6001600160a01b03831661294a5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610d92565b6001600160a01b0382166129ab5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610d92565b6001600160a01b038381165f8181526066602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b5f612a19602082848661437a565b610e2991614724565b5f612a3160286020848661437a565b612a3a91614741565b60c01c9392505050565b5f612a4f8484612ffe565b509092915050565b6060612a66826028818661437a565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250929695505050505050565b606084848484604051602001612aba949392919061476f565b6040516020818303038152906040529050949350505050565b6001600160a01b038316612b375760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610d92565b6001600160a01b038216612b995760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610d92565b6001600160a01b0383165f9081526065602052604090205481811015612c105760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610d92565b6001600160a01b038085165f8181526065602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90612c6f9086815260200190565b60405180910390a36122b0565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f612ca66130bd565b612cae613125565b60408051602081019490945283019190915260608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b5f8051602061492c8339815191527fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d102612d2884826147bd565b5060038101612d3783826147bd565b505f8082556001909101555050565b5f610c3c612d5261231b565b8360405161190160f01b8152600281019290925260228201526042902090565b5f805f612d7f8585613167565b90925090505f816004811115612d9757612d9761487c565b148015612db55750856001600160a01b0316826001600160a01b0316145b8061104a575061104a8686866131a6565b6001600160a01b038216612e265760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610d92565b6001600160a01b0382165f9081526065602052604090205481811015612e995760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610d92565b6001600160a01b0383165f8181526065602090815260408083208686039055606780548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b5f813414612f1b576040516304fb820960e51b8152346004820152602401610d92565b5090565b5f7f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b6001600160a01b031663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f7c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fa09190614890565b90506001600160a01b038116612fc9576040516329b99a9560e11b815260040160405180910390fd5b61232e6001600160a01b038216337f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b8561328d565b6001600160a01b0382166130545760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610d92565b8060675f8282546130659190614045565b90915550506001600160a01b0382165f818152606560209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b5f5f8051602061492c833981519152816130d5612461565b8051909150156130ed57805160209091012092915050565b815480156130fc579392505050565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470935050505090565b5f5f8051602061492c8339815191528161313d612521565b80519091501561315557805160209091012092915050565b600182015480156130fc579392505050565b5f80825160410361319b576020830151604084015160608501515f1a61318f878285856132e7565b94509450505050610c22565b505f90506002610c22565b5f805f856001600160a01b0316631626ba7e60e01b86866040516024016131ce9291906148ab565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161320c91906148c3565b5f60405180830381855afa9150503d805f8114613244576040519150601f19603f3d011682016040523d82523d5f602084013e613249565b606091505b509150915081801561325d57506020815110155b801561104a57508051630b135d3f60e11b9061328290830160209081019084016148d4565b149695505050505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526122b09085906133a4565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561331c57505f9050600361339b565b604080515f8082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561336d573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b038116613395575f6001925092505061339b565b91505f90505b94509492505050565b5f6133f8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166134779092919063ffffffff16565b905080515f1480613418575080806020019051810190613418919061450c565b61202c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610d92565b606061192884845f85855f80866001600160a01b0316858760405161349c91906148c3565b5f6040518083038185875af1925050503d805f81146134d6576040519150601f19603f3d011682016040523d82523d5f602084013e6134db565b606091505b509150915061286387838387606083156135555782515f0361354e576001600160a01b0385163b61354e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d92565b5081611928565b611928838381511561356a5781518083602001fd5b8060405162461bcd60e51b8152600401610d929190613689565b60405180606001604052805f80191681526020015f6001600160401b031681526020016135c260405180604001604052805f81526020015f81525090565b905290565b5f60e0828403121561269b575f80fd5b5f80604083850312156135e8575f80fd5b82356001600160401b038111156135fd575f80fd5b613609858286016135c7565b95602094909401359450505050565b5f5b8381101561363257818101518382015260200161361a565b50505f910152565b5f8151808452613651816020860160208601613618565b601f01601f19169290920160200192915050565b604081525f613677604083018561363a565b8281036020840152612407818561363a565b602081525f610e29602083018461363a565b6001600160a01b0381168114611ec0575f80fd5b5f80604083850312156136c0575f80fd5b82356136cb8161369b565b946020939093013593505050565b5f602082840312156136e9575f80fd5b81356001600160401b038111156136fe575f80fd5b611928848285016135c7565b83518152602080850151908201525f60a08201604060a0604085015281865180845260c08601915060c08160051b870101935060208089015f5b838110156137835788870360bf190185528151805188528301518388018790526137708789018261363a565b9750509382019390820190600101613744565b50508751606088015250505060208501516080850152509050611928565b5f602082840312156137b1575f80fd5b5035919050565b5f6060828403121561269b575f80fd5b5f8083601f8401126137d8575f80fd5b5081356001600160401b038111156137ee575f80fd5b602083019150836020828501011115610c22575f80fd5b5f805f805f805f60e0888a03121561381b575f80fd5b61382589896137b8565b96506060880135955060808801356001600160401b0380821115613847575f80fd5b6138538b838c016137c8565b909750955060a08a013591506138688261369b565b90935060c0890135908082111561387d575f80fd5b5061388a8a828b016137c8565b989b979a50959850939692959293505050565b5f805f606084860312156138af575f80fd5b83356138ba8161369b565b925060208401356138ca8161369b565b929592945050506040919091013590565b803563ffffffff811681146138ee575f80fd5b919050565b5f8060408385031215613904575f80fd5b6136cb836138db565b8015158114611ec0575f80fd5b5f806040838503121561392b575f80fd5b82356001600160401b03811115613940575f80fd5b61394c858286016135c7565b925050602083013561395d8161390d565b809150509250929050565b815181526020808301519082015260408101610c3c565b803561ffff811681146138ee575f80fd5b5f80604083850312156139a1575f80fd5b6139aa836138db565b91506139b86020840161397f565b90509250929050565b803560ff811681146138ee575f80fd5b5f805f805f60a086880312156139e5575f80fd5b85356139f08161369b565b945060208601359350613a05604087016139c1565b94979396509394606081013594506080013592915050565b5f60208284031215613a2d575f80fd5b8135610e298161369b565b60ff60f81b881681525f602060e06020840152613a5860e084018a61363a565b8381036040850152613a6a818a61363a565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825260208088019350909101905f5b81811015613abd57835183529284019291840191600101613aa1565b50909c9b505050505050505050505050565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b0381118282101715613b0557613b05613acf565b60405290565b604051601f8201601f191681016001600160401b0381118282101715613b3357613b33613acf565b604052919050565b5f6001600160401b03821115613b5357613b53613acf565b50601f01601f191660200190565b5f82601f830112613b70575f80fd5b8135613b83613b7e82613b3b565b613b0b565b818152846020838601011115613b97575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f805f805f60e0888a031215613bc9575f80fd5b8735613bd48161369b565b96506020880135613be48161369b565b955060408801359450606088013593506080880135925060a0880135915060c08801356001600160401b03811115613c1a575f80fd5b613c268a828b01613b61565b91505092959891949750929550565b5f805f805f60a08688031215613c49575f80fd5b8535613c548161369b565b94506020860135613c648161369b565b9350604086013592506060860135915060808601356001600160401b03811115613c8c575f80fd5b613c9888828901613b61565b9150509295509295909350565b6001600160401b0381168114611ec0575f80fd5b5f60208284031215613cc9575f80fd5b8135610e2981613ca5565b5f805f60608486031215613ce6575f80fd5b8335613cf18161369b565b92506020840135915060408401356001600160401b03811115613d12575f80fd5b613d1e86828701613b61565b9150509250925092565b5f8083601f840112613d38575f80fd5b5081356001600160401b03811115613d4e575f80fd5b6020830191508360208260051b8501011115610c22575f80fd5b5f8060208385031215613d79575f80fd5b82356001600160401b03811115613d8e575f80fd5b613d9a85828601613d28565b90969095509350505050565b5f60208284031215613db6575f80fd5b610e29826138db565b5f805f8060608587031215613dd2575f80fd5b613ddb856138db565b9350613de96020860161397f565b925060408501356001600160401b03811115613e03575f80fd5b613e0f878288016137c8565b95989497509550505050565b5f805f8385036080811215613e2e575f80fd5b84356001600160401b03811115613e43575f80fd5b613e4f878288016135c7565b9450506040601f1982011215613e63575f80fd5b506020840191506060840135613e788161369b565b809150509250925092565b5f60c082019050835182526001600160401b0360208501511660208301526040840151613ebd604084018280518252602090810151910152565b5082516080830152602083015160a0830152610e29565b5f805f805f805f60e0888a031215613eea575f80fd5b8735613ef58161369b565b96506020880135613f058161369b565b95506040880135945060608801359350613f21608089016139c1565b925060a0880135915060c0880135905092959891949750929550565b5f8060408385031215613f4e575f80fd5b8235613f598161369b565b9150602083013561395d8161369b565b5f805f805f805f805f6101208a8c031215613f82575f80fd5b8935613f8d8161369b565b985060208a0135613f9d8161369b565b975060408a0135965060608a0135955060808a0135945060a08a01359350613fc760c08b016139c1565b925060e08a013591506101008a013590509295985092959850929598565b5f805f60608486031215613ff7575f80fd5b833592506020840135915061400e604085016138db565b90509250925092565b5f60608284031215614027575f80fd5b610e2983836137b8565b634e487b7160e01b5f52601160045260245ffd5b80820180821115610c3c57610c3c614031565b600181811c9082168061406c57607f821691505b60208210810361269b57634e487b7160e01b5f52602260045260245ffd5b928352602083019190915260f81b6001600160f81b031916604082015260410190565b9687526001600160a01b0395861660208801529390941660408601526060850191909152608084015260a083019190915260c082015260e00190565b634e487b7160e01b5f52603260045260245ffd5b5f8235605e19833603018112614111575f80fd5b9190910192915050565b5f808335601e19843603018112614130575f80fd5b8301803591506001600160401b03821115614149575f80fd5b602001915036819003821315610c22575f80fd5b5f6020828403121561416d575f80fd5b610e298261397f565b601f82111561202c57805f5260205f20601f840160051c8101602085101561419b5750805b601f840160051c820191505b8181101561115a575f81556001016141a7565b6001600160401b038311156141d1576141d1613acf565b6141e5836141df8354614058565b83614176565b5f601f841160018114614216575f85156141ff5750838201355b5f19600387901b1c1916600186901b17835561115a565b5f83815260208120601f198716915b828110156142455786850135825560209485019460019092019101614225565b5086821015614261575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60208082528181018390525f906040808401600586901b8501820187855b8881101561436c57878303603f190184528135368b9003605e190181126142de575f80fd5b8a01606063ffffffff6142f0836138db565b16855261ffff61430189840161397f565b168886015286820135601e1983360301811261431b575f80fd5b9091018781019190356001600160401b03811115614337575f80fd5b803603831315614345575f80fd5b81888701526143578287018285614273565b968901969550505091860191506001016142b9565b509098975050505050505050565b5f8085851115614388575f80fd5b83861115614394575f80fd5b5050820193919092039150565b5f84516143b2818460208901613618565b8201838582375f930192835250909392505050565b602081525f611928602083018486614273565b5f823561013e19833603018112614111575f80fd5b63ffffffff6143fd896138db565b168152602088013560208201525f604089013561441981613ca5565b6001600160401b03811660408401525087606083015260e0608083015261444460e083018789614273565b6001600160a01b03861660a084015282810360c0840152614466818587614273565b9a9950505050505050505050565b5f60208284031215614484575f80fd5b81516001600160401b03811115614499575f80fd5b8201601f810184136144a9575f80fd5b80516144b7613b7e82613b3b565b8181528560208385010111156144cb575f80fd5b612407826020830160208601613618565b5f604082840312156144ec575f80fd5b6144f4613ae3565b82358152602083013560208201528091505092915050565b5f6020828403121561451c575f80fd5b8151610e298161390d565b5f8261454157634e487b7160e01b5f52601260045260245ffd5b500490565b60018060a01b038516815283602082015261ffff83166040820152608060608201525f61104a608083018461363a565b6040815263ffffffff8351166040820152602083015160608201525f604084015160a060808401526145ab60e084018261363a565b90506060850151603f198483030160a08501526145c8828261363a565b60809690960151151560c08501525050506001600160a01b039190911660209091015290565b5f604082840312156145fe575f80fd5b614606613ae3565b9050815181526020820151602082015292915050565b5f6040828403121561462c575f80fd5b610e2983836145ee565b8082028115828204841417610c3c57610c3c614031565b6001600160f01b031981358181169160028510156146755780818660020360031b1b83161692505b505092915050565b5f6080828403121561468d575f80fd5b604051606081018181106001600160401b03821117156146af576146af613acf565b6040528251815260208301516146c481613ca5565b60208201526146d684604085016145ee565b60408201529392505050565b8481526001600160401b0360c01b8460c01b1660208201528260288201525f8251614714816048850160208701613618565b9190910160480195945050505050565b80356020831015610c3c575f19602084900360031b1b1692915050565b6001600160c01b031981358181169160088510156146755760089490940360031b84901b1690921692915050565b6001600160401b0360c01b8560c01b16815263ffffffff60e01b8460e01b16600882015282600c8201525f82516147ad81602c850160208701613618565b91909101602c0195945050505050565b81516001600160401b038111156147d6576147d6613acf565b6147ea816147e48454614058565b84614176565b602080601f83116001811461481d575f84156148065750858301515b5f19600386901b1c1916600185901b178555614874565b5f85815260208120601f198616915b8281101561484b5788860151825594840194600190910190840161482c565b508582101561486857878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b634e487b7160e01b5f52602160045260245ffd5b5f602082840312156148a0575f80fd5b8151610e298161369b565b828152604060208201525f611928604083018461363a565b5f8251614111818460208701613618565b5f602082840312156148e4575f80fd5b505191905056fe72ab1bc1039b79dc4724ffca13de82c96834302d3c7e0d4252232d4b2dd8f9006607eb842e76408d8b3956685dc6b9da5897a1d9b47edcc993ce266e603fa500a16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100a26469706673582212202cbc8a4f9fd16988bd0a9095653f95f32a504363376aae6eabeea052d198d2f464736f6c63430008160033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b
-----Decoded View---------------
Arg [0] : _lzEndpoint (address): 0x6F475642a6e85809B1c36Fa62763669b1b48DD5B
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b
Deployed Bytecode Sourcemap
239516:2261:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;240893:238;;;;;;;;;;-1:-1:-1;240893:238:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;240001:101;;;;;;;;;;-1:-1:-1;240073:21:0;;;;;;;;;;;;-1:-1:-1;;;240073:21:0;;;;240001:101;;;;;;;:::i;139421:201::-;;;;;;;;;;-1:-1:-1;139421:201:0;;;;;:::i;:::-;;:::i;:::-;;;2367:14:1;;2360:22;2342:41;;2330:2;2315:18;139421:201:0;2202:187:1;220716:1283:0;;;;;;;;;;-1:-1:-1;220716:1283:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;240360:115::-;;;;;;;;;;-1:-1:-1;240360:115:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;4600:31:1;;;4582:50;;4570:2;4555:18;240360:115:0;4438:200:1;218958:152:0;;;;;;;;;;;;;:::i;:::-;;;-1:-1:-1;;;;;4807:32:1;;;4789:51;;4777:2;4762:18;218958:152:0;4643:203:1;190775:723:0;;;;;;:::i;:::-;;:::i;:::-;;217632:40;;;;;;;;;;;;217671:1;217632:40;;;;;6589:6:1;6577:19;;;6559:38;;6547:2;6532:18;217632:40:0;6415:188:1;236884:142:0;;;;;;;;;;-1:-1:-1;236884:142:0;;;-1:-1:-1;;;6778:52:1;;237016:1:0;6861:2:1;6846:18;;6839:59;6751:18;236884:142:0;6608:296:1;215350:265:0;;;;;;;;;;-1:-1:-1;215350:265:0;;;195611:1;7116:34:1;;;7181:2;7166:18;;7159:43;7052:18;215350:265:0;6909:299:1;138190:108:0;;;;;;;;;;-1:-1:-1;138278:12:0;;138190:108;;;7359:25:1;;;7347:2;7332:18;138190:108:0;7213:177:1;217594:31:0;;;;;;;;;;;;217624:1;217594:31;;140202:261;;;;;;;;;;-1:-1:-1;140202:261:0;;;;;:::i;:::-;;:::i;138032:93::-;;;;;;;;;;-1:-1:-1;138115:2:0;138032:93;;;8028:4:1;8016:17;;;7998:36;;7986:2;7971:18;138032:93:0;7856:184:1;166274:206:0;;;;;;;;;;-1:-1:-1;166274:206:0;;;;;:::i;:::-;;:::i;194314:106::-;;;;;;;;;;;;;:::i;239890:103::-;;;;;;;;;;;;;:::i;140872:238::-;;;;;;;;;;-1:-1:-1;140872:238:0;;;;;:::i;:::-;;:::i;222462:787::-;;;;;;;;;;-1:-1:-1;222462:787:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;208979:95::-;;;;;;;;;;-1:-1:-1;209061:4:0;208979:95;;239714:88;;;;;;;;;;-1:-1:-1;239780:14:0;;;;;;;;;;;;-1:-1:-1;;;239780:14:0;;;;239714:88;;152076:225;;;;;;;;;;-1:-1:-1;152076:225:0;;;;;:::i;:::-;;:::i;181279:222::-;;;;;;;;;;-1:-1:-1;181279:222:0;;;;;:::i;:::-;;:::i;230818:134::-;;;;;;;;;;-1:-1:-1;230818:134:0;;;;;:::i;:::-;165718:13;;;;;230900:4;165718:13;;;-1:-1:-1;;;;;;;;;;;165718:13:0;;;;;;230924:20;;230818:134;164234:46;;;;;;;;;;;;;;;220175:226;;;;;;;;;;-1:-1:-1;220175:226:0;;;;;:::i;:::-;;:::i;138361:127::-;;;;;;;;;;-1:-1:-1;138361:127:0;;;;;:::i;:::-;-1:-1:-1;;;;;138462:18:0;138435:7;138462:18;;;:9;:18;;;;;;;138361:127;115159:103;;;;;;;;;;;;;:::i;189897:130::-;;;;;;;;;;-1:-1:-1;189897:130:0;;;;;:::i;:::-;189986:12;189897:130;;;;;194118:188;;;;;;;;;;-1:-1:-1;194118:188:0;;;;;:::i;:::-;;:::i;131039:931::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;219729:89::-;;;;;;;;;;-1:-1:-1;219809:1:0;219729:89;;179737:1105;;;;;;;;;;-1:-1:-1;179737:1105:0;;;;;:::i;:::-;;:::i;114518:87::-;;;;;;;;;;-1:-1:-1;114591:6:0;;-1:-1:-1;;;;;114591:6:0;114518:87;;240110:96;;;;;;;;;;-1:-1:-1;240184:14:0;;;;;;;;;;;;-1:-1:-1;;;240184:14:0;;;;240110:96;;217283:46;;;;;;;;;;;;;;;237657:96;;;;;;;;;;-1:-1:-1;237716:4:0;237657:96;;193574:536;;;;;;;;;;-1:-1:-1;193574:536:0;;;;;:::i;:::-;;:::i;141613:436::-;;;;;;;;;;-1:-1:-1;141613:436:0;;;;;:::i;:::-;;:::i;138694:193::-;;;;;;;;;;-1:-1:-1;138694:193:0;;;;;:::i;:::-;;:::i;240237:115::-;;;;;;;;;;-1:-1:-1;240237:115:0;;;;;:::i;:::-;;:::i;208495:183::-;;;;;;;;;;;;;:::i;181879:564::-;;;;;;;;;;-1:-1:-1;181879:564:0;;;;;:::i;:::-;;:::i;153072:609::-;;;;;;;;;;-1:-1:-1;153072:609:0;;;;;:::i;:::-;;:::i;165573:166::-;;;;;;;;;;-1:-1:-1;165573:166:0;;;;;:::i;:::-;165718:13;;165631:7;165718:13;;;-1:-1:-1;;;;;;;;;;;165718:13:0;;;;;;;165573:166;154454:1081;;;;;;;;;;-1:-1:-1;154454:1081:0;;;;;:::i;:::-;;:::i;209911:1358::-;;;;;;:::i;:::-;;:::i;240483:126::-;;;;;;;;;;-1:-1:-1;240483:126:0;;;;;:::i;:::-;;:::i;223954:1339::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;167395:107::-;;;;;;;;;;-1:-1:-1;167395:107:0;;;;;:::i;:::-;;:::i;176501:1020::-;;;;;;;;;;-1:-1:-1;176501:1020:0;;;;;:::i;:::-;;:::i;211931:419::-;;;;;;:::i;:::-;;:::i;209212:230::-;;;;;;;;;;-1:-1:-1;209212:230:0;;;;;:::i;:::-;;:::i;193160:406::-;;;;;;;;;;-1:-1:-1;193160:406:0;;;;;:::i;:::-;;:::i;138950:151::-;;;;;;;;;;-1:-1:-1;138950:151:0;;;;;:::i;:::-;;:::i;175305:590::-;;;;;;;;;;-1:-1:-1;175305:590:0;;;;;:::i;:::-;;:::i;184265:208::-;;;;;;;;;;-1:-1:-1;184265:208:0;;;;;:::i;:::-;-1:-1:-1;;;;;184400:58:0;;;;184376:4;184400:58;;;-1:-1:-1;;;;;;;;;;;184400:58:0;;;;;;;;:65;;;;;;;;;;;184265:208;178358:588;;;;;;;;;;-1:-1:-1;178358:588:0;;;;;:::i;:::-;;:::i;240617:268::-;;;;;;;;;;-1:-1:-1;240617:268:0;;;;;:::i;:::-;;:::i;:::-;;;;22739:25:1;;;22795:2;22780:18;;22773:34;;;;22712:18;240617:268:0;22565:248:1;115417:201:0;;;;;;;;;;-1:-1:-1;115417:201:0;;;;;:::i;:::-;;:::i;189146:151::-;;;;;;;;;;-1:-1:-1;189146:151:0;;;;;:::i;:::-;;:::i;240893:238::-;241019:20;241041;241081:42;241101:10;241113:9;241081:19;:42::i;:::-;241074:49;;;;240893:238;;;;;;:::o;139421:201::-;139504:4;87451:10;139560:32;87451:10;139576:7;139585:6;139560:8;:32::i;:::-;139610:4;139603:11;;;139421:201;;;;;:::o;220716:1283::-;-1:-1:-1;;;;;;;;;;;;;;;;;220874:35:0;220911:28;-1:-1:-1;;;;;;;;;;;;;;;;;;;220911:28:0;221133:34;;;;;;;;-1:-1:-1;221133:34:0;;;-1:-1:-1;;;;;221133:34:0;;;;;;;221287:21;;;;;;;;;;;221133:34;;-1:-1:-1;;;221287:21:0;;;-1:-1:-1;;;;;;;;;;;;;;;;;221287:21:0;;;;;;;;;;;;;;;-1:-1:-1;221271:37:0;-1:-1:-1;221751:20:0;;221801:124;221826:19;;;;221860:22;;;;221897:17;;;;221826:10;221897:17;:::i;:::-;221801:10;:124::i;:::-;221949:42;;;;;;;;;;;;;;;;220716:1283;;;;-1:-1:-1;;;;;;220716:1283:0:o;240360:115::-;240416:15;240451:16;240457:9;240451:5;:16::i;218958:152::-;219003:7;;217854:22;219050:20;219088:14;-1:-1:-1;;;;;219088:14:0;;218958:152;-1:-1:-1;;218958:152:0:o;190775:723::-;191096:8;-1:-1:-1;;;;;191088:31:0;191109:10;191088:31;191084:68;;191128:24;;-1:-1:-1;;;191128:24:0;;191141:10;191128:24;;;4789:51:1;4762:18;;191128:24:0;;;;;;;;191084:68;191291:14;;;;;;191255:32;;191272:14;;191291:7;191272:14;:::i;:::-;191255:16;:32::i;:::-;:50;191251:103;;191323:14;;;;:7;:14;:::i;:::-;191314:40;;-1:-1:-1;;;191314:40:0;;23261:10:1;23249:23;;;191314:40:0;;;23231:42:1;191339:14:0;;;;23289:18:1;;;23282:34;23204:18;;191314:40:0;23059:263:1;191251:103:0;191431:59;191442:7;191451:5;191458:8;;191468:9;191479:10;;191431;:59::i;:::-;190775:723;;;;;;;:::o;140202:261::-;140299:4;87451:10;140357:38;140373:4;87451:10;140388:6;140357:15;:38::i;:::-;140406:27;140416:4;140422:2;140426:6;140406:9;:27::i;:::-;140451:4;140444:11;;;140202:261;;;;;;:::o;166274:206::-;114404:13;:11;:13::i;:::-;166415::::1;::::0;::::1;166355:25;166415:13:::0;;;-1:-1:-1;;;;;;;;;;;166415:13:0::1;::::0;;;;;;;;:21;;;166452:20;;23231:42:1;;;23289:18;;23282:34;;;164123:23:0;166452:20:::1;::::0;23204:18:1;166452:20:0::1;;;;;;;;166344:136;166274:206:::0;;:::o;194314:106::-;194365:7;194392:20;:18;:20::i;:::-;194385:27;;194314:106;:::o;239890:103::-;84696:13;;239939:1;;84696:13;;;;;84695:14;:40;;;;-1:-1:-1;84713:12:0;;:22;;;;:12;;:22;84695:40;84687:99;;;;-1:-1:-1;;;84687:99:0;;23529:2:1;84687:99:0;;;23511:21:1;23568:2;23548:18;;;23541:30;23607:34;23587:18;;;23580:62;-1:-1:-1;;;23658:18:1;;;23651:44;23712:19;;84687:99:0;23327:410:1;84687:99:0;84797:12;:22;;-1:-1:-1;;84830:20:0;84797:22;;;84830:20;84797:22;84830:20;;;239953:32:::1;239967:6;240073:21:::0;;;;;;;;;;;;-1:-1:-1;;;240073:21:0;;;;;240001:101;239967:6:::1;239780:14:::0;;;;;;;;;;;;-1:-1:-1;;;239780:14:0;;;;239953:13:::1;:32::i;:::-;84889:5:::0;84873:21;;-1:-1:-1;;84873:21:0;;;84910:20;;8028:4:1;8016:17;;7998:36;;84910:20:0;;7986:2:1;7971:18;84910:20:0;;;;;;;239890:103;:::o;140872:238::-;140960:4;87451:10;141016:64;87451:10;141032:7;141069:10;141041:25;87451:10;141032:7;141041:9;:25::i;:::-;:38;;;;:::i;:::-;141016:8;:64::i;222462:787::-;-1:-1:-1;;;;;;;;;;;;;;;;;222802:24:0;222830:74;222841:19;;;;222862:22;;;;222886:17;;;;222841:10;222886:17;:::i;222830:74::-;222799:105;;;222996:20;223018;223042:49;223062:10;223074:16;223042:19;:49::i;:::-;222995:96;;-1:-1:-1;222995:96:0;-1:-1:-1;223183:58:0;223190:17;;;;:10;:17;:::i;:::-;223209:7;223218;223227:13;223183:6;:58::i;:::-;223176:65;222462:787;-1:-1:-1;;;;;;222462:787:0:o;152076:225::-;152260:23;;;152177:33;152260:23;;;151688:31;152260:23;;;;;;;;:33;;;;;;;;;;;152253:40;;152152:12;;151688:31;152260:33;152253:40;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;152076:225;;;;:::o;181279:222::-;181394:99;181428:10;181447:5;181482:1;181485;181488;181465:25;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;181394:19;:99::i;:::-;181279:222;;;;;:::o;220175:226::-;114404:13;:11;:13::i;:::-;217854:22;220317:30;;-1:-1:-1;;;;;;220317:30:0::1;-1:-1:-1::0;;;;;220317:30:0;::::1;::::0;;::::1;::::0;;220363::::1;::::0;4789:51:1;;;220363:30:0::1;::::0;4777:2:1;4762:18;220363:30:0::1;;;;;;;;220248:153;220175:226:::0;:::o;115159:103::-;114404:13;:11;:13::i;:::-;115224:30:::1;115251:1;115224:18;:30::i;:::-;115159:103::o:0;194118:188::-;-1:-1:-1;;;;;194273:15:0;;194178:7;194273:15;;;192915:27;194273:15;;;;;;;21828:14;194273:25;21736:114;131039:931;131142:13;131170:18;;131142:13;;;131170:18;131142:13;-1:-1:-1;;;;;;;;;;;131660:13:0;;131391:45;;-1:-1:-1;131660:18:0;:43;;;;-1:-1:-1;131682:16:0;;;;:21;131660:43;131652:77;;;;-1:-1:-1;;;131652:77:0;;24934:2:1;131652:77:0;;;24916:21:1;24973:2;24953:18;;;24946:30;-1:-1:-1;;;24992:18:1;;;24985:51;25053:18;;131652:77:0;24732:345:1;131652:77:0;131795:13;:11;:13::i;:::-;131823:16;:14;:16::i;:::-;131935;;;131918:1;131935:16;;;;;;;;;-1:-1:-1;;;131742:220:0;;;-1:-1:-1;131742:220:0;;-1:-1:-1;131854:13:0;;-1:-1:-1;131890:4:0;;-1:-1:-1;131918:1:0;-1:-1:-1;131935:16:0;-1:-1:-1;131742:220:0;-1:-1:-1;;131039:931:0:o;179737:1105::-;-1:-1:-1;;;;;180027:16:0;;180033:10;180027:16;180023:76;;180052:47;;-1:-1:-1;;;180052:47:0;;180075:10;180052:47;;;25294:34:1;-1:-1:-1;;;;;25364:15:1;;25344:18;;;25337:43;25229:18;;180052:47:0;25082:304:1;180023:76:0;180133:10;180114:15;:29;180110:64;;180152:22;;-1:-1:-1;;;180152:22:0;;;;;;;;;;;180110:64;180208:11;180189:15;:30;180185:65;;180228:22;;-1:-1:-1;;;180228:22:0;;;;;;;;;;;180185:65;180261:63;180303:4;180316:5;180261:27;:63::i;:::-;180373:268;180424:4;173332:66;180494:35;;180531:4;180537:2;180541:5;180548:10;180560:11;180573:5;180483:96;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;180455:139;;;;;;180620:9;180373:27;:268::i;:::-;180715:60;180754:4;180767:5;180715:24;:60::i;:::-;180786:48;180804:4;180814:2;180826:5;180786:9;:48::i;193574:536::-;193784:8;193765:15;:27;;193757:69;;;;-1:-1:-1;;;193757:69:0;;26261:2:1;193757:69:0;;;26243:21:1;26300:2;26280:18;;;26273:30;26339:31;26319:18;;;26312:59;26388:18;;193757:69:0;26059:353:1;193757:69:0;193839:219;193890:5;192338:95;193960:5;193967:7;193976:5;193983:16;193993:5;193983:9;:16::i;:::-;193932:78;;;;;;26704:25:1;;;;-1:-1:-1;;;;;26803:15:1;;;26783:18;;;26776:43;26855:15;;;;26835:18;;;26828:43;26887:18;;;26880:34;26930:19;;;26923:35;26974:19;;;26967:35;;;26676:19;;193932:78:0;26417:591:1;193839:219:0;194071:31;194080:5;194087:7;194096:5;194071:8;:31::i;141613:436::-;141706:4;87451:10;141706:4;141789:25;87451:10;141806:7;141789:9;:25::i;:::-;141762:52;;141853:15;141833:16;:35;;141825:85;;;;-1:-1:-1;;;141825:85:0;;27215:2:1;141825:85:0;;;27197:21:1;27254:2;27234:18;;;27227:30;27293:34;27273:18;;;27266:62;-1:-1:-1;;;27344:18:1;;;27337:35;27389:19;;141825:85:0;27013:401:1;141825:85:0;141946:60;141955:5;141962:7;141990:15;141971:16;:34;141946:8;:60::i;:::-;-1:-1:-1;142037:4:0;;141613:436;-1:-1:-1;;;;141613:436:0:o;138694:193::-;138773:4;87451:10;138829:28;87451:10;138846:2;138850:6;138829:9;:28::i;240237:115::-;240292:16;240328;240334:9;240328:5;:16::i;208495:183::-;208547:7;;208092:36;208608:34;207940:206;181879:564;181985:69;182027:10;182046:5;181985:27;:69::i;:::-;182163:60;;;173558:66;182163:60;;;27621:25:1;-1:-1:-1;;;;;27682:32:1;;27662:18;;;27655:60;;;;27731:18;;;27724:34;;;182065:206:0;;182116:10;;27594:18:1;;182163:60:0;27419:345:1;182065:206:0;-1:-1:-1;;;;;182284:58:0;;:46;:58;;;-1:-1:-1;;;;;;;;;;;182284:58:0;;;;;;;;:65;;;;;;;;;:72;;-1:-1:-1;;182284:72:0;182352:4;182284:72;;;182372:63;182284:65;;:58;182372:63;;;181879:564;;;:::o;153072:609::-;114404:13;:11;:13::i;:::-;151688:31;153185:33:::1;153261:360;153281:27:::0;;::::1;153261:360;;;153445:48;153465:16;;153482:1;153465:19;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:27;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;153445:19;:48::i;:::-;153582:16;;153599:1;153582:19;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:27;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;153508:1:::0;:17:::1;153526:16:::0;;153543:1;153526:19;;::::1;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:23;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;153508:42;;;;;;;;;;;;;;;:71;153551:16;;153568:1;153551:19;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:27;::::0;;;;;::::1;;;:::i;:::-;153508:71;;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;153508:71:0;;:101:::1;::::0;;:71;:101:::1;:::i;:::-;-1:-1:-1::0;153310:3:0::1;;153261:360;;;;153638:35;153656:16;;153638:35;;;;;;;:::i;154454:1081::-:0;154726:23;;;154626:33;154726:23;;;151688:31;154726:23;;;;;;;;:33;;;;;;;;;;154702:57;;154601:12;;154626:33;154726;154702:57;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;154891:8;:15;154910:1;154891:20;154887:46;;154920:13;;154913:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;154913:20:0;;-1:-1:-1;154913:20:0;;-1:-1:-1;;;;;154913:20:0;154887:46;155021:1;154997:25;;;154993:46;;155031:8;-1:-1:-1;155024:15:0;;-1:-1:-1;155024:15:0;154993:46;155189:1;155165:25;;155161:271;;155207:34;155227:13;;155207:19;:34::i;:::-;155392:8;155402:17;:13;155416:1;155402:13;;:17;:::i;:::-;155379:41;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;155372:48;;;;;;155161:271;155513:13;;155498:29;;-1:-1:-1;;;155498:29:0;;;;;;;;;:::i;154454:1081::-;;;;;;;:::o;209911:1358::-;210013:9;210008:1057;210028:19;;;210008:1057;;;210069:29;210101:8;;210110:1;210101:11;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;210069:43;-1:-1:-1;210198:50:0;210205:20;;;;210069:43;210205:20;:::i;:::-;210227;;;;165718:13;;;;;230900:4;165718:13;;;-1:-1:-1;;;;;;;;;;;165718:13:0;;;;;;230924:20;;230818:134;210198:50;210193:65;;210250:8;;;210193:65;210829:4;:22;210860:12;;;;:6;210925:11;;;;210955:14;;;;210860:6;210955:14;:::i;:::-;210988:15;;;;;;;;:::i;:::-;211022:16;;;;:6;:16;:::i;:::-;210829:224;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;210054:1011;210008:1057;210049:3;;210008:1057;;;;211225:10;-1:-1:-1;;;;;211215:43:0;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;211215:45:0;;;;;;;;;;;;:::i;:::-;211198:63;;-1:-1:-1;;;211198:63:0;;;;;;;;:::i;240483:126::-;240543:16;240579:22;240591:9;240579:11;:22::i;223954:1339::-;224119:34;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;224521:20:0;;224571:120;224592:19;;;;224626:22;;;;224663:17;;;;224592:10;224663:17;:::i;:::-;224571:6;:120::i;:::-;224520:171;;;;224783:20;224805;224829:49;224849:10;224861:16;224829:19;:49::i;:::-;224782:96;;-1:-1:-1;224782:96:0;-1:-1:-1;225004:66:0;225012:17;;;;:10;:17;:::i;:::-;225031:7;225040;225004:66;;;;;;;225049:4;225004:66;:::i;:::-;225055:14;225004:7;:66::i;:::-;225138:42;;;;;;;;;;;;;;;;;;;225206:15;;224991:79;;-1:-1:-1;225138:42:0;;-1:-1:-1;225242:10:0;;225206:15;225198:87;;225223:17;;;;:10;:17;:::i;:::-;225198:87;;;36658:10:1;36646:23;;;36628:42;;36701:2;36686:18;;36679:34;;;36729:18;;36722:34;;;36616:2;36601:18;225198:87:0;;;;;;;224185:1108;;;;223954:1339;;;;;;:::o;167395:107::-;114404:13;:11;:13::i;:::-;167463:31:::1;::::0;-1:-1:-1;;;167463:31:0;;-1:-1:-1;;;;;4807:32:1;;;167463:31:0::1;::::0;::::1;4789:51:1::0;167463:8:0::1;:20;::::0;::::1;::::0;4762:18:1;;167463:31:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;176501:1020:::0;176811:10;176792:15;:29;176788:64;;176830:22;;-1:-1:-1;;;176830:22:0;;;;;;;;;;;176788:64;176886:11;176867:15;:30;176863:65;;176906:22;;-1:-1:-1;;;176906:22:0;;;;;;;;;;;176863:65;176939:63;176981:4;176994:5;176939:27;:63::i;:::-;177051:269;177102:4;173037:66;177172:36;;177210:4;177216:2;177220:5;177227:10;177239:11;177252:5;177161:97;;;;;;;;;;;;;;:::i;211931:419::-;212218:10;212240:4;212218:27;212214:50;;212254:10;;-1:-1:-1;;;212254:10:0;;;;;;;;;;;212214:50;212275:67;212294:7;212303:5;212310:8;;212320:9;212331:10;;212275:18;:67::i;209212:230::-;114404:13;:11;:13::i;:::-;208092:36;209374:22;;-1:-1:-1;;;;;;209374:22:0::1;-1:-1:-1::0;;;;;209374:22:0;::::1;::::0;;::::1;::::0;;209412::::1;::::0;4789:51:1;;;209412:22:0::1;::::0;4777:2:1;4762:18;209412:22:0::1;4643:203:1::0;193160:406:0;193370:188;193399:5;193428:7;193457:5;193487:8;193538:1;193541;193544;193521:25;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;193370:6;:188::i;138950:151::-;-1:-1:-1;;;;;139066:18:0;;;139039:7;139066:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;138950:151::o;175305:590::-;175622:265;175669:4;175692:2;175716:5;175748:10;175786:11;175819:5;175867:1;175870;175873;175850:25;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;175622;:265::i;:::-;175305:590;;;;;;;;;:::o;178358:588::-;178674:264;178720:4;178743:2;178767:5;178799:10;178837:11;178870:5;178918:1;178921;178924;178901:25;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;178674:24;:264::i;240617:268::-;240716:20;240738:24;240833:44;240844:9;240855:12;240869:7;240833:10;:44::i;:::-;240826:51;;;;240617:268;;;;;;;:::o;115417:201::-;114404:13;:11;:13::i;:::-;-1:-1:-1;;;;;115506:22:0;::::1;115498:73;;;::::0;-1:-1:-1;;;115498:73:0;;36969:2:1;115498:73:0::1;::::0;::::1;36951:21:1::0;37008:2;36988:18;;;36981:30;37047:34;37027:18;;;37020:62;-1:-1:-1;;;37098:18:1;;;37091:36;37144:19;;115498:73:0::1;36767:402:1::0;115498:73:0::1;115582:28;115601:8;115582:18;:28::i;:::-;115417:201:::0;:::o;189146:151::-;189228:4;189276:13;;;;;;189252:20;;189258:13;;189276:6;189258:13;:::i;189252:20::-;:37;;189146:151;-1:-1:-1;;189146:151:0:o;225596:1419::-;225731:20;225753;225786:15;225959:330;225992:10;:13;;;226020:16;226026:9;226020:5;:16::i;:::-;226257:21;;;;:10;:21;:::i;:::-;225959:330;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;225959:18:0;;-1:-1:-1;;;225959:330:0:i;:::-;225935:354;;-1:-1:-1;225935:354:0;-1:-1:-1;226371:14:0;225935:354;226388:33;;217624:1;226388:33;;;217671:1;226388:33;226371:50;-1:-1:-1;226545:67:0;226560:17;;;;:10;:17;:::i;:::-;226579:7;226588:23;;;;:10;:23;:::i;226545:67::-;217854:22;226918:14;;226535:77;;-1:-1:-1;217854:22:0;-1:-1:-1;;;;;226918:14:0;:28;226914:93;;226966:14;;226948:59;;-1:-1:-1;;;226948:59:0;;-1:-1:-1;;;;;226966:14:0;;;;226948:41;;:59;;226990:7;;226999;;226948:59;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;226914:93;225775:1240;;;225596:1419;;;;;:::o;241583:191::-;241717:49;241743:5;241750:7;241759:6;241717:25;:49::i;:::-;241583:191;;;:::o;232879:682::-;233025:20;233047:24;233223:22;233235:9;233223:11;:22::i;:::-;233208:37;;233373:12;233354:31;;233458:12;233439:16;:31;233435:119;;;233494:48;;-1:-1:-1;;;233494:48:0;;;;;22739:25:1;;;22780:18;;;22773:34;;;22712:18;;233494:48:0;22565:248:1;232133:149:0;232198:15;232240:33;232252:21;232240:9;:33;:::i;166786:262::-;166951:13;;;166856:7;166951:13;;;-1:-1:-1;;;;;;;;;;;166951:13:0;;;;;;;;;166975:43;;167006:12;;-1:-1:-1;;;167006:12:0;;37820:10:1;37808:23;;167006:12:0;;;37790:42:1;37763:18;;167006:12:0;37646:192:1;227546:1837:0;228032:17;228052:36;:17;:8;;:15;:17::i;:::-;76274:2;76162:125;228052:36;228032:56;;228223:24;228250:62;228258:9;228269:26;228275:19;:8;;:17;:19::i;:::-;228269:5;:26::i;:::-;228297:14;;;;:7;:14;:::i;:::-;228250:7;:62::i;:::-;228223:89;-1:-1:-1;73553:2:0;-1:-1:-1;;228325:970:0;;;228431:23;228457:180;228501:13;;;;;;;;:::i;:::-;228533:14;;;;:7;:14;:::i;:::-;228566:16;228601:21;:8;;:19;:21::i;:::-;228457:25;:180::i;:::-;229191:92;;-1:-1:-1;;;229191:92:0;;228431:206;;-1:-1:-1;;;;;;229191:8:0;:20;;;;:92;;229212:9;;229223:5;;229230:1;;228431:206;;229191:92;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;228352:943;228325:970;-1:-1:-1;;;;;229312:63:0;;229324:5;229312:63;229331:14;;;;:7;:14;:::i;:::-;229312:63;;;23261:10:1;23249:23;;;23231:42;;23304:2;23289:18;;23282:34;;;23204:18;229312:63:0;;;;;;;227855:1528;;227546:1837;;;;;;;:::o;146243:419::-;146344:24;146371:25;146381:5;146388:7;146371:9;:25::i;:::-;146344:52;;-1:-1:-1;;146411:16:0;:37;146407:248;;146493:6;146473:16;:26;;146465:68;;;;-1:-1:-1;;;146465:68:0;;38796:2:1;146465:68:0;;;38778:21:1;38835:2;38815:18;;;38808:30;38874:31;38854:18;;;38847:59;38923:18;;146465:68:0;38594:353:1;146465:68:0;146577:51;146586:5;146593:7;146621:6;146602:16;:25;146577:8;:51::i;:::-;146333:329;146243:419;;;:::o;241362:182::-;241492:44;241519:4;241525:2;241529:6;241492:26;:44::i;114683:132::-;114591:6;;-1:-1:-1;;;;;114591:6:0;87451:10;114747:23;114739:68;;;;-1:-1:-1;;;114739:68:0;;39154:2:1;114739:68:0;;;39136:21:1;;;39173:18;;;39166:30;39232:34;39212:18;;;39205:62;39284:18;;114739:68:0;38952:356:1;129851:111:0;129904:7;129931:23;:21;:23::i;129299:132::-;129385:38;129409:4;129415:7;129385:23;:38::i;:::-;129299:132;;:::o;197150:402::-;-1:-1:-1;;;;;;;;;;;;;;;;;197378:8:0;-1:-1:-1;;;;;197378:14:0;;197411:86;;;;;;;;197427:7;197411:86;;;;;;197436:25;197453:7;197436:16;:25::i;:::-;197411:86;;;;197463:8;197411:86;;;;197473:8;197411:86;;;;197483:13;197411:86;;;;;197524:4;197378:166;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;197358:186;197150:402;-1:-1:-1;;;;;197150:402:0:o;115778:191::-;115871:6;;;-1:-1:-1;;;;;115888:17:0;;;-1:-1:-1;;;;;;115888:17:0;;;;;;;115921:40;;115871:6;;;115888:17;115871:6;;115921:40;;115852:16;;115921:40;115841:128;115778:191;:::o;132202:158::-;132345:7;132338:14;;132256:13;;-1:-1:-1;;;;;;;;;;;128676:21:0;132338:14;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;132202:158;:::o;132595:164::-;132741:10;132734:17;;132652:13;;-1:-1:-1;;;;;;;;;;;128676:21:0;132734:17;;;:::i;182867:224::-;-1:-1:-1;;;;;;;;;;;;;;;;182967:58:0;;:46;:58;;;;;;;;;;;:65;;;;;;;;;;182963:120;;;183054:29;;-1:-1:-1;;;183054:29:0;;;;;;;;;;;172115:402;172256:192;172320:6;172351:42;172381:10;172351:16;:42::i;:::-;172423:9;172256:36;:192::i;:::-;172255:193;:217;;;-1:-1:-1;;;;;;172452:20:0;;;172255:217;172237:272;;;172491:18;;-1:-1:-1;;;172491:18:0;;;;;;;;;;;183514:243;-1:-1:-1;;;;;183602:58:0;;:46;:58;;;-1:-1:-1;;;;;;;;;;;183602:58:0;;;;;;;;:65;;;;;;;;;:72;;-1:-1:-1;;183602:72:0;183670:4;183602:72;;;183690:59;183602:65;;:58;183690:59;;;183514:243;;:::o;194428:237::-;-1:-1:-1;;;;;194594:15:0;;194488;194594;;;192915:27;194594:15;;;;;;;;21828:14;;21965:1;21947:19;;;;;21828:14;194630:27;194505:160;194428:237;;;:::o;231761:141::-;231825:16;231861:33;231873:21;-1:-1:-1;;;;;231861:33:0;;;:::i;155681:221::-;155768:18;155803:13;155814:1;155768:18;155803:8;;:13;:::i;:::-;155796:21;;;:::i;:::-;155789:29;;;-1:-1:-1;151536:1:0;155833:28;;155829:65;;155885:8;;155870:24;;-1:-1:-1;;;155870:24:0;;;;;;;;;:::i;231356:174::-;231427:16;231501:21;231464:33;231501:21;231464:9;:33;:::i;:::-;231463:59;;;;:::i;238188:561::-;238330:20;238352:24;238424:44;238435:9;238446:12;238460:7;238424:10;:44::i;:::-;238389:79;;-1:-1:-1;238389:79:0;-1:-1:-1;238710:31:0;238716:10;238389:79;238710:5;:31::i;198327:783::-;198534:31;;:::i;:::-;198701:20;198724:26;198735:4;:14;;;198724:10;:26::i;:::-;198765:15;;;;198701:49;;-1:-1:-1;198765:19:0;198761:53;;198786:28;198798:4;:15;;;198786:11;:28::i;:::-;198847:8;-1:-1:-1;;;;;198847:13:0;;198869:12;198962:92;;;;;;;;198978:7;198962:92;;;;;;198987:25;199004:7;198987:16;:25::i;:::-;198962:92;;;;199014:8;198962:92;;;;199024:8;198962:92;;;;199052:1;199034:4;:15;;;:19;198962:92;;;;;199073:14;198847:255;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;198827:275;198327:783;-1:-1:-1;;;;;;;198327:783:0:o;73918:516::-;74116:18;;74056:17;;74116:22;;;74261:165;;74403:7;74412:13;74386:40;;;;;;;;42099:19:1;;;42174:3;42152:16;-1:-1:-1;;;;;;42148:51:1;42143:2;42134:12;;42127:73;42225:2;42216:12;;41944:290;74386:40:0;;;;;;;;;;;;;74261:165;;;74304:7;74313:13;74345:10;74358:11;74287:83;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;74261:165;74254:172;;73918:516;;;;;;:::o;145606:346::-;-1:-1:-1;;;;;145708:19:0;;145700:68;;;;-1:-1:-1;;;145700:68:0;;42978:2:1;145700:68:0;;;42960:21:1;43017:2;42997:18;;;42990:30;43056:34;43036:18;;;43029:62;-1:-1:-1;;;43107:18:1;;;43100:34;43151:19;;145700:68:0;42776:400:1;145700:68:0;-1:-1:-1;;;;;145787:21:0;;145779:68;;;;-1:-1:-1;;;145779:68:0;;43383:2:1;145779:68:0;;;43365:21:1;43422:2;43402:18;;;43395:30;43461:34;43441:18;;;43434:62;-1:-1:-1;;;43512:18:1;;;43505:32;43554:19;;145779:68:0;43181:398:1;145779:68:0;-1:-1:-1;;;;;145860:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;145912:32;;7359:25:1;;;145912:32:0;;7332:18:1;145912:32:0;;;;;;;145606:346;;;:::o;74919:125::-;74979:7;75014:21;73497:2;74979:7;75014:4;;:21;:::i;:::-;75006:30;;;:::i;75229:154::-;75291:6;75331:42;73553:2;73497;75331:4;;:42;:::i;:::-;75324:50;;;:::i;:::-;75317:58;;;75229:154;-1:-1:-1;;;75229:154:0:o;239093:371::-;239231:24;239311:21;239317:3;239322:9;239311:5;:21::i;:::-;-1:-1:-1;239447:9:0;;239093:371;-1:-1:-1;;239093:371:0:o;75550:132::-;75614:12;75646:28;:4;73553:2;75646:4;;:28;:::i;:::-;75639:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;75639:35:0;;75550:132;-1:-1:-1;;;;;;75550:132:0:o;70842:291::-;71031:17;71085:6;71093:7;71102:9;71113:11;71068:57;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;71061:64;;70842:291;;;;;;:::o;142519:806::-;-1:-1:-1;;;;;142616:18:0;;142608:68;;;;-1:-1:-1;;;142608:68:0;;44955:2:1;142608:68:0;;;44937:21:1;44994:2;44974:18;;;44967:30;45033:34;45013:18;;;45006:62;-1:-1:-1;;;45084:18:1;;;45077:35;45129:19;;142608:68:0;44753:401:1;142608:68:0;-1:-1:-1;;;;;142695:16:0;;142687:64;;;;-1:-1:-1;;;142687:64:0;;45361:2:1;142687:64:0;;;45343:21:1;45400:2;45380:18;;;45373:30;45439:34;45419:18;;;45412:62;-1:-1:-1;;;45490:18:1;;;45483:33;45533:19;;142687:64:0;45159:399:1;142687:64:0;-1:-1:-1;;;;;142837:15:0;;142815:19;142837:15;;;:9;:15;;;;;;142871:21;;;;142863:72;;;;-1:-1:-1;;;142863:72:0;;45765:2:1;142863:72:0;;;45747:21:1;45804:2;45784:18;;;45777:30;45843:34;45823:18;;;45816:62;-1:-1:-1;;;45894:18:1;;;45887:36;45940:19;;142863:72:0;45563:402:1;142863:72:0;-1:-1:-1;;;;;142971:15:0;;;;;;;:9;:15;;;;;;142989:20;;;142971:38;;143189:13;;;;;;;;;;:23;;;;;;143241:26;;;;;;143003:6;7359:25:1;;7347:2;7332:18;;7213:177;143241:26:0;;;;;;;;143280:37;241583:191;129970:193;130025:7;127892:95;130084:17;:15;:17::i;:::-;130103:20;:18;:20::i;:::-;130062:92;;;;;;46229:25:1;;;;46270:18;;46263:34;;;;46313:18;;;46306:34;130125:13:0;46356:18:1;;;46349:34;130148:4:0;46399:19:1;;;46392:61;46201:19;;130062:92:0;;;;;;;;;;;;130052:103;;;;;;130045:110;;129970:193;:::o;129439:321::-;-1:-1:-1;;;;;;;;;;;129591:7:0;:14;129601:4;129591:7;:14;:::i;:::-;-1:-1:-1;129616:10:0;;;:20;129629:7;129616:10;:20;:::i;:::-;-1:-1:-1;129720:1:0;129704:17;;;129732:16;;;;:20;-1:-1:-1;;129439:321:0:o;130806:178::-;130883:7;130910:66;130943:20;:18;:20::i;:::-;130965:10;112479:4;112473:11;-1:-1:-1;;;112498:23:0;;112551:4;112542:14;;112535:39;;;;112604:4;112595:14;;112588:34;112659:4;112644:20;;;112276:406;156903:371;157009:4;157027:17;157046:24;157074:33;157091:4;157097:9;157074:16;:33::i;:::-;157026:81;;-1:-1:-1;157026:81:0;-1:-1:-1;157148:26:0;157139:5;:35;;;;;;;;:::i;:::-;;:58;;;;;157191:6;-1:-1:-1;;;;;157178:19:0;:9;-1:-1:-1;;;;;157178:19:0;;157139:58;157138:128;;;;157215:51;157242:6;157250:4;157256:9;157215:26;:51::i;144493:675::-;-1:-1:-1;;;;;144577:21:0;;144569:67;;;;-1:-1:-1;;;144569:67:0;;48146:2:1;144569:67:0;;;48128:21:1;48185:2;48165:18;;;48158:30;48224:34;48204:18;;;48197:62;-1:-1:-1;;;48275:18:1;;;48268:31;48316:19;;144569:67:0;47944:397:1;144569:67:0;-1:-1:-1;;;;;144736:18:0;;144711:22;144736:18;;;:9;:18;;;;;;144773:24;;;;144765:71;;;;-1:-1:-1;;;144765:71:0;;48548:2:1;144765:71:0;;;48530:21:1;48587:2;48567:18;;;48560:30;48626:34;48606:18;;;48599:62;-1:-1:-1;;;48677:18:1;;;48670:32;48719:19;;144765:71:0;48346:398:1;144765:71:0;-1:-1:-1;;;;;144872:18:0;;;;;;:9;:18;;;;;;;;144893:23;;;144872:44;;145011:12;:22;;;;;;;145062:37;7359:25:1;;;144872:18:0;;;145062:37;;7332:18:1;145062:37:0;;;;;;;241583:191;;;:::o;199819:194::-;199885:17;199932:10;199919:9;:23;199915:62;;199951:26;;-1:-1:-1;;;199951:26:0;;199967:9;199951:26;;;7359:25:1;7332:18;;199951:26:0;7213:177:1;199915:62:0;-1:-1:-1;199995:10:0;199819:194::o;200399:417::-;200554:15;200572:8;-1:-1:-1;;;;;200572:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;200554:36;-1:-1:-1;;;;;;200605:21:0;;200601:54;;200635:20;;-1:-1:-1;;;200635:20:0;;;;;;;;;;;200601:54;200732:76;-1:-1:-1;;;;;200732:32:0;;200765:10;200785:8;200796:11;200732:32;:76::i;143612:548::-;-1:-1:-1;;;;;143696:21:0;;143688:65;;;;-1:-1:-1;;;143688:65:0;;49207:2:1;143688:65:0;;;49189:21:1;49246:2;49226:18;;;49219:30;49285:33;49265:18;;;49258:61;49336:18;;143688:65:0;49005:355:1;143688:65:0;143844:6;143828:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;143999:18:0;;;;;;:9;:18;;;;;;;;:28;;;;;;144054:37;7359:25:1;;;144054:37:0;;7332:18:1;144054:37:0;;;;;;;129299:132;;:::o;132981:702::-;133031:7;-1:-1:-1;;;;;;;;;;;133031:7:0;133128:13;:11;:13::i;:::-;133156:18;;133107:34;;-1:-1:-1;133156:22:0;133152:524;;133202:22;;;;;;;;132981:702;-1:-1:-1;;132981:702:0:o;133152:524::-;133503:13;;133535:15;;133531:134;;133578:10;132981:702;-1:-1:-1;;;132981:702:0:o;133531:134::-;133636:13;133629:20;;;;;132981:702;:::o;133911:738::-;133964:7;-1:-1:-1;;;;;;;;;;;133964:7:0;134064:16;:14;:16::i;:::-;134095:21;;134040:40;;-1:-1:-1;134095:25:0;134091:551;;134144:25;;;;;;;;133911:738;-1:-1:-1;;133911:738:0:o;134091:551::-;134460:16;;;;134495:18;;134491:140;;134541:13;133911:738;-1:-1:-1;;;133911:738:0:o;96564:747::-;96645:7;96654:12;96683:9;:16;96703:2;96683:22;96679:625;;97027:4;97012:20;;97006:27;97077:4;97062:20;;97056:27;97135:4;97120:20;;97114:27;96722:9;97106:36;97178:25;97189:4;97106:36;97006:27;97056;97178:10;:25::i;:::-;97171:32;;;;;;;;;96679:625;-1:-1:-1;97252:1:0;;-1:-1:-1;97256:35:0;97236:56;;157689:484;157836:4;157854:12;157868:19;157891:6;-1:-1:-1;;;;;157891:17:0;157946:34;;;157982:4;157988:9;157923:75;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;157923:75:0;;;;;;;;;;;;;;-1:-1:-1;;;;;157923:75:0;-1:-1:-1;;;;;;157923:75:0;;;;;;;;;;157891:118;;;;157923:75;157891:118;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;157853:156;;;;158028:7;:43;;;;;158069:2;158052:6;:13;:19;;158028:43;:136;;;;-1:-1:-1;158088:29:0;;-1:-1:-1;;;158129:34:0;158088:29;;;;;;;;;;;;:::i;:::-;:76;;157689:484;-1:-1:-1;;;;;;157689:484:0:o;117570:205::-;117698:68;;;-1:-1:-1;;;;;50397:15:1;;;117698:68:0;;;50379:34:1;50449:15;;50429:18;;;50422:43;50481:18;;;;50474:34;;;117698:68:0;;;;;;;;;;50314:18:1;;;;117698:68:0;;;;;;;;-1:-1:-1;;;;;117698:68:0;-1:-1:-1;;;117698:68:0;;;117671:96;;117691:5;;117671:19;:96::i;99497:1477::-;99585:7;;100519:66;100506:79;;100502:163;;;-1:-1:-1;100618:1:0;;-1:-1:-1;100622:30:0;100602:51;;100502:163;100779:24;;;100762:14;100779:24;;;;;;;;;50746:25:1;;;50819:4;50807:17;;50787:18;;;50780:45;;;;50841:18;;;50834:34;;;50884:18;;;50877:34;;;100779:24:0;;50718:19:1;;100779:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;100779:24:0;;-1:-1:-1;;100779:24:0;;;-1:-1:-1;;;;;;;100818:20:0;;100814:103;;100871:1;100875:29;100855:50;;;;;;;100814:103;100937:6;-1:-1:-1;100945:20:0;;-1:-1:-1;99497:1477:0;;;;;;;;:::o;121494:649::-;121918:23;121944:69;121972:4;121944:69;;;;;;;;;;;;;;;;;121952:5;-1:-1:-1;;;;;121944:27:0;;;:69;;;;;:::i;:::-;121918:95;;122032:10;:17;122053:1;122032:22;:56;;;;122069:10;122058:30;;;;;;;;;;;;:::i;:::-;122024:111;;;;-1:-1:-1;;;122024:111:0;;51124:2:1;122024:111:0;;;51106:21:1;51163:2;51143:18;;;51136:30;51202:34;51182:18;;;51175:62;-1:-1:-1;;;51253:18:1;;;51246:40;51303:19;;122024:111:0;50922:406:1;4312:229:0;4449:12;4481:52;4503:6;4511:4;4517:1;4520:12;4449;5686;5700:23;5727:6;-1:-1:-1;;;;;5727:11:0;5746:5;5753:4;5727:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5685:73;;;;5776:69;5803:6;5811:7;5820:10;5832:12;8156;8185:7;8181:427;;;8213:10;:17;8234:1;8213:22;8209:290;;-1:-1:-1;;;;;1852:19:0;;;8423:60;;;;-1:-1:-1;;;8423:60:0;;51942:2:1;8423:60:0;;;51924:21:1;51981:2;51961:18;;;51954:30;52020:31;52000:18;;;51993:59;52069:18;;8423:60:0;51740:353:1;8423:60:0;-1:-1:-1;8520:10:0;8513:17;;8181:427;8563:33;8571:10;8583:12;9318:17;;:21;9314:388;;9550:10;9544:17;9607:15;9594:10;9590:2;9586:19;9579:44;9314:388;9677:12;9670:20;;-1:-1:-1;;;9670:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:158:1:-;76:5;121:3;112:6;107:3;103:16;99:26;96:46;;;138:1;135;128:12;177:428;274:6;282;335:2;323:9;314:7;310:23;306:32;303:52;;;351:1;348;341:12;303:52;391:9;378:23;-1:-1:-1;;;;;416:6:1;413:30;410:50;;;456:1;453;446:12;410:50;479:69;540:7;531:6;520:9;516:22;479:69;:::i;:::-;469:79;595:2;580:18;;;;567:32;;-1:-1:-1;;;;177:428:1:o;610:250::-;695:1;705:113;719:6;716:1;713:13;705:113;;;795:11;;;789:18;776:11;;;769:39;741:2;734:10;705:113;;;-1:-1:-1;;852:1:1;834:16;;827:27;610:250::o;865:270::-;906:3;944:5;938:12;971:6;966:3;959:19;987:76;1056:6;1049:4;1044:3;1040:14;1033:4;1026:5;1022:16;987:76;:::i;:::-;1117:2;1096:15;-1:-1:-1;;1092:29:1;1083:39;;;;1124:4;1079:50;;865:270;-1:-1:-1;;865:270:1:o;1140:377::-;1333:2;1322:9;1315:21;1296:4;1359:44;1399:2;1388:9;1384:18;1376:6;1359:44;:::i;:::-;1451:9;1443:6;1439:22;1434:2;1423:9;1419:18;1412:50;1479:32;1504:6;1496;1479:32;:::i;1522:219::-;1671:2;1660:9;1653:21;1634:4;1691:44;1731:2;1720:9;1716:18;1708:6;1691:44;:::i;1746:131::-;-1:-1:-1;;;;;1821:31:1;;1811:42;;1801:70;;1867:1;1864;1857:12;1882:315;1950:6;1958;2011:2;1999:9;1990:7;1986:23;1982:32;1979:52;;;2027:1;2024;2017:12;1979:52;2066:9;2053:23;2085:31;2110:5;2085:31;:::i;:::-;2135:5;2187:2;2172:18;;;;2159:32;;-1:-1:-1;;;1882:315:1:o;2394:360::-;2482:6;2535:2;2523:9;2514:7;2510:23;2506:32;2503:52;;;2551:1;2548;2541:12;2503:52;2591:9;2578:23;-1:-1:-1;;;;;2616:6:1;2613:30;2610:50;;;2656:1;2653;2646:12;2610:50;2679:69;2740:7;2731:6;2720:9;2716:22;2679:69;:::i;2913:1335::-;2833:12;;2821:25;;2895:4;2884:16;;;2878:23;2862:14;;;2855:47;3279:4;3327:3;3312:19;;3404:2;3442:3;3437:2;3426:9;3422:18;3415:31;3466:6;3501;3495:13;3532:6;3524;3517:22;3570:3;3559:9;3555:19;3548:26;;3633:3;3623:6;3620:1;3616:14;3605:9;3601:30;3597:40;3583:54;;3656:4;3695;3687:6;3683:17;3718:1;3728:428;3742:6;3739:1;3736:13;3728:428;;;3807:22;;;-1:-1:-1;;3803:37:1;3791:50;;3864:13;;3905:9;;3890:25;;3954:11;;3948:18;3986:15;;;3979:27;;;4029:47;4060:15;;;3948:18;4029:47;:::i;:::-;4019:57;-1:-1:-1;;4134:12:1;;;;4099:15;;;;3764:1;3757:9;3728:428;;;-1:-1:-1;;2833:12:1;;4238:2;4223:18;;2821:25;-1:-1:-1;;;2895:4:1;2884:16;;2878:23;2862:14;;;2855:47;-1:-1:-1;4173:6:1;-1:-1:-1;4188:54:1;2759:149;4253:180;4312:6;4365:2;4353:9;4344:7;4340:23;4336:32;4333:52;;;4381:1;4378;4371:12;4333:52;-1:-1:-1;4404:23:1;;4253:180;-1:-1:-1;4253:180:1:o;4851:154::-;4910:5;4955:2;4946:6;4941:3;4937:16;4933:25;4930:45;;;4971:1;4968;4961:12;5010:347;5061:8;5071:6;5125:3;5118:4;5110:6;5106:17;5102:27;5092:55;;5143:1;5140;5133:12;5092:55;-1:-1:-1;5166:20:1;;-1:-1:-1;;;;;5198:30:1;;5195:50;;;5241:1;5238;5231:12;5195:50;5278:4;5270:6;5266:17;5254:29;;5330:3;5323:4;5314:6;5306;5302:19;5298:30;5295:39;5292:59;;;5347:1;5344;5337:12;5362:1048;5505:6;5513;5521;5529;5537;5545;5553;5606:3;5594:9;5585:7;5581:23;5577:33;5574:53;;;5623:1;5620;5613:12;5574:53;5646;5691:7;5680:9;5646:53;:::i;:::-;5636:63;;5746:2;5735:9;5731:18;5718:32;5708:42;;5801:3;5790:9;5786:19;5773:33;-1:-1:-1;;;;;5866:2:1;5858:6;5855:14;5852:34;;;5882:1;5879;5872:12;5852:34;5921:58;5971:7;5962:6;5951:9;5947:22;5921:58;:::i;:::-;5998:8;;-1:-1:-1;5895:84:1;-1:-1:-1;6083:3:1;6068:19;;6055:33;;-1:-1:-1;6097:31:1;6055:33;6097:31;:::i;:::-;6147:5;;-1:-1:-1;6205:3:1;6190:19;;6177:33;;6222:16;;;6219:36;;;6251:1;6248;6241:12;6219:36;;6290:60;6342:7;6331:8;6320:9;6316:24;6290:60;:::i;:::-;5362:1048;;;;-1:-1:-1;5362:1048:1;;-1:-1:-1;5362:1048:1;;;;6264:86;;-1:-1:-1;;;5362:1048:1:o;7395:456::-;7472:6;7480;7488;7541:2;7529:9;7520:7;7516:23;7512:32;7509:52;;;7557:1;7554;7547:12;7509:52;7596:9;7583:23;7615:31;7640:5;7615:31;:::i;:::-;7665:5;-1:-1:-1;7722:2:1;7707:18;;7694:32;7735:33;7694:32;7735:33;:::i;:::-;7395:456;;7787:7;;-1:-1:-1;;;7841:2:1;7826:18;;;;7813:32;;7395:456::o;8045:163::-;8112:20;;8172:10;8161:22;;8151:33;;8141:61;;8198:1;8195;8188:12;8141:61;8045:163;;;:::o;8213:252::-;8280:6;8288;8341:2;8329:9;8320:7;8316:23;8312:32;8309:52;;;8357:1;8354;8347:12;8309:52;8380:28;8398:9;8380:28;:::i;8652:118::-;8738:5;8731:13;8724:21;8717:5;8714:32;8704:60;;8760:1;8757;8750:12;8775:489;8869:6;8877;8930:2;8918:9;8909:7;8905:23;8901:32;8898:52;;;8946:1;8943;8936:12;8898:52;8986:9;8973:23;-1:-1:-1;;;;;9011:6:1;9008:30;9005:50;;;9051:1;9048;9041:12;9005:50;9074:69;9135:7;9126:6;9115:9;9111:22;9074:69;:::i;:::-;9064:79;;;9193:2;9182:9;9178:18;9165:32;9206:28;9228:5;9206:28;:::i;:::-;9253:5;9243:15;;;8775:489;;;;;:::o;9269:257::-;2833:12;;2821:25;;2895:4;2884:16;;;2878:23;2862:14;;;2855:47;9463:2;9448:18;;9475:45;2759:149;9531:159;9598:20;;9658:6;9647:18;;9637:29;;9627:57;;9680:1;9677;9670:12;9695:256;9761:6;9769;9822:2;9810:9;9801:7;9797:23;9793:32;9790:52;;;9838:1;9835;9828:12;9790:52;9861:28;9879:9;9861:28;:::i;:::-;9851:38;;9908:37;9941:2;9930:9;9926:18;9908:37;:::i;:::-;9898:47;;9695:256;;;;;:::o;10178:156::-;10244:20;;10304:4;10293:16;;10283:27;;10273:55;;10324:1;10321;10314:12;10339:523;10432:6;10440;10448;10456;10464;10517:3;10505:9;10496:7;10492:23;10488:33;10485:53;;;10534:1;10531;10524:12;10485:53;10573:9;10560:23;10592:31;10617:5;10592:31;:::i;:::-;10642:5;-1:-1:-1;10694:2:1;10679:18;;10666:32;;-1:-1:-1;10717:36:1;10749:2;10734:18;;10717:36;:::i;:::-;10339:523;;;;-1:-1:-1;10707:46:1;;10800:2;10785:18;;10772:32;;-1:-1:-1;10851:3:1;10836:19;10823:33;;10339:523;-1:-1:-1;;10339:523:1:o;11104:247::-;11163:6;11216:2;11204:9;11195:7;11191:23;11187:32;11184:52;;;11232:1;11229;11222:12;11184:52;11271:9;11258:23;11290:31;11315:5;11290:31;:::i;11356:1257::-;11762:3;11757;11753:13;11745:6;11741:26;11730:9;11723:45;11704:4;11787:2;11825:3;11820:2;11809:9;11805:18;11798:31;11852:45;11892:3;11881:9;11877:19;11869:6;11852:45;:::i;:::-;11945:9;11937:6;11933:22;11928:2;11917:9;11913:18;11906:50;11979:32;12004:6;11996;11979:32;:::i;:::-;12042:2;12027:18;;12020:34;;;-1:-1:-1;;;;;12091:32:1;;12085:3;12070:19;;12063:61;12111:3;12140:19;;12133:35;;;12205:22;;;12199:3;12184:19;;12177:51;12277:13;;12299:22;;;12349:2;12375:15;;;;-1:-1:-1;12337:15:1;;;;-1:-1:-1;12418:169:1;12432:6;12429:1;12426:13;12418:169;;;12493:13;;12481:26;;12562:15;;;;12527:12;;;;12454:1;12447:9;12418:169;;;-1:-1:-1;12604:3:1;;11356:1257;-1:-1:-1;;;;;;;;;;;;11356:1257:1:o;12618:127::-;12679:10;12674:3;12670:20;12667:1;12660:31;12710:4;12707:1;12700:15;12734:4;12731:1;12724:15;12750:251;12822:2;12816:9;;;12852:15;;-1:-1:-1;;;;;12882:34:1;;12918:22;;;12879:62;12876:88;;;12944:18;;:::i;:::-;12980:2;12973:22;12750:251;:::o;13006:275::-;13077:2;13071:9;13142:2;13123:13;;-1:-1:-1;;13119:27:1;13107:40;;-1:-1:-1;;;;;13162:34:1;;13198:22;;;13159:62;13156:88;;;13224:18;;:::i;:::-;13260:2;13253:22;13006:275;;-1:-1:-1;13006:275:1:o;13286:186::-;13334:4;-1:-1:-1;;;;;13359:6:1;13356:30;13353:56;;;13389:18;;:::i;:::-;-1:-1:-1;13455:2:1;13434:15;-1:-1:-1;;13430:29:1;13461:4;13426:40;;13286:186::o;13477:462::-;13519:5;13572:3;13565:4;13557:6;13553:17;13549:27;13539:55;;13590:1;13587;13580:12;13539:55;13626:6;13613:20;13657:48;13673:31;13701:2;13673:31;:::i;:::-;13657:48;:::i;:::-;13730:2;13721:7;13714:19;13776:3;13769:4;13764:2;13756:6;13752:15;13748:26;13745:35;13742:55;;;13793:1;13790;13783:12;13742:55;13858:2;13851:4;13843:6;13839:17;13832:4;13823:7;13819:18;13806:55;13906:1;13881:16;;;13899:4;13877:27;13870:38;;;;13885:7;13477:462;-1:-1:-1;;;13477:462:1:o;13944:872::-;14066:6;14074;14082;14090;14098;14106;14114;14167:3;14155:9;14146:7;14142:23;14138:33;14135:53;;;14184:1;14181;14174:12;14135:53;14223:9;14210:23;14242:31;14267:5;14242:31;:::i;:::-;14292:5;-1:-1:-1;14349:2:1;14334:18;;14321:32;14362:33;14321:32;14362:33;:::i;:::-;14414:7;-1:-1:-1;14468:2:1;14453:18;;14440:32;;-1:-1:-1;14519:2:1;14504:18;;14491:32;;-1:-1:-1;14570:3:1;14555:19;;14542:33;;-1:-1:-1;14622:3:1;14607:19;;14594:33;;-1:-1:-1;14678:3:1;14663:19;;14650:33;-1:-1:-1;;;;;14695:30:1;;14692:50;;;14738:1;14735;14728:12;14692:50;14761:49;14802:7;14793:6;14782:9;14778:22;14761:49;:::i;:::-;14751:59;;;13944:872;;;;;;;;;;:::o;14821:734::-;14925:6;14933;14941;14949;14957;15010:3;14998:9;14989:7;14985:23;14981:33;14978:53;;;15027:1;15024;15017:12;14978:53;15066:9;15053:23;15085:31;15110:5;15085:31;:::i;:::-;15135:5;-1:-1:-1;15192:2:1;15177:18;;15164:32;15205:33;15164:32;15205:33;:::i;:::-;15257:7;-1:-1:-1;15311:2:1;15296:18;;15283:32;;-1:-1:-1;15362:2:1;15347:18;;15334:32;;-1:-1:-1;15417:3:1;15402:19;;15389:33;-1:-1:-1;;;;;15434:30:1;;15431:50;;;15477:1;15474;15467:12;15431:50;15500:49;15541:7;15532:6;15521:9;15517:22;15500:49;:::i;:::-;15490:59;;;14821:734;;;;;;;;:::o;15560:129::-;-1:-1:-1;;;;;15638:5:1;15634:30;15627:5;15624:41;15614:69;;15679:1;15676;15669:12;15694:245;15752:6;15805:2;15793:9;15784:7;15780:23;15776:32;15773:52;;;15821:1;15818;15811:12;15773:52;15860:9;15847:23;15879:30;15903:5;15879:30;:::i;15944:523::-;16030:6;16038;16046;16099:2;16087:9;16078:7;16074:23;16070:32;16067:52;;;16115:1;16112;16105:12;16067:52;16154:9;16141:23;16173:31;16198:5;16173:31;:::i;:::-;16223:5;-1:-1:-1;16275:2:1;16260:18;;16247:32;;-1:-1:-1;16330:2:1;16315:18;;16302:32;-1:-1:-1;;;;;16346:30:1;;16343:50;;;16389:1;16386;16379:12;16343:50;16412:49;16453:7;16444:6;16433:9;16429:22;16412:49;:::i;:::-;16402:59;;;15944:523;;;;;:::o;16472:395::-;16563:8;16573:6;16627:3;16620:4;16612:6;16608:17;16604:27;16594:55;;16645:1;16642;16635:12;16594:55;-1:-1:-1;16668:20:1;;-1:-1:-1;;;;;16700:30:1;;16697:50;;;16743:1;16740;16733:12;16697:50;16780:4;16772:6;16768:17;16756:29;;16840:3;16833:4;16823:6;16820:1;16816:14;16808:6;16804:27;16800:38;16797:47;16794:67;;;16857:1;16854;16847:12;16872:504;16997:6;17005;17058:2;17046:9;17037:7;17033:23;17029:32;17026:52;;;17074:1;17071;17064:12;17026:52;17114:9;17101:23;-1:-1:-1;;;;;17139:6:1;17136:30;17133:50;;;17179:1;17176;17169:12;17133:50;17218:98;17308:7;17299:6;17288:9;17284:22;17218:98;:::i;:::-;17335:8;;17192:124;;-1:-1:-1;16872:504:1;-1:-1:-1;;;;16872:504:1:o;17381:184::-;17439:6;17492:2;17480:9;17471:7;17467:23;17463:32;17460:52;;;17508:1;17505;17498:12;17460:52;17531:28;17549:9;17531:28;:::i;17570:553::-;17656:6;17664;17672;17680;17733:2;17721:9;17712:7;17708:23;17704:32;17701:52;;;17749:1;17746;17739:12;17701:52;17772:28;17790:9;17772:28;:::i;:::-;17762:38;;17819:37;17852:2;17841:9;17837:18;17819:37;:::i;:::-;17809:47;;17907:2;17896:9;17892:18;17879:32;-1:-1:-1;;;;;17926:6:1;17923:30;17920:50;;;17966:1;17963;17956:12;17920:50;18005:58;18055:7;18046:6;18035:9;18031:22;18005:58;:::i;:::-;17570:553;;;;-1:-1:-1;18082:8:1;-1:-1:-1;;;;17570:553:1:o;18631:657::-;18769:6;18777;18785;18829:9;18820:7;18816:23;18859:3;18855:2;18851:12;18848:32;;;18876:1;18873;18866:12;18848:32;18916:9;18903:23;-1:-1:-1;;;;;18941:6:1;18938:30;18935:50;;;18981:1;18978;18971:12;18935:50;19004:69;19065:7;19056:6;19045:9;19041:22;19004:69;:::i;:::-;18994:79;-1:-1:-1;;19107:2:1;-1:-1:-1;;19089:16:1;;19085:25;19082:45;;;19123:1;19120;19113:12;19082:45;;19161:2;19150:9;19146:18;19136:28;;19214:2;19203:9;19199:18;19186:32;19227:31;19252:5;19227:31;:::i;:::-;19277:5;19267:15;;;18631:657;;;;;:::o;19293:613::-;19537:4;19579:3;19568:9;19564:19;19556:27;;19616:6;19610:13;19599:9;19592:32;-1:-1:-1;;;;;19684:4:1;19676:6;19672:17;19666:24;19662:49;19655:4;19644:9;19640:20;19633:79;19759:4;19751:6;19747:17;19741:24;19774:62;19830:4;19819:9;19815:20;19801:12;2833;;2821:25;;2895:4;2884:16;;;2878:23;2862:14;;2855:47;2759:149;19774:62;-1:-1:-1;2833:12:1;;19895:3;19880:19;;2821:25;2895:4;2884:16;;2878:23;2862:14;;;2855:47;19845:55;2759:149;19911:734;20022:6;20030;20038;20046;20054;20062;20070;20123:3;20111:9;20102:7;20098:23;20094:33;20091:53;;;20140:1;20137;20130:12;20091:53;20179:9;20166:23;20198:31;20223:5;20198:31;:::i;:::-;20248:5;-1:-1:-1;20305:2:1;20290:18;;20277:32;20318:33;20277:32;20318:33;:::i;:::-;20370:7;-1:-1:-1;20424:2:1;20409:18;;20396:32;;-1:-1:-1;20475:2:1;20460:18;;20447:32;;-1:-1:-1;20498:37:1;20530:3;20515:19;;20498:37;:::i;:::-;20488:47;;20582:3;20571:9;20567:19;20554:33;20544:43;;20634:3;20623:9;20619:19;20606:33;20596:43;;19911:734;;;;;;;;;;:::o;20650:388::-;20718:6;20726;20779:2;20767:9;20758:7;20754:23;20750:32;20747:52;;;20795:1;20792;20785:12;20747:52;20834:9;20821:23;20853:31;20878:5;20853:31;:::i;:::-;20903:5;-1:-1:-1;20960:2:1;20945:18;;20932:32;20973:33;20932:32;20973:33;:::i;21043:872::-;21172:6;21180;21188;21196;21204;21212;21220;21228;21236;21289:3;21277:9;21268:7;21264:23;21260:33;21257:53;;;21306:1;21303;21296:12;21257:53;21345:9;21332:23;21364:31;21389:5;21364:31;:::i;:::-;21414:5;-1:-1:-1;21471:2:1;21456:18;;21443:32;21484:33;21443:32;21484:33;:::i;:::-;21536:7;-1:-1:-1;21590:2:1;21575:18;;21562:32;;-1:-1:-1;21641:2:1;21626:18;;21613:32;;-1:-1:-1;21692:3:1;21677:19;;21664:33;;-1:-1:-1;21744:3:1;21729:19;;21716:33;;-1:-1:-1;21768:37:1;21800:3;21785:19;;21768:37;:::i;:::-;21758:47;;21852:3;21841:9;21837:19;21824:33;21814:43;;21904:3;21893:9;21889:19;21876:33;21866:43;;21043:872;;;;;;;;;;;:::o;22240:320::-;22316:6;22324;22332;22385:2;22373:9;22364:7;22360:23;22356:32;22353:52;;;22401:1;22398;22391:12;22353:52;22437:9;22424:23;22414:33;;22494:2;22483:9;22479:18;22466:32;22456:42;;22517:37;22550:2;22539:9;22535:18;22517:37;:::i;:::-;22507:47;;22240:320;;;;;:::o;22818:236::-;22903:6;22956:2;22944:9;22935:7;22931:23;22927:32;22924:52;;;22972:1;22969;22962:12;22924:52;22995:53;23040:7;23029:9;22995:53;:::i;23742:127::-;23803:10;23798:3;23794:20;23791:1;23784:31;23834:4;23831:1;23824:15;23858:4;23855:1;23848:15;23874:125;23939:9;;;23960:10;;;23957:36;;;23973:18;;:::i;24004:380::-;24083:1;24079:12;;;;24126;;;24147:61;;24201:4;24193:6;24189:17;24179:27;;24147:61;24254:2;24246:6;24243:14;24223:18;24220:38;24217:161;;24300:10;24295:3;24291:20;24288:1;24281:31;24335:4;24332:1;24325:15;24363:4;24360:1;24353:15;24389:338;24570:19;;;24614:2;24605:12;;24598:28;;;;24682:3;24660:16;-1:-1:-1;;;;;;24656:36:1;24651:2;24642:12;;24635:58;24718:2;24709:12;;24389:338::o;25391:663::-;25706:25;;;-1:-1:-1;;;;;25805:15:1;;;25800:2;25785:18;;25778:43;25857:15;;;;25852:2;25837:18;;25830:43;25904:2;25889:18;;25882:34;;;;25947:3;25932:19;;25925:35;25758:3;25976:19;;25969:35;;;;26035:3;26020:19;;26013:35;25693:3;25678:19;;25391:663::o;27769:127::-;27830:10;27825:3;27821:20;27818:1;27811:31;27861:4;27858:1;27851:15;27885:4;27882:1;27875:15;27901:336;28006:4;28064:11;28051:25;28158:2;28154:7;28143:8;28127:14;28123:29;28119:43;28099:18;28095:68;28085:96;;28177:1;28174;28167:12;28085:96;28198:33;;;;;27901:336;-1:-1:-1;;27901:336:1:o;28242:521::-;28319:4;28325:6;28385:11;28372:25;28479:2;28475:7;28464:8;28448:14;28444:29;28440:43;28420:18;28416:68;28406:96;;28498:1;28495;28488:12;28406:96;28525:33;;28577:20;;;-1:-1:-1;;;;;;28609:30:1;;28606:50;;;28652:1;28649;28642:12;28606:50;28685:4;28673:17;;-1:-1:-1;28716:14:1;28712:27;;;28702:38;;28699:58;;;28753:1;28750;28743:12;28768:184;28826:6;28879:2;28867:9;28858:7;28854:23;28850:32;28847:52;;;28895:1;28892;28885:12;28847:52;28918:28;28936:9;28918:28;:::i;29082:517::-;29183:2;29178:3;29175:11;29172:421;;;29219:5;29216:1;29209:16;29263:4;29260:1;29250:18;29333:2;29321:10;29317:19;29314:1;29310:27;29304:4;29300:38;29369:4;29357:10;29354:20;29351:47;;;-1:-1:-1;29392:4:1;29351:47;29447:2;29442:3;29438:12;29435:1;29431:20;29425:4;29421:31;29411:41;;29502:81;29520:2;29513:5;29510:13;29502:81;;;29579:1;29565:16;;29546:1;29535:13;29502:81;;29775:1194;-1:-1:-1;;;;;29892:3:1;29889:27;29886:53;;;29919:18;;:::i;:::-;29948:93;30037:3;29997:38;30029:4;30023:11;29997:38;:::i;:::-;29991:4;29948:93;:::i;:::-;30067:1;30092:2;30087:3;30084:11;30109:1;30104:607;;;;30755:1;30772:3;30769:93;;;-1:-1:-1;30828:19:1;;;30815:33;30769:93;-1:-1:-1;;29732:1:1;29728:11;;;29724:24;29720:29;29710:40;29756:1;29752:11;;;29707:57;30875:78;;30077:886;;30104:607;29029:1;29022:14;;;29066:4;29053:18;;-1:-1:-1;;30140:17:1;;;30254:229;30268:7;30265:1;30262:14;30254:229;;;30357:19;;;30344:33;30329:49;;30464:4;30449:20;;;;30417:1;30405:14;;;;30284:12;30254:229;;;30258:3;30511;30502:7;30499:16;30496:159;;;30635:1;30631:6;30625:3;30619;30616:1;30612:11;30608:21;30604:34;30600:39;30587:9;30582:3;30578:19;30565:33;30561:79;30553:6;30546:95;30496:159;;;30698:1;30692:3;30689:1;30685:11;30681:19;30675:4;30668:33;30077:886;;29775:1194;;;:::o;30974:266::-;31062:6;31057:3;31050:19;31114:6;31107:5;31100:4;31095:3;31091:14;31078:43;-1:-1:-1;31166:1:1;31141:16;;;31159:4;31137:27;;;31130:38;;;;31222:2;31201:15;;;-1:-1:-1;;31197:29:1;31188:39;;;31184:50;;30974:266::o;31245:1774::-;31502:2;31554:21;;;31527:18;;;31610:22;;;31473:4;;31651:2;31669:18;;;31733:1;31729:14;;;31714:30;;31710:39;;31772:6;31473:4;31806:1184;31820:6;31817:1;31814:13;31806:1184;;;31885:22;;;-1:-1:-1;;31881:36:1;31869:49;;31957:20;;32032:14;32028:27;;;-1:-1:-1;;32024:41:1;32000:66;;31990:94;;32080:1;32077;32070:12;31990:94;32110:31;;32164:4;32226:10;32200:24;32110:31;32200:24;:::i;:::-;32196:41;32188:6;32181:57;32314:6;32279:33;32308:2;32301:5;32297:14;32279:33;:::i;:::-;32275:46;32270:2;32262:6;32258:15;32251:71;32387:2;32380:5;32376:14;32363:28;32476:2;32472:7;32464:5;32448:14;32444:26;32440:40;32418:20;32414:67;32404:95;;32495:1;32492;32485:12;32404:95;32527:32;;;32635:16;;;;-1:-1:-1;32586:21:1;-1:-1:-1;;;;;32667:30:1;;32664:50;;;32710:1;32707;32700:12;32664:50;32763:6;32747:14;32743:27;32734:7;32730:41;32727:61;;;32784:1;32781;32774:12;32727:61;32825:2;32820;32812:6;32808:15;32801:27;32851:59;32906:2;32898:6;32894:15;32886:6;32877:7;32851:59;:::i;:::-;32968:12;;;;32841:69;-1:-1:-1;;;32933:15:1;;;;-1:-1:-1;31842:1:1;31835:9;31806:1184;;;-1:-1:-1;33007:6:1;;31245:1774;-1:-1:-1;;;;;;;;31245:1774:1:o;33024:331::-;33129:9;33140;33182:8;33170:10;33167:24;33164:44;;;33204:1;33201;33194:12;33164:44;33233:6;33223:8;33220:20;33217:40;;;33253:1;33250;33243:12;33217:40;-1:-1:-1;;33279:23:1;;;33324:25;;;;;-1:-1:-1;33024:331:1:o;33360:476::-;33551:3;33589:6;33583:13;33605:66;33664:6;33659:3;33652:4;33644:6;33640:17;33605:66;:::i;:::-;33693:16;;33746:6;33738;33693:16;33718:35;33810:1;33772:18;;33799:13;;;-1:-1:-1;33772:18:1;;33360:476;-1:-1:-1;;;33360:476:1:o;33841:244::-;33998:2;33987:9;33980:21;33961:4;34018:61;34075:2;34064:9;34060:18;34052:6;34044;34018:61;:::i;34090:331::-;34189:4;34247:11;34234:25;34341:3;34337:8;34326;34310:14;34306:29;34302:44;34282:18;34278:69;34268:97;;34361:1;34358;34351:12;34426:992;34804:10;34777:25;34795:6;34777:25;:::i;:::-;34773:42;34762:9;34755:61;34879:4;34871:6;34867:17;34854:31;34847:4;34836:9;34832:20;34825:61;34736:4;34933;34925:6;34921:17;34908:31;34948:30;34972:5;34948:30;:::i;:::-;-1:-1:-1;;;;;35020:5:1;35016:30;35009:4;34998:9;34994:20;34987:60;;35083:6;35078:2;35067:9;35063:18;35056:34;35127:3;35121;35110:9;35106:19;35099:32;35154:62;35211:3;35200:9;35196:19;35188:6;35180;35154:62;:::i;:::-;-1:-1:-1;;;;;35253:32:1;;35273:3;35232:19;;35225:61;35323:22;;;35317:3;35302:19;;35295:51;35363:49;35327:6;35397;35389;35363:49;:::i;:::-;35355:57;34426:992;-1:-1:-1;;;;;;;;;;34426:992:1:o;35423:647::-;35502:6;35555:2;35543:9;35534:7;35530:23;35526:32;35523:52;;;35571:1;35568;35561:12;35523:52;35604:9;35598:16;-1:-1:-1;;;;;35629:6:1;35626:30;35623:50;;;35669:1;35666;35659:12;35623:50;35692:22;;35745:4;35737:13;;35733:27;-1:-1:-1;35723:55:1;;35774:1;35771;35764:12;35723:55;35803:2;35797:9;35828:48;35844:31;35872:2;35844:31;:::i;35828:48::-;35899:2;35892:5;35885:17;35939:7;35934:2;35929;35925;35921:11;35917:20;35914:33;35911:53;;;35960:1;35957;35950:12;35911:53;35973:67;36037:2;36032;36025:5;36021:14;36016:2;36012;36008:11;35973:67;:::i;36075:348::-;36164:6;36217:2;36205:9;36196:7;36192:23;36188:32;36185:52;;;36233:1;36230;36223:12;36185:52;36259:22;;:::i;:::-;36317:9;36304:23;36297:5;36290:38;36388:2;36377:9;36373:18;36360:32;36355:2;36348:5;36344:14;36337:56;36412:5;36402:15;;;36075:348;;;;:::o;37174:245::-;37241:6;37294:2;37282:9;37273:7;37269:23;37265:32;37262:52;;;37310:1;37307;37300:12;37262:52;37342:9;37336:16;37361:28;37383:5;37361:28;:::i;37424:217::-;37464:1;37490;37480:132;;37534:10;37529:3;37525:20;37522:1;37515:31;37569:4;37566:1;37559:15;37597:4;37594:1;37587:15;37480:132;-1:-1:-1;37626:9:1;;37424:217::o;37843:478::-;38110:1;38106;38101:3;38097:11;38093:19;38085:6;38081:32;38070:9;38063:51;38150:6;38145:2;38134:9;38130:18;38123:34;38205:6;38197;38193:19;38188:2;38177:9;38173:18;38166:47;38249:3;38244:2;38233:9;38229:18;38222:31;38044:4;38270:45;38310:3;38299:9;38295:19;38287:6;38270:45;:::i;39313:889::-;39536:2;39525:9;39518:21;39594:10;39585:6;39579:13;39575:30;39570:2;39559:9;39555:18;39548:58;39660:4;39652:6;39648:17;39642:24;39637:2;39626:9;39622:18;39615:52;39499:4;39714:2;39706:6;39702:15;39696:22;39755:4;39749:3;39738:9;39734:19;39727:33;39783:51;39829:3;39818:9;39814:19;39800:12;39783:51;:::i;:::-;39769:65;;39883:2;39875:6;39871:15;39865:22;39957:2;39953:7;39941:9;39933:6;39929:22;39925:36;39918:4;39907:9;39903:20;39896:66;39985:40;40018:6;40002:14;39985:40;:::i;:::-;40094:3;40082:16;;;;40076:23;40069:31;40062:39;40056:3;40041:19;;40034:68;-1:-1:-1;;;;;;;;40163:32:1;;;;40156:4;40141:20;;;40134:62;39971:54;39313:889::o;40207:284::-;40277:5;40325:4;40313:9;40308:3;40304:19;40300:30;40297:50;;;40343:1;40340;40333:12;40297:50;40365:22;;:::i;:::-;40356:31;;40416:9;40410:16;40403:5;40396:31;40480:2;40469:9;40465:18;40459:25;40454:2;40447:5;40443:14;40436:49;40207:284;;;;:::o;40496:259::-;40596:6;40649:2;40637:9;40628:7;40624:23;40620:32;40617:52;;;40665:1;40662;40655:12;40617:52;40688:61;40741:7;40730:9;40688:61;:::i;40760:168::-;40833:9;;;40864;;40881:15;;;40875:22;;40861:37;40851:71;;40902:18;;:::i;40933:318::-;-1:-1:-1;;;;;;41053:19:1;;41124:11;;;;41155:1;41147:10;;41144:101;;;41232:2;41226;41219:3;41216:1;41212:11;41209:1;41205:19;41201:28;41197:2;41193:37;41189:46;41180:55;;41144:101;;;40933:318;;;;:::o;41256:683::-;41360:6;41413:3;41401:9;41392:7;41388:23;41384:33;41381:53;;;41430:1;41427;41420:12;41381:53;41463:2;41457:9;41505:4;41497:6;41493:17;41576:6;41564:10;41561:22;-1:-1:-1;;;;;41528:10:1;41525:34;41522:62;41519:88;;;41587:18;;:::i;:::-;41623:2;41616:22;41662:16;;41647:32;;41722:2;41707:18;;41701:25;41735:30;41701:25;41735:30;:::i;:::-;41793:2;41781:15;;41774:30;41837:70;41899:7;41894:2;41879:18;;41837:70;:::i;:::-;41832:2;41820:15;;41813:95;41824:6;41256:683;-1:-1:-1;;;41256:683:1:o;42239:532::-;42480:6;42475:3;42468:19;-1:-1:-1;;;;;42543:3:1;42539:28;42530:6;42525:3;42521:16;42517:51;42512:2;42507:3;42503:12;42496:73;42599:6;42594:2;42589:3;42585:12;42578:28;42450:3;42635:6;42629:13;42651:73;42717:6;42712:2;42707:3;42703:12;42698:2;42690:6;42686:15;42651:73;:::i;:::-;42744:16;;;;42762:2;42740:25;;42239:532;-1:-1:-1;;;;;42239:532:1:o;43584:255::-;43704:19;;43743:2;43735:11;;43732:101;;;-1:-1:-1;;43804:2:1;43800:12;;;43797:1;43793:20;43789:33;43778:45;43584:255;;;;:::o;43844:331::-;-1:-1:-1;;;;;;43964:19:1;;44048:11;;;;44079:1;44071:10;;44068:101;;;44140:1;44136:11;;;;44133:1;44129:19;44125:28;;;44117:37;44113:46;;;;43844:331;-1:-1:-1;;43844:331:1:o;44180:568::-;-1:-1:-1;;;;;44445:3:1;44441:28;44432:6;44427:3;44423:16;44419:51;44414:3;44407:64;44531:10;44526:3;44522:20;44513:6;44508:3;44504:16;44500:43;44496:1;44491:3;44487:11;44480:64;44574:6;44569:2;44564:3;44560:12;44553:28;44389:3;44610:6;44604:13;44626:75;44694:6;44689:2;44684:3;44680:12;44673:4;44665:6;44661:17;44626:75;:::i;:::-;44721:16;;;;44739:2;44717:25;;44180:568;-1:-1:-1;;;;;44180:568:1:o;46464:1343::-;46590:3;46584:10;-1:-1:-1;;;;;46609:6:1;46606:30;46603:56;;;46639:18;;:::i;:::-;46668:96;46757:6;46717:38;46749:4;46743:11;46717:38;:::i;:::-;46711:4;46668:96;:::i;:::-;46819:4;;46876:2;46865:14;;46893:1;46888:662;;;;47594:1;47611:6;47608:89;;;-1:-1:-1;47663:19:1;;;47657:26;47608:89;-1:-1:-1;;29732:1:1;29728:11;;;29724:24;29720:29;29710:40;29756:1;29752:11;;;29707:57;47710:81;;46858:943;;46888:662;29029:1;29022:14;;;29066:4;29053:18;;-1:-1:-1;;46924:20:1;;;47041:236;47055:7;47052:1;47049:14;47041:236;;;47144:19;;;47138:26;47123:42;;47236:27;;;;47204:1;47192:14;;;;47071:19;;47041:236;;;47045:3;47305:6;47296:7;47293:19;47290:201;;;47366:19;;;47360:26;-1:-1:-1;;47449:1:1;47445:14;;;47461:3;47441:24;47437:37;47433:42;47418:58;47403:74;;47290:201;;;47537:1;47528:6;47525:1;47521:14;47517:22;47511:4;47504:36;46858:943;;;;;46464:1343;;:::o;47812:127::-;47873:10;47868:3;47864:20;47861:1;47854:31;47904:4;47901:1;47894:15;47928:4;47925:1;47918:15;48749:251;48819:6;48872:2;48860:9;48851:7;48847:23;48843:32;48840:52;;;48888:1;48885;48878:12;48840:52;48920:9;48914:16;48939:31;48964:5;48939:31;:::i;49365:288::-;49540:6;49529:9;49522:25;49583:2;49578;49567:9;49563:18;49556:30;49503:4;49603:44;49643:2;49632:9;49628:18;49620:6;49603:44;:::i;49658:287::-;49787:3;49825:6;49819:13;49841:66;49900:6;49895:3;49888:4;49880:6;49876:17;49841:66;:::i;49950:184::-;50020:6;50073:2;50061:9;50052:7;50048:23;50044:32;50041:52;;;50089:1;50086;50079:12;50041:52;-1:-1:-1;50112:16:1;;49950:184;-1:-1:-1;49950:184:1:o
Swarm Source
ipfs://2cbc8a4f9fd16988bd0a9095653f95f32a504363376aae6eabeea052d198d2f4
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.