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:
FraxOFTUpgradeable
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/FraxOFTUpgradeable.sol
contract FraxOFTUpgradeable is OFTUpgradeable, EIP3009Module, PermitModule {
constructor(address _lzEndpoint) OFTUpgradeable(_lzEndpoint) {
_disableInitializers();
}
function version() public pure returns (string memory) {
return "1.1.0";
}
//==============================================================================
// Admin
//==============================================================================
/// @dev This method is called specifically when deploying a new OFT
function initialize(string memory _name, string memory _symbol, address _delegate) external reinitializer(3) {
__EIP712_init(_name, version());
__OFT_init(_name, _symbol, _delegate);
__Ownable_init();
_transferOwnership(_delegate);
}
/// @dev This method is called specifically when upgrading an existing OFT
function initializeV110() external reinitializer(3) {
__EIP712_init(name(), version());
}
//==============================================================================
// Helper view
//==============================================================================
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":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_delegate","type":"address"}],"name":"initialize","outputs":[],"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":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"nextNonce","outputs":[{"internalType":"uint64","name":"nonce","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"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":"view","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
60c060405234801562000010575f80fd5b506040516200501a3803806200501a833981016040819052620000339162000134565b6001600160a01b038116608052806012816200005160068362000177565b6200005e90600a62000292565b60a052506200006f91505062000076565b50620002a2565b5f54610100900460ff1615620000e25760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b5f5460ff9081161462000132575f805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b5f6020828403121562000145575f80fd5b81516001600160a01b03811681146200015c575f80fd5b9392505050565b634e487b7160e01b5f52601160045260245ffd5b60ff828116828216039081111562000193576200019362000163565b92915050565b600181815b80851115620001d957815f1904821115620001bd57620001bd62000163565b80851615620001cb57918102915b93841c93908002906200019e565b509250929050565b5f82620001f15750600162000193565b81620001ff57505f62000193565b8160018114620002185760028114620002235762000243565b600191505062000193565b60ff84111562000237576200023762000163565b50506001821b62000193565b5060208310610133831016604e8410600b841016171562000268575081810a62000193565b62000274838362000199565b805f19048211156200028a576200028a62000163565b029392505050565b5f6200015c60ff841683620001e1565b60805160a051614d106200030a5f395f818161088d01528181612217015281816127ed015261285f01525f818161072901528181610e8401528181611cc301528181612317015281816124de015281816128df015281816130f601526131ad0152614d105ff3fe6080604052600436106103b3575f3560e01c8063857749b0116101e9578063bd815db011610108578063dd62ed3e1161009d578063f01630231161006d578063f016302314610b7a578063f2fde38b14610bae578063fc0c546a14610673578063ff7bd03d14610bcd575f80fd5b8063dd62ed3e14610acd578063e3ee160e14610aec578063e94a010214610b0b578063ef55bec614610b5b575f80fd5b8063cf092995116100d8578063cf09299514610a5d578063d045a0dc14610a7c578063d424388514610a8f578063d505accf14610aae575f80fd5b8063bd815db0146109eb578063c0779988146109fe578063c7c7f5b314610a1d578063ca5eb5e114610a3e575f80fd5b8063a9059cbb1161017e578063b92d0eff1161014e578063b92d0eff14610673578063b98bd07014610970578063bb0b6a531461098f578063bc70b354146109cc575f80fd5b8063a9059cbb146108ff578063b3a5abeb1461091e578063b731ea0a1461093d578063b7b7289914610951575f80fd5b8063963efcaa116101b9578063963efcaa1461087c5780639f68b964146108af5780639fd5a6cf146108c1578063a457c2d7146108e0575f80fd5b8063857749b01461081957806388b7ab631461082c5780638da5cb5b1461084b57806395d89b4114610868575f80fd5b80633644e515116102d55780635a0dfe4d1161026a578063715018a61161023a578063715018a61461079e5780637d25a05e146107b25780637ecebe00146107d357806384b0196e146107f2575f80fd5b80635a0dfe4d146106d75780635e280f11146107185780636fc1b31e1461074b57806370a082311461076a575f80fd5b806352ae2879116102a557806352ae28791461067357806354fd4d50146106855780635535d461146106995780635a049a70146106b8575f80fd5b80633644e515146106005780633714fffa1461061457806339509351146106285780633b6f743b14610647575f80fd5b8063134d4f251161034b5780631f5e13341161031b5780631f5e13341461058d57806323b872dd146105a1578063313ce567146105c05780633400288b146105e1575f80fd5b8063134d4f2514610502578063156a0d0f1461052957806317442b701461054f57806318160ddd1461056f575f80fd5b80630d35b415116103865780630d35b4151461045e5780630e78842c1461048c578063111ecdad146104c357806313137d65146104ef575f80fd5b8063056d62de146103b757806306fdde03146103ed578063077f224a1461040e578063095ea7b31461042f575b5f80fd5b3480156103c2575f80fd5b506103d66103d1366004613866565b610bec565b6040516103e49291906138f4565b60405180910390f35b3480156103f8575f80fd5b50610401610c05565b6040516103e49190613918565b348015610419575f80fd5b5061042d610428366004613a22565b610c95565b005b34801561043a575f80fd5b5061044e610449366004613a94565b610d60565b60405190151581526020016103e4565b348015610469575f80fd5b5061047d610478366004613abe565b610d79565b6040516103e493929190613aef565b348015610497575f80fd5b506104ab6104a6366004613b86565b610e44565b6040516001600160401b0390911681526020016103e4565b3480156104ce575f80fd5b506104d7610e4e565b6040516001600160a01b0390911681526020016103e4565b61042d6104fd366004613bea565b610e82565b34801561050d575f80fd5b50610516600281565b60405161ffff90911681526020016103e4565b348015610534575f80fd5b506040805162b9270b60e21b815260016020820152016103e4565b34801561055a575f80fd5b506040805160018082526020820152016103e4565b34801561057a575f80fd5b506067545b6040519081526020016103e4565b348015610598575f80fd5b50610516600181565b3480156105ac575f80fd5b5061044e6105bb366004613c82565b610f3d565b3480156105cb575f80fd5b5060125b60405160ff90911681526020016103e4565b3480156105ec575f80fd5b5061042d6105fb366004613cd8565b610f62565b34801561060b575f80fd5b5061057f610fcd565b34801561061f575f80fd5b5061042d610fdb565b348015610633575f80fd5b5061044e610642366004613a94565b611080565b348015610652575f80fd5b50610666610661366004613cff565b6110a1565b6040516103e49190613d4d565b34801561067e575f80fd5b50306104d7565b348015610690575f80fd5b50610401611105565b3480156106a4575f80fd5b506104016106b3366004613d75565b611124565b3480156106c3575f80fd5b5061042d6106d2366004613db6565b6111fc565b3480156106e2575f80fd5b5061044e6106f1366004613cd8565b63ffffffff919091165f9081525f80516020614c7b83398151915260205260409020541490565b348015610723575f80fd5b506104d77f000000000000000000000000000000000000000000000000000000000000000081565b348015610756575f80fd5b5061042d610765366004613e02565b611231565b348015610775575f80fd5b5061057f610784366004613e02565b6001600160a01b03165f9081526065602052604090205490565b3480156107a9575f80fd5b5061042d6112ad565b3480156107bd575f80fd5b506104ab6107cc366004613cd8565b5f92915050565b3480156107de575f80fd5b5061057f6107ed366004613e02565b6112c0565b3480156107fd575f80fd5b506108066112fe565b6040516103e49796959493929190613e1d565b348015610824575f80fd5b5060066105cf565b348015610837575f80fd5b5061042d610846366004613eb4565b6113a7565b348015610856575f80fd5b506033546001600160a01b03166104d7565b348015610873575f80fd5b5061040161149f565b348015610887575f80fd5b5061057f7f000000000000000000000000000000000000000000000000000000000000000081565b3480156108ba575f80fd5b505f61044e565b3480156108cc575f80fd5b5061042d6108db366004613f36565b6114ae565b3480156108eb575f80fd5b5061044e6108fa366004613a94565b611577565b34801561090a575f80fd5b5061044e610919366004613a94565b6115fc565b348015610929575f80fd5b5061057f610938366004613fba565b611609565b348015610948575f80fd5b506104d7611613565b34801561095c575f80fd5b5061042d61096b366004613fd5565b61163b565b34801561097b575f80fd5b5061042d61098a366004614069565b6116fb565b34801561099a575f80fd5b5061057f6109a93660046140a7565b63ffffffff165f9081525f80516020614c7b833981519152602052604090205490565b3480156109d7575f80fd5b506104016109e63660046140c0565b611877565b61042d6109f9366004614069565b611a0f565b348015610a09575f80fd5b5061057f610a18366004613b86565b611b9b565b610a30610a2b36600461411c565b611ba5565b6040516103e4929190614179565b348015610a49575f80fd5b5061042d610a58366004613e02565b611c9c565b348015610a68575f80fd5b5061042d610a77366004613eb4565b611d16565b61042d610a8a366004613bea565b611da3565b348015610a9a575f80fd5b5061042d610aa9366004613e02565b611dd2565b348015610ab9575f80fd5b5061042d610ac83660046141ca565b611e46565b348015610ad8575f80fd5b5061057f610ae7366004614233565b611e76565b348015610af7575f80fd5b5061042d610b0636600461425f565b611ea0565b348015610b16575f80fd5b5061044e610b25366004613a94565b6001600160a01b03919091165f9081525f80516020614c9b83398151915260209081526040808320938352929052205460ff1690565b348015610b66575f80fd5b5061042d610b7536600461425f565b611edd565b348015610b85575f80fd5b50610b99610b943660046142db565b611f0f565b604080519283526020830191909152016103e4565b348015610bb9575f80fd5b5061042d610bc8366004613e02565b611f29565b348015610bd8575f80fd5b5061044e610be736600461430d565b611fa2565b606080610bf98484611fbf565b915091505b9250929050565b606060688054610c1490614327565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4090614327565b8015610c8b5780601f10610c6257610100808354040283529160200191610c8b565b820191905f5260205f20905b815481529060010190602001808311610c6e57829003601f168201915b5050505050905090565b5f54600390610100900460ff16158015610cb557505f5460ff8083169116105b610cda5760405162461bcd60e51b8152600401610cd190614359565b60405180910390fd5b5f805461ffff191660ff831617610100179055610cfe84610cf9611105565b612100565b610d0984848461210e565b610d1161214c565b610d1a8261217a565b5f805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b5f33610d6d8185856121cb565b60019150505b92915050565b604080518082019091525f80825260208201526060610da960405180604001604052805f81526020015f81525090565b6040805180820182525f8082526001600160401b03602080840182905284518381529081019094529195509182610e02565b604080518082019091525f815260606020820152815260200190600190039081610ddb5790505b5093505f80610e26604089013560608a0135610e2160208c018c6140a7565b6121d6565b60408051808201909152918252602082015296989597505050505050565b5f610d7382612211565b5f807f41db8a78b0206aba5c54bcbfc2bda0d84082a84eb88e680379a57b9e9f653c005b546001600160a01b031692915050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163314610ecd576040516391ac5e4f60e01b8152336004820152602401610cd1565b60208701803590610ee790610ee2908a6140a7565b61223c565b14610f2557610ef960208801886140a7565b60405163309afaf360e21b815263ffffffff909116600482015260208801356024820152604401610cd1565b610f3487878787878787612285565b50505050505050565b5f33610f4a8582856123e3565b610f5585858561245b565b60019150505b9392505050565b610f6a612466565b63ffffffff82165f8181525f80516020614c7b833981519152602081815260409283902085905582519384528301849052917f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b91015b60405180910390a1505050565b5f610fd66124c0565b905090565b5f54600390610100900460ff16158015610ffb57505f5460ff8083169116105b6110175760405162461bcd60e51b8152600401610cd190614359565b5f805461ffff191660ff83161761010017905561103d611035610c05565b610cf9611105565b5f805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b5f33610d6d8185856110928383611e76565b61109c91906143bb565b6121cb565b604080518082019091525f80825260208201525f6110cf60408501356060860135610e2160208801886140a7565b9150505f806110de8684611fbf565b90925090506110fb6110f360208801886140a7565b8383886124c9565b9695505050505050565b6040805180820190915260058152640312e312e360dc1b602082015290565b63ffffffff82165f9081527f8d2bda5d9f6ffb5796910376005392955773acee5548d0fcdb10e7c264ea00006020818152604080842061ffff861685529091529091208054606092919061117790614327565b80601f01602080910402602001604051908101604052809291908181526020018280546111a390614327565b80156111ee5780601f106111c5576101008083540402835291602001916111ee565b820191905f5260205f20905b8154815290600101906020018083116111d157829003601f168201915b505050505091505092915050565b61122a8585848487604051602001611216939291906143ce565b60405160208183030381529060405261163b565b5050505050565b611239612466565b7f41db8a78b0206aba5c54bcbfc2bda0d84082a84eb88e680379a57b9e9f653c0080546001600160a01b0319166001600160a01b03831690811782556040519081527ff0be4f1e87349231d80c36b33f9e8639658eeaf474014dee15a3e6a4d4414197906020015b60405180910390a15050565b6112b5612466565b6112be5f61217a565b565b6001600160a01b0381165f9081527fb39b43abb0b115e0a59dece28477e279ee5f8e2fd55fbe200557c3ab864a030060208190526040822054610f5b565b5f60608082808083815f80516020614cbb833981519152805490915015801561132957506001810154155b61136d5760405162461bcd60e51b81526020600482015260156024820152741152540dcc4c8e88155b9a5b9a5d1a585b1a5e9959605a1b6044820152606401610cd1565b6113756125a7565b61137d612667565b604080515f80825260208201909252600f60f81b9c939b5091995046985030975095509350915050565b6001600160a01b03861633146113e157604051637f54a22160e11b81523360048201526001600160a01b0387166024820152604401610cd1565b83421161140157604051632ce87eeb60e01b815260040160405180910390fd5b8242106114215760405163a899ef9360e01b815260040160405180910390fd5b61142b87836126a5565b61148a877fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de85f1b89898989898960405160200161146e97969594939291906143f1565b60405160208183030381529060405280519060200120836126f4565b6114948783612738565b610f3487878761245b565b606060698054610c1490614327565b814211156114fe5760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610cd1565b61156c857f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c987878761152f8b61279d565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810185905260e00161146e565b61122a8585856121cb565b5f33816115848286611e76565b9050838110156115e45760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610cd1565b6115f182868684036121cb565b506001949350505050565b5f33610d6d81858561245b565b5f610d73826127e7565b5f807fefb041d771d6daaa55702fff6eb740d63ba559a75d2d1d3e151c78ff2480b600610e72565b61164583836126a5565b604080517f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a159742960208201526001600160a01b038516918101919091526060810183905261169590849060800161146e565b6001600160a01b0383165f8181525f80516020614c9b83398151915260209081526040808320868452909152808220805460ff19166001179055518492917f1cdd46ff242716cdaa72d159d339a485b3438398348d68f09d7c8c0a59353d8191a3505050565b611703612466565b7f8d2bda5d9f6ffb5796910376005392955773acee5548d0fcdb10e7c264ea00005f5b82811015611845576117688484838181106117435761174361442d565b90506020028101906117559190614441565b61176390604081019061445f565b61281b565b83838281811061177a5761177a61442d565b905060200281019061178c9190614441565b61179a90604081019061445f565b835f8787868181106117ae576117ae61442d565b90506020028101906117c09190614441565b6117ce9060208101906140a7565b63ffffffff1663ffffffff1681526020019081526020015f205f8787868181106117fa576117fa61442d565b905060200281019061180c9190614441565b61181d9060408101906020016144a1565b61ffff16815260208101919091526040015f209161183c9190836144fe565b50600101611726565b507fbe4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b6748383604051610fc09291906145df565b63ffffffff84165f9081527f8d2bda5d9f6ffb5796910376005392955773acee5548d0fcdb10e7c264ea00006020818152604080842061ffff881685529091528220805460609391906118c990614327565b80601f01602080910402602001604051908101604052809291908181526020018280546118f590614327565b80156119405780601f1061191757610100808354040283529160200191611940565b820191905f5260205f20905b81548152906001019060200180831161192357829003601f168201915b5050505050905080515f0361198f5784848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250929550611a07945050505050565b5f8490036119a0579150611a079050565b600284106119ea576119b2858561281b565b806119c085600281896146be565b6040516020016119d2939291906146e5565b60405160208183030381529060405292505050611a07565b8484604051639a6d49cd60e01b8152600401610cd192919061470b565b949350505050565b5f5b81811015611b1e5736838383818110611a2c57611a2c61442d565b9050602002810190611a3e919061471e565b9050611a7c611a5060208301836140a7565b602083013563ffffffff919091165f9081525f80516020614c7b83398151915260205260409020541490565b611a865750611b16565b3063d045a0dc60c08301358360a0810135611aa561010083018361445f565b611ab6610100890160e08a01613e02565b611ac46101208a018a61445f565b6040518963ffffffff1660e01b8152600401611ae69796959493929190614733565b5f604051808303818588803b158015611afd575f80fd5b505af1158015611b0f573d5f803e3d5ffd5b5050505050505b600101611a11565b50336001600160a01b0316638e9e70996040518163ffffffff1660e01b81526004015f60405180830381865afa158015611b5a573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611b8191908101906147b8565b604051638351eea760e01b8152600401610cd19190613918565b5f610d738261285c565b611bad613813565b604080518082019091525f80825260208201525f80611be160408801356060890135611bdc60208b018b6140a7565b612892565b915091505f80611bf18984611fbf565b9092509050611c1d611c0660208b018b6140a7565b8383611c17368d90038d018d614820565b8b6128ae565b60408051808201909152858152602080820186905282519298509096503391907f85496b760a4b7f8d66384b9df21b381f5d1b1e79f229a47aaf4c232edc2fe59a90611c6b908d018d6140a7565b6040805163ffffffff909216825260208201899052810187905260600160405180910390a350505050935093915050565b611ca4612466565b60405163ca5eb5e160e01b81526001600160a01b0382811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063ca5eb5e1906024015f604051808303815f87803b158015611d04575f80fd5b505af115801561122a573d5f803e3d5ffd5b834211611d3657604051632ce87eeb60e01b815260040160405180910390fd5b824210611d565760405163a899ef9360e01b815260040160405180910390fd5b611d6087836126a5565b61148a877f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a22675f1b89898989898960405160200161146e97969594939291906143f1565b333014611dc35760405163029a949d60e31b815260040160405180910390fd5b610f3487878787878787610f25565b611dda612466565b7fefb041d771d6daaa55702fff6eb740d63ba559a75d2d1d3e151c78ff2480b60080546001600160a01b0319166001600160a01b03831690811782556040519081527fd48d879cef83a1c0bdda516f27b13ddb1b3f8bbac1c9e1511bb2a659c2427760906020016112a1565b610f3487878787868689604051602001611e62939291906143ce565b6040516020818303038152906040526114ae565b6001600160a01b039182165f90815260666020908152604080832093909416825291909152205490565b611ed289898989898988888b604051602001611ebe939291906143ce565b604051602081830303815290604052611d16565b505050505050505050565b611ed289898989898988888b604051602001611efb939291906143ce565b6040516020818303038152906040526113a7565b5f80611f1c8585856121d6565b915091505b935093915050565b611f31612466565b6001600160a01b038116611f965760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610cd1565b611f9f8161217a565b50565b5f60208201803590611fb8906109a990856140a7565b1492915050565b6060805f61201a8560200135611fd486612211565b611fe160a089018961445f565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506129b492505050565b90935090505f8161202c57600161202f565b60025b905061204f61204160208801886140a7565b826109e660808a018a61445f565b7f41db8a78b0206aba5c54bcbfc2bda0d84082a84eb88e680379a57b9e9f653c008054919450906001600160a01b0316156120f657805460405163043a78eb60e01b81526001600160a01b039091169063043a78eb906120b590889088906004016138f4565b602060405180830381865afa1580156120d0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120f49190614850565b505b5050509250929050565b61210a8282612a2e565b5050565b5f54610100900460ff166121345760405162461bcd60e51b8152600401610cd19061486b565b61213e8383612a85565b61214781612ab5565b505050565b5f54610100900460ff166121725760405162461bcd60e51b8152600401610cd19061486b565b6112be612ae4565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b612147838383612b13565b5f806121e18561285c565b915081905083811015611f21576040516371c4efed60e01b81526004810182905260248101859052604401610cd1565b5f610d737f0000000000000000000000000000000000000000000000000000000000000000836148b6565b63ffffffff81165f9081525f80516020614c7b8339815191526020819052604082205480610f5b5760405163f6ff4fb760e01b815263ffffffff85166004820152602401610cd1565b5f6122966122938787612c36565b90565b90505f6122c1826122af6122aa8a8a612c4d565b6127e7565b6122bc60208d018d6140a7565b612c6f565b90506028861115612381575f6122fd6122e060608c0160408d01613fba565b6122ed60208d018d6140a7565b846122f88c8c612c82565b612ccc565b604051633e5ac80960e11b81529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690637cb59012906123529086908d905f9087906004016148d5565b5f604051808303815f87803b158015612369575f80fd5b505af115801561237b573d5f803e3d5ffd5b50505050505b6001600160a01b038216887fefed6d3500546b29533b128a29e3a94d70788727f0507505ac12eaf2e578fd9c6123ba60208d018d6140a7565b6040805163ffffffff9092168252602082018690520160405180910390a3505050505050505050565b5f6123ee8484611e76565b90505f19811461245557818110156124485760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610cd1565b61245584848484036121cb565b50505050565b612147838383612cfe565b6033546001600160a01b031633146112be5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610cd1565b5f610fd6612ea7565b604080518082019091525f80825260208201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ddc28c586040518060a001604052808863ffffffff16815260200161252b8961223c565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b8152600401612560929190614905565b6040805180830381865afa15801561257a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061259e91906149ab565b95945050505050565b7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10280546060915f80516020614cbb833981519152916125e590614327565b80601f016020809104026020016040519081016040528092919081815260200182805461261190614327565b801561265c5780601f106126335761010080835404028352916020019161265c565b820191905f5260205f20905b81548152906001019060200180831161263f57829003601f168201915b505050505091505090565b7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10380546060915f80516020614cbb833981519152916125e590614327565b5f80516020614c9b8339815191526001600160a01b0383165f90815260209182526040808220848352909252205460ff161561210a5760405163076f007560e21b815260040160405180910390fd5b6127078361270184612f1a565b83612f46565b158061271a57506001600160a01b038316155b1561214757604051638baa579f60e01b815260040160405180910390fd5b6001600160a01b0382165f8181525f80516020614c9b83398151915260209081526040808320858452909152808220805460ff19166001179055518392917f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a591a35050565b6001600160a01b0381165f9081527fb39b43abb0b115e0a59dece28477e279ee5f8e2fd55fbe200557c3ab864a030060208190526040909120805460018101909155905b50919050565b5f610d737f00000000000000000000000000000000000000000000000000000000000000006001600160401b0384166149c5565b5f61282960028284866146be565b612832916149dc565b60f01c905060038114612147578282604051639a6d49cd60e01b8152600401610cd192919061470b565b5f7f000000000000000000000000000000000000000000000000000000000000000061288881846148b6565b610d7391906149c5565b5f8061289f8585856121d6565b9092509050611f213383612f9a565b6128b6613813565b5f6128c3845f01516130cc565b6020850151909150156128dd576128dd84602001516130f3565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632637a450826040518060a001604052808b63ffffffff16815260200161292d8c61223c565b81526020018a81526020018981526020015f8960200151111515815250866040518463ffffffff1660e01b8152600401612968929190614905565b60806040518083038185885af1158015612984573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906129a99190614a0c565b979650505050505050565b80516060901515806129fd5784846040516020016129e992919091825260c01b6001600160c01b031916602082015260280190565b604051602081830303815290604052612a24565b84843385604051602001612a149493929190614a71565b6040516020818303038152906040525b9150935093915050565b5f80516020614cbb8339815191527fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d102612a678482614ab3565b5060038101612a768382614ab3565b505f8082556001909101555050565b5f54610100900460ff16612aab5760405162461bcd60e51b8152600401610cd19061486b565b61210a82826131d2565b5f54610100900460ff16612adb5760405162461bcd60e51b8152600401610cd19061486b565b611f9f81613211565b5f54610100900460ff16612b0a5760405162461bcd60e51b8152600401610cd19061486b565b6112be3361217a565b6001600160a01b038316612b755760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610cd1565b6001600160a01b038216612bd65760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610cd1565b6001600160a01b038381165f8181526066602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b5f612c4460208284866146be565b610f5b91614b72565b5f612c5c6028602084866146be565b612c6591614b8f565b60c01c9392505050565b5f612c7a8484613240565b509092915050565b6060612c9182602881866146be565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250929695505050505050565b606084848484604051602001612ce59493929190614bbd565b6040516020818303038152906040529050949350505050565b6001600160a01b038316612d625760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610cd1565b6001600160a01b038216612dc45760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610cd1565b6001600160a01b0383165f9081526065602052604090205481811015612e3b5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610cd1565b6001600160a01b038085165f8181526065602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90612e9a9086815260200190565b60405180910390a3612455565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f612ed16132ff565b612ed9613367565b60408051602081019490945283019190915260608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b5f610d73612f266124c0565b8360405161190160f01b8152600281019290925260228201526042902090565b5f805f612f5385856133a9565b90925090505f816004811115612f6b57612f6b614c0b565b148015612f895750856001600160a01b0316826001600160a01b0316145b806110fb57506110fb8686866133e8565b6001600160a01b038216612ffa5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610cd1565b6001600160a01b0382165f908152606560205260409020548181101561306d5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610cd1565b6001600160a01b0383165f8181526065602090815260408083208686039055606780548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b5f8134146130ef576040516304fb820960e51b8152346004820152602401610cd1565b5090565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa158015613150573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131749190614c1f565b90506001600160a01b03811661319d576040516329b99a9560e11b815260040160405180910390fd5b61210a6001600160a01b038216337f0000000000000000000000000000000000000000000000000000000000000000856134cf565b5f54610100900460ff166131f85760405162461bcd60e51b8152600401610cd19061486b565b60686132048382614ab3565b5060696121478282614ab3565b5f54610100900460ff166132375760405162461bcd60e51b8152600401610cd19061486b565b611f9f81613529565b6001600160a01b0382166132965760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610cd1565b8060675f8282546132a791906143bb565b90915550506001600160a01b0382165f818152606560209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b5f5f80516020614cbb833981519152816133176125a7565b80519091501561332f57805160209091012092915050565b8154801561333e579392505050565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470935050505090565b5f5f80516020614cbb8339815191528161337f612667565b80519091501561339757805160209091012092915050565b6001820154801561333e579392505050565b5f8082516041036133dd576020830151604084015160608501515f1a6133d187828585613576565b94509450505050610bfe565b505f90506002610bfe565b5f805f856001600160a01b0316631626ba7e60e01b8686604051602401613410929190614c3a565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161344e9190614c52565b5f60405180830381855afa9150503d805f8114613486576040519150601f19603f3d011682016040523d82523d5f602084013e61348b565b606091505b509150915081801561349f57506020815110155b80156110fb57508051630b135d3f60e11b906134c49083016020908101908401614c63565b149695505050505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612455908590613633565b5f54610100900460ff1661354f5760405162461bcd60e51b8152600401610cd19061486b565b6001600160a01b038116611ca457604051632d618d8160e21b815260040160405180910390fd5b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156135ab57505f9050600361362a565b604080515f8082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156135fc573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b038116613624575f6001925092505061362a565b91505f90505b94509492505050565b5f613687826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166137069092919063ffffffff16565b905080515f14806136a75750808060200190518101906136a79190614850565b6121475760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610cd1565b6060611a0784845f85855f80866001600160a01b0316858760405161372b9190614c52565b5f6040518083038185875af1925050503d805f8114613765576040519150601f19603f3d011682016040523d82523d5f602084013e61376a565b606091505b50915091506129a987838387606083156137e45782515f036137dd576001600160a01b0385163b6137dd5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610cd1565b5081611a07565b611a0783838151156137f95781518083602001fd5b8060405162461bcd60e51b8152600401610cd19190613918565b60405180606001604052805f80191681526020015f6001600160401b0316815260200161385160405180604001604052805f81526020015f81525090565b905290565b5f60e082840312156127e1575f80fd5b5f8060408385031215613877575f80fd5b82356001600160401b0381111561388c575f80fd5b61389885828601613856565b95602094909401359450505050565b5f5b838110156138c15781810151838201526020016138a9565b50505f910152565b5f81518084526138e08160208601602086016138a7565b601f01601f19169290920160200192915050565b604081525f61390660408301856138c9565b828103602084015261259e81856138c9565b602081525f610f5b60208301846138c9565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b03811182821017156139605761396061392a565b60405290565b604051601f8201601f191681016001600160401b038111828210171561398e5761398e61392a565b604052919050565b5f6001600160401b038211156139ae576139ae61392a565b50601f01601f191660200190565b5f82601f8301126139cb575f80fd5b81356139de6139d982613996565b613966565b8181528460208386010111156139f2575f80fd5b816020850160208301375f918101602001919091529392505050565b6001600160a01b0381168114611f9f575f80fd5b5f805f60608486031215613a34575f80fd5b83356001600160401b0380821115613a4a575f80fd5b613a56878388016139bc565b94506020860135915080821115613a6b575f80fd5b50613a78868287016139bc565b9250506040840135613a8981613a0e565b809150509250925092565b5f8060408385031215613aa5575f80fd5b8235613ab081613a0e565b946020939093013593505050565b5f60208284031215613ace575f80fd5b81356001600160401b03811115613ae3575f80fd5b611a0784828501613856565b83518152602080850151908201525f60a08201604060a0604085015281865180845260c08601915060c08160051b870101935060208089015f5b83811015613b685788870360bf19018552815180518852830151838801879052613b55878901826138c9565b9750509382019390820190600101613b29565b50508751606088015250505060208501516080850152509050611a07565b5f60208284031215613b96575f80fd5b5035919050565b5f606082840312156127e1575f80fd5b5f8083601f840112613bbd575f80fd5b5081356001600160401b03811115613bd3575f80fd5b602083019150836020828501011115610bfe575f80fd5b5f805f805f805f60e0888a031215613c00575f80fd5b613c0a8989613b9d565b96506060880135955060808801356001600160401b0380821115613c2c575f80fd5b613c388b838c01613bad565b909750955060a08a01359150613c4d82613a0e565b90935060c08901359080821115613c62575f80fd5b50613c6f8a828b01613bad565b989b979a50959850939692959293505050565b5f805f60608486031215613c94575f80fd5b8335613c9f81613a0e565b92506020840135613caf81613a0e565b929592945050506040919091013590565b803563ffffffff81168114613cd3575f80fd5b919050565b5f8060408385031215613ce9575f80fd5b613ab083613cc0565b8015158114611f9f575f80fd5b5f8060408385031215613d10575f80fd5b82356001600160401b03811115613d25575f80fd5b613d3185828601613856565b9250506020830135613d4281613cf2565b809150509250929050565b815181526020808301519082015260408101610d73565b803561ffff81168114613cd3575f80fd5b5f8060408385031215613d86575f80fd5b613d8f83613cc0565b9150613d9d60208401613d64565b90509250929050565b803560ff81168114613cd3575f80fd5b5f805f805f60a08688031215613dca575f80fd5b8535613dd581613a0e565b945060208601359350613dea60408701613da6565b94979396509394606081013594506080013592915050565b5f60208284031215613e12575f80fd5b8135610f5b81613a0e565b60ff60f81b881681525f602060e06020840152613e3d60e084018a6138c9565b8381036040850152613e4f818a6138c9565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825260208088019350909101905f5b81811015613ea257835183529284019291840191600101613e86565b50909c9b505050505050505050505050565b5f805f805f805f60e0888a031215613eca575f80fd5b8735613ed581613a0e565b96506020880135613ee581613a0e565b955060408801359450606088013593506080880135925060a0880135915060c08801356001600160401b03811115613f1b575f80fd5b613f278a828b016139bc565b91505092959891949750929550565b5f805f805f60a08688031215613f4a575f80fd5b8535613f5581613a0e565b94506020860135613f6581613a0e565b9350604086013592506060860135915060808601356001600160401b03811115613f8d575f80fd5b613f99888289016139bc565b9150509295509295909350565b6001600160401b0381168114611f9f575f80fd5b5f60208284031215613fca575f80fd5b8135610f5b81613fa6565b5f805f60608486031215613fe7575f80fd5b8335613ff281613a0e565b92506020840135915060408401356001600160401b03811115614013575f80fd5b61401f868287016139bc565b9150509250925092565b5f8083601f840112614039575f80fd5b5081356001600160401b0381111561404f575f80fd5b6020830191508360208260051b8501011115610bfe575f80fd5b5f806020838503121561407a575f80fd5b82356001600160401b0381111561408f575f80fd5b61409b85828601614029565b90969095509350505050565b5f602082840312156140b7575f80fd5b610f5b82613cc0565b5f805f80606085870312156140d3575f80fd5b6140dc85613cc0565b93506140ea60208601613d64565b925060408501356001600160401b03811115614104575f80fd5b61411087828801613bad565b95989497509550505050565b5f805f838503608081121561412f575f80fd5b84356001600160401b03811115614144575f80fd5b61415087828801613856565b9450506040601f1982011215614164575f80fd5b506020840191506060840135613a8981613a0e565b5f60c082019050835182526001600160401b03602085015116602083015260408401516141b3604084018280518252602090810151910152565b5082516080830152602083015160a0830152610f5b565b5f805f805f805f60e0888a0312156141e0575f80fd5b87356141eb81613a0e565b965060208801356141fb81613a0e565b9550604088013594506060880135935061421760808901613da6565b925060a0880135915060c0880135905092959891949750929550565b5f8060408385031215614244575f80fd5b823561424f81613a0e565b91506020830135613d4281613a0e565b5f805f805f805f805f6101208a8c031215614278575f80fd5b893561428381613a0e565b985060208a013561429381613a0e565b975060408a0135965060608a0135955060808a0135945060a08a013593506142bd60c08b01613da6565b925060e08a013591506101008a013590509295985092959850929598565b5f805f606084860312156142ed575f80fd5b833592506020840135915061430460408501613cc0565b90509250925092565b5f6060828403121561431d575f80fd5b610f5b8383613b9d565b600181811c9082168061433b57607f821691505b6020821081036127e157634e487b7160e01b5f52602260045260245ffd5b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b634e487b7160e01b5f52601160045260245ffd5b80820180821115610d7357610d736143a7565b928352602083019190915260f81b6001600160f81b031916604082015260410190565b9687526001600160a01b0395861660208801529390941660408601526060850191909152608084015260a083019190915260c082015260e00190565b634e487b7160e01b5f52603260045260245ffd5b5f8235605e19833603018112614455575f80fd5b9190910192915050565b5f808335601e19843603018112614474575f80fd5b8301803591506001600160401b0382111561448d575f80fd5b602001915036819003821315610bfe575f80fd5b5f602082840312156144b1575f80fd5b610f5b82613d64565b601f82111561214757805f5260205f20601f840160051c810160208510156144df5750805b601f840160051c820191505b8181101561122a575f81556001016144eb565b6001600160401b038311156145155761451561392a565b614529836145238354614327565b836144ba565b5f601f84116001811461455a575f85156145435750838201355b5f19600387901b1c1916600186901b17835561122a565b5f83815260208120601f198716915b828110156145895786850135825560209485019460019092019101614569565b50868210156145a5575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60208082528181018390525f906040808401600586901b8501820187855b888110156146b057878303603f190184528135368b9003605e19018112614622575f80fd5b8a01606063ffffffff61463483613cc0565b16855261ffff614645898401613d64565b168886015286820135601e1983360301811261465f575f80fd5b9091018781019190356001600160401b0381111561467b575f80fd5b803603831315614689575f80fd5b818887015261469b82870182856145b7565b968901969550505091860191506001016145fd565b509098975050505050505050565b5f80858511156146cc575f80fd5b838611156146d8575f80fd5b5050820193919092039150565b5f84516146f68184602089016138a7565b8201838582375f930192835250909392505050565b602081525f611a076020830184866145b7565b5f823561013e19833603018112614455575f80fd5b63ffffffff61474189613cc0565b168152602088013560208201525f604089013561475d81613fa6565b6001600160401b03811660408401525087606083015260e0608083015261478860e0830187896145b7565b6001600160a01b03861660a084015282810360c08401526147aa8185876145b7565b9a9950505050505050505050565b5f602082840312156147c8575f80fd5b81516001600160401b038111156147dd575f80fd5b8201601f810184136147ed575f80fd5b80516147fb6139d982613996565b81815285602083850101111561480f575f80fd5b61259e8260208301602086016138a7565b5f60408284031215614830575f80fd5b61483861393e565b82358152602083013560208201528091505092915050565b5f60208284031215614860575f80fd5b8151610f5b81613cf2565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b5f826148d057634e487b7160e01b5f52601260045260245ffd5b500490565b60018060a01b038516815283602082015261ffff83166040820152608060608201525f6110fb60808301846138c9565b6040815263ffffffff8351166040820152602083015160608201525f604084015160a0608084015261493a60e08401826138c9565b90506060850151603f198483030160a085015261495782826138c9565b60809690960151151560c08501525050506001600160a01b039190911660209091015290565b5f6040828403121561498d575f80fd5b61499561393e565b9050815181526020820151602082015292915050565b5f604082840312156149bb575f80fd5b610f5b838361497d565b8082028115828204841417610d7357610d736143a7565b6001600160f01b03198135818116916002851015614a045780818660020360031b1b83161692505b505092915050565b5f60808284031215614a1c575f80fd5b604051606081018181106001600160401b0382111715614a3e57614a3e61392a565b604052825181526020830151614a5381613fa6565b6020820152614a65846040850161497d565b60408201529392505050565b8481526001600160401b0360c01b8460c01b1660208201528260288201525f8251614aa38160488501602087016138a7565b9190910160480195945050505050565b81516001600160401b03811115614acc57614acc61392a565b614ae081614ada8454614327565b846144ba565b602080601f831160018114614b13575f8415614afc5750858301515b5f19600386901b1c1916600185901b178555614b6a565b5f85815260208120601f198616915b82811015614b4157888601518255948401946001909101908401614b22565b5085821015614b5e57878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b80356020831015610d73575f19602084900360031b1b1692915050565b6001600160c01b03198135818116916008851015614a045760089490940360031b84901b1690921692915050565b6001600160401b0360c01b8560c01b16815263ffffffff60e01b8460e01b16600882015282600c8201525f8251614bfb81602c8501602087016138a7565b91909101602c0195945050505050565b634e487b7160e01b5f52602160045260245ffd5b5f60208284031215614c2f575f80fd5b8151610f5b81613a0e565b828152604060208201525f611a0760408301846138c9565b5f82516144558184602087016138a7565b5f60208284031215614c73575f80fd5b505191905056fe72ab1bc1039b79dc4724ffca13de82c96834302d3c7e0d4252232d4b2dd8f9006607eb842e76408d8b3956685dc6b9da5897a1d9b47edcc993ce266e603fa500a16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100a2646970667358221220f1551093d0a4fc78776efc5a6799d0f3e995df8f490a6fd6fcf58686806ca94b64736f6c634300081600330000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b
Deployed Bytecode
0x6080604052600436106103b3575f3560e01c8063857749b0116101e9578063bd815db011610108578063dd62ed3e1161009d578063f01630231161006d578063f016302314610b7a578063f2fde38b14610bae578063fc0c546a14610673578063ff7bd03d14610bcd575f80fd5b8063dd62ed3e14610acd578063e3ee160e14610aec578063e94a010214610b0b578063ef55bec614610b5b575f80fd5b8063cf092995116100d8578063cf09299514610a5d578063d045a0dc14610a7c578063d424388514610a8f578063d505accf14610aae575f80fd5b8063bd815db0146109eb578063c0779988146109fe578063c7c7f5b314610a1d578063ca5eb5e114610a3e575f80fd5b8063a9059cbb1161017e578063b92d0eff1161014e578063b92d0eff14610673578063b98bd07014610970578063bb0b6a531461098f578063bc70b354146109cc575f80fd5b8063a9059cbb146108ff578063b3a5abeb1461091e578063b731ea0a1461093d578063b7b7289914610951575f80fd5b8063963efcaa116101b9578063963efcaa1461087c5780639f68b964146108af5780639fd5a6cf146108c1578063a457c2d7146108e0575f80fd5b8063857749b01461081957806388b7ab631461082c5780638da5cb5b1461084b57806395d89b4114610868575f80fd5b80633644e515116102d55780635a0dfe4d1161026a578063715018a61161023a578063715018a61461079e5780637d25a05e146107b25780637ecebe00146107d357806384b0196e146107f2575f80fd5b80635a0dfe4d146106d75780635e280f11146107185780636fc1b31e1461074b57806370a082311461076a575f80fd5b806352ae2879116102a557806352ae28791461067357806354fd4d50146106855780635535d461146106995780635a049a70146106b8575f80fd5b80633644e515146106005780633714fffa1461061457806339509351146106285780633b6f743b14610647575f80fd5b8063134d4f251161034b5780631f5e13341161031b5780631f5e13341461058d57806323b872dd146105a1578063313ce567146105c05780633400288b146105e1575f80fd5b8063134d4f2514610502578063156a0d0f1461052957806317442b701461054f57806318160ddd1461056f575f80fd5b80630d35b415116103865780630d35b4151461045e5780630e78842c1461048c578063111ecdad146104c357806313137d65146104ef575f80fd5b8063056d62de146103b757806306fdde03146103ed578063077f224a1461040e578063095ea7b31461042f575b5f80fd5b3480156103c2575f80fd5b506103d66103d1366004613866565b610bec565b6040516103e49291906138f4565b60405180910390f35b3480156103f8575f80fd5b50610401610c05565b6040516103e49190613918565b348015610419575f80fd5b5061042d610428366004613a22565b610c95565b005b34801561043a575f80fd5b5061044e610449366004613a94565b610d60565b60405190151581526020016103e4565b348015610469575f80fd5b5061047d610478366004613abe565b610d79565b6040516103e493929190613aef565b348015610497575f80fd5b506104ab6104a6366004613b86565b610e44565b6040516001600160401b0390911681526020016103e4565b3480156104ce575f80fd5b506104d7610e4e565b6040516001600160a01b0390911681526020016103e4565b61042d6104fd366004613bea565b610e82565b34801561050d575f80fd5b50610516600281565b60405161ffff90911681526020016103e4565b348015610534575f80fd5b506040805162b9270b60e21b815260016020820152016103e4565b34801561055a575f80fd5b506040805160018082526020820152016103e4565b34801561057a575f80fd5b506067545b6040519081526020016103e4565b348015610598575f80fd5b50610516600181565b3480156105ac575f80fd5b5061044e6105bb366004613c82565b610f3d565b3480156105cb575f80fd5b5060125b60405160ff90911681526020016103e4565b3480156105ec575f80fd5b5061042d6105fb366004613cd8565b610f62565b34801561060b575f80fd5b5061057f610fcd565b34801561061f575f80fd5b5061042d610fdb565b348015610633575f80fd5b5061044e610642366004613a94565b611080565b348015610652575f80fd5b50610666610661366004613cff565b6110a1565b6040516103e49190613d4d565b34801561067e575f80fd5b50306104d7565b348015610690575f80fd5b50610401611105565b3480156106a4575f80fd5b506104016106b3366004613d75565b611124565b3480156106c3575f80fd5b5061042d6106d2366004613db6565b6111fc565b3480156106e2575f80fd5b5061044e6106f1366004613cd8565b63ffffffff919091165f9081525f80516020614c7b83398151915260205260409020541490565b348015610723575f80fd5b506104d77f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b81565b348015610756575f80fd5b5061042d610765366004613e02565b611231565b348015610775575f80fd5b5061057f610784366004613e02565b6001600160a01b03165f9081526065602052604090205490565b3480156107a9575f80fd5b5061042d6112ad565b3480156107bd575f80fd5b506104ab6107cc366004613cd8565b5f92915050565b3480156107de575f80fd5b5061057f6107ed366004613e02565b6112c0565b3480156107fd575f80fd5b506108066112fe565b6040516103e49796959493929190613e1d565b348015610824575f80fd5b5060066105cf565b348015610837575f80fd5b5061042d610846366004613eb4565b6113a7565b348015610856575f80fd5b506033546001600160a01b03166104d7565b348015610873575f80fd5b5061040161149f565b348015610887575f80fd5b5061057f7f000000000000000000000000000000000000000000000000000000e8d4a5100081565b3480156108ba575f80fd5b505f61044e565b3480156108cc575f80fd5b5061042d6108db366004613f36565b6114ae565b3480156108eb575f80fd5b5061044e6108fa366004613a94565b611577565b34801561090a575f80fd5b5061044e610919366004613a94565b6115fc565b348015610929575f80fd5b5061057f610938366004613fba565b611609565b348015610948575f80fd5b506104d7611613565b34801561095c575f80fd5b5061042d61096b366004613fd5565b61163b565b34801561097b575f80fd5b5061042d61098a366004614069565b6116fb565b34801561099a575f80fd5b5061057f6109a93660046140a7565b63ffffffff165f9081525f80516020614c7b833981519152602052604090205490565b3480156109d7575f80fd5b506104016109e63660046140c0565b611877565b61042d6109f9366004614069565b611a0f565b348015610a09575f80fd5b5061057f610a18366004613b86565b611b9b565b610a30610a2b36600461411c565b611ba5565b6040516103e4929190614179565b348015610a49575f80fd5b5061042d610a58366004613e02565b611c9c565b348015610a68575f80fd5b5061042d610a77366004613eb4565b611d16565b61042d610a8a366004613bea565b611da3565b348015610a9a575f80fd5b5061042d610aa9366004613e02565b611dd2565b348015610ab9575f80fd5b5061042d610ac83660046141ca565b611e46565b348015610ad8575f80fd5b5061057f610ae7366004614233565b611e76565b348015610af7575f80fd5b5061042d610b0636600461425f565b611ea0565b348015610b16575f80fd5b5061044e610b25366004613a94565b6001600160a01b03919091165f9081525f80516020614c9b83398151915260209081526040808320938352929052205460ff1690565b348015610b66575f80fd5b5061042d610b7536600461425f565b611edd565b348015610b85575f80fd5b50610b99610b943660046142db565b611f0f565b604080519283526020830191909152016103e4565b348015610bb9575f80fd5b5061042d610bc8366004613e02565b611f29565b348015610bd8575f80fd5b5061044e610be736600461430d565b611fa2565b606080610bf98484611fbf565b915091505b9250929050565b606060688054610c1490614327565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4090614327565b8015610c8b5780601f10610c6257610100808354040283529160200191610c8b565b820191905f5260205f20905b815481529060010190602001808311610c6e57829003601f168201915b5050505050905090565b5f54600390610100900460ff16158015610cb557505f5460ff8083169116105b610cda5760405162461bcd60e51b8152600401610cd190614359565b60405180910390fd5b5f805461ffff191660ff831617610100179055610cfe84610cf9611105565b612100565b610d0984848461210e565b610d1161214c565b610d1a8261217a565b5f805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b5f33610d6d8185856121cb565b60019150505b92915050565b604080518082019091525f80825260208201526060610da960405180604001604052805f81526020015f81525090565b6040805180820182525f8082526001600160401b03602080840182905284518381529081019094529195509182610e02565b604080518082019091525f815260606020820152815260200190600190039081610ddb5790505b5093505f80610e26604089013560608a0135610e2160208c018c6140a7565b6121d6565b60408051808201909152918252602082015296989597505050505050565b5f610d7382612211565b5f807f41db8a78b0206aba5c54bcbfc2bda0d84082a84eb88e680379a57b9e9f653c005b546001600160a01b031692915050565b7f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b6001600160a01b03163314610ecd576040516391ac5e4f60e01b8152336004820152602401610cd1565b60208701803590610ee790610ee2908a6140a7565b61223c565b14610f2557610ef960208801886140a7565b60405163309afaf360e21b815263ffffffff909116600482015260208801356024820152604401610cd1565b610f3487878787878787612285565b50505050505050565b5f33610f4a8582856123e3565b610f5585858561245b565b60019150505b9392505050565b610f6a612466565b63ffffffff82165f8181525f80516020614c7b833981519152602081815260409283902085905582519384528301849052917f238399d427b947898edb290f5ff0f9109849b1c3ba196a42e35f00c50a54b98b91015b60405180910390a1505050565b5f610fd66124c0565b905090565b5f54600390610100900460ff16158015610ffb57505f5460ff8083169116105b6110175760405162461bcd60e51b8152600401610cd190614359565b5f805461ffff191660ff83161761010017905561103d611035610c05565b610cf9611105565b5f805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b5f33610d6d8185856110928383611e76565b61109c91906143bb565b6121cb565b604080518082019091525f80825260208201525f6110cf60408501356060860135610e2160208801886140a7565b9150505f806110de8684611fbf565b90925090506110fb6110f360208801886140a7565b8383886124c9565b9695505050505050565b6040805180820190915260058152640312e312e360dc1b602082015290565b63ffffffff82165f9081527f8d2bda5d9f6ffb5796910376005392955773acee5548d0fcdb10e7c264ea00006020818152604080842061ffff861685529091529091208054606092919061117790614327565b80601f01602080910402602001604051908101604052809291908181526020018280546111a390614327565b80156111ee5780601f106111c5576101008083540402835291602001916111ee565b820191905f5260205f20905b8154815290600101906020018083116111d157829003601f168201915b505050505091505092915050565b61122a8585848487604051602001611216939291906143ce565b60405160208183030381529060405261163b565b5050505050565b611239612466565b7f41db8a78b0206aba5c54bcbfc2bda0d84082a84eb88e680379a57b9e9f653c0080546001600160a01b0319166001600160a01b03831690811782556040519081527ff0be4f1e87349231d80c36b33f9e8639658eeaf474014dee15a3e6a4d4414197906020015b60405180910390a15050565b6112b5612466565b6112be5f61217a565b565b6001600160a01b0381165f9081527fb39b43abb0b115e0a59dece28477e279ee5f8e2fd55fbe200557c3ab864a030060208190526040822054610f5b565b5f60608082808083815f80516020614cbb833981519152805490915015801561132957506001810154155b61136d5760405162461bcd60e51b81526020600482015260156024820152741152540dcc4c8e88155b9a5b9a5d1a585b1a5e9959605a1b6044820152606401610cd1565b6113756125a7565b61137d612667565b604080515f80825260208201909252600f60f81b9c939b5091995046985030975095509350915050565b6001600160a01b03861633146113e157604051637f54a22160e11b81523360048201526001600160a01b0387166024820152604401610cd1565b83421161140157604051632ce87eeb60e01b815260040160405180910390fd5b8242106114215760405163a899ef9360e01b815260040160405180910390fd5b61142b87836126a5565b61148a877fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de85f1b89898989898960405160200161146e97969594939291906143f1565b60405160208183030381529060405280519060200120836126f4565b6114948783612738565b610f3487878761245b565b606060698054610c1490614327565b814211156114fe5760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610cd1565b61156c857f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c987878761152f8b61279d565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810185905260e00161146e565b61122a8585856121cb565b5f33816115848286611e76565b9050838110156115e45760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610cd1565b6115f182868684036121cb565b506001949350505050565b5f33610d6d81858561245b565b5f610d73826127e7565b5f807fefb041d771d6daaa55702fff6eb740d63ba559a75d2d1d3e151c78ff2480b600610e72565b61164583836126a5565b604080517f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a159742960208201526001600160a01b038516918101919091526060810183905261169590849060800161146e565b6001600160a01b0383165f8181525f80516020614c9b83398151915260209081526040808320868452909152808220805460ff19166001179055518492917f1cdd46ff242716cdaa72d159d339a485b3438398348d68f09d7c8c0a59353d8191a3505050565b611703612466565b7f8d2bda5d9f6ffb5796910376005392955773acee5548d0fcdb10e7c264ea00005f5b82811015611845576117688484838181106117435761174361442d565b90506020028101906117559190614441565b61176390604081019061445f565b61281b565b83838281811061177a5761177a61442d565b905060200281019061178c9190614441565b61179a90604081019061445f565b835f8787868181106117ae576117ae61442d565b90506020028101906117c09190614441565b6117ce9060208101906140a7565b63ffffffff1663ffffffff1681526020019081526020015f205f8787868181106117fa576117fa61442d565b905060200281019061180c9190614441565b61181d9060408101906020016144a1565b61ffff16815260208101919091526040015f209161183c9190836144fe565b50600101611726565b507fbe4864a8e820971c0247f5992e2da559595f7bf076a21cb5928d443d2a13b6748383604051610fc09291906145df565b63ffffffff84165f9081527f8d2bda5d9f6ffb5796910376005392955773acee5548d0fcdb10e7c264ea00006020818152604080842061ffff881685529091528220805460609391906118c990614327565b80601f01602080910402602001604051908101604052809291908181526020018280546118f590614327565b80156119405780601f1061191757610100808354040283529160200191611940565b820191905f5260205f20905b81548152906001019060200180831161192357829003601f168201915b5050505050905080515f0361198f5784848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250929550611a07945050505050565b5f8490036119a0579150611a079050565b600284106119ea576119b2858561281b565b806119c085600281896146be565b6040516020016119d2939291906146e5565b60405160208183030381529060405292505050611a07565b8484604051639a6d49cd60e01b8152600401610cd192919061470b565b949350505050565b5f5b81811015611b1e5736838383818110611a2c57611a2c61442d565b9050602002810190611a3e919061471e565b9050611a7c611a5060208301836140a7565b602083013563ffffffff919091165f9081525f80516020614c7b83398151915260205260409020541490565b611a865750611b16565b3063d045a0dc60c08301358360a0810135611aa561010083018361445f565b611ab6610100890160e08a01613e02565b611ac46101208a018a61445f565b6040518963ffffffff1660e01b8152600401611ae69796959493929190614733565b5f604051808303818588803b158015611afd575f80fd5b505af1158015611b0f573d5f803e3d5ffd5b5050505050505b600101611a11565b50336001600160a01b0316638e9e70996040518163ffffffff1660e01b81526004015f60405180830381865afa158015611b5a573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611b8191908101906147b8565b604051638351eea760e01b8152600401610cd19190613918565b5f610d738261285c565b611bad613813565b604080518082019091525f80825260208201525f80611be160408801356060890135611bdc60208b018b6140a7565b612892565b915091505f80611bf18984611fbf565b9092509050611c1d611c0660208b018b6140a7565b8383611c17368d90038d018d614820565b8b6128ae565b60408051808201909152858152602080820186905282519298509096503391907f85496b760a4b7f8d66384b9df21b381f5d1b1e79f229a47aaf4c232edc2fe59a90611c6b908d018d6140a7565b6040805163ffffffff909216825260208201899052810187905260600160405180910390a350505050935093915050565b611ca4612466565b60405163ca5eb5e160e01b81526001600160a01b0382811660048301527f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b169063ca5eb5e1906024015f604051808303815f87803b158015611d04575f80fd5b505af115801561122a573d5f803e3d5ffd5b834211611d3657604051632ce87eeb60e01b815260040160405180910390fd5b824210611d565760405163a899ef9360e01b815260040160405180910390fd5b611d6087836126a5565b61148a877f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a22675f1b89898989898960405160200161146e97969594939291906143f1565b333014611dc35760405163029a949d60e31b815260040160405180910390fd5b610f3487878787878787610f25565b611dda612466565b7fefb041d771d6daaa55702fff6eb740d63ba559a75d2d1d3e151c78ff2480b60080546001600160a01b0319166001600160a01b03831690811782556040519081527fd48d879cef83a1c0bdda516f27b13ddb1b3f8bbac1c9e1511bb2a659c2427760906020016112a1565b610f3487878787868689604051602001611e62939291906143ce565b6040516020818303038152906040526114ae565b6001600160a01b039182165f90815260666020908152604080832093909416825291909152205490565b611ed289898989898988888b604051602001611ebe939291906143ce565b604051602081830303815290604052611d16565b505050505050505050565b611ed289898989898988888b604051602001611efb939291906143ce565b6040516020818303038152906040526113a7565b5f80611f1c8585856121d6565b915091505b935093915050565b611f31612466565b6001600160a01b038116611f965760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610cd1565b611f9f8161217a565b50565b5f60208201803590611fb8906109a990856140a7565b1492915050565b6060805f61201a8560200135611fd486612211565b611fe160a089018961445f565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506129b492505050565b90935090505f8161202c57600161202f565b60025b905061204f61204160208801886140a7565b826109e660808a018a61445f565b7f41db8a78b0206aba5c54bcbfc2bda0d84082a84eb88e680379a57b9e9f653c008054919450906001600160a01b0316156120f657805460405163043a78eb60e01b81526001600160a01b039091169063043a78eb906120b590889088906004016138f4565b602060405180830381865afa1580156120d0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120f49190614850565b505b5050509250929050565b61210a8282612a2e565b5050565b5f54610100900460ff166121345760405162461bcd60e51b8152600401610cd19061486b565b61213e8383612a85565b61214781612ab5565b505050565b5f54610100900460ff166121725760405162461bcd60e51b8152600401610cd19061486b565b6112be612ae4565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b612147838383612b13565b5f806121e18561285c565b915081905083811015611f21576040516371c4efed60e01b81526004810182905260248101859052604401610cd1565b5f610d737f000000000000000000000000000000000000000000000000000000e8d4a51000836148b6565b63ffffffff81165f9081525f80516020614c7b8339815191526020819052604082205480610f5b5760405163f6ff4fb760e01b815263ffffffff85166004820152602401610cd1565b5f6122966122938787612c36565b90565b90505f6122c1826122af6122aa8a8a612c4d565b6127e7565b6122bc60208d018d6140a7565b612c6f565b90506028861115612381575f6122fd6122e060608c0160408d01613fba565b6122ed60208d018d6140a7565b846122f88c8c612c82565b612ccc565b604051633e5ac80960e11b81529091506001600160a01b037f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b1690637cb59012906123529086908d905f9087906004016148d5565b5f604051808303815f87803b158015612369575f80fd5b505af115801561237b573d5f803e3d5ffd5b50505050505b6001600160a01b038216887fefed6d3500546b29533b128a29e3a94d70788727f0507505ac12eaf2e578fd9c6123ba60208d018d6140a7565b6040805163ffffffff9092168252602082018690520160405180910390a3505050505050505050565b5f6123ee8484611e76565b90505f19811461245557818110156124485760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610cd1565b61245584848484036121cb565b50505050565b612147838383612cfe565b6033546001600160a01b031633146112be5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610cd1565b5f610fd6612ea7565b604080518082019091525f80825260208201527f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b6001600160a01b031663ddc28c586040518060a001604052808863ffffffff16815260200161252b8961223c565b8152602001878152602001868152602001851515815250306040518363ffffffff1660e01b8152600401612560929190614905565b6040805180830381865afa15801561257a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061259e91906149ab565b95945050505050565b7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10280546060915f80516020614cbb833981519152916125e590614327565b80601f016020809104026020016040519081016040528092919081815260200182805461261190614327565b801561265c5780601f106126335761010080835404028352916020019161265c565b820191905f5260205f20905b81548152906001019060200180831161263f57829003601f168201915b505050505091505090565b7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10380546060915f80516020614cbb833981519152916125e590614327565b5f80516020614c9b8339815191526001600160a01b0383165f90815260209182526040808220848352909252205460ff161561210a5760405163076f007560e21b815260040160405180910390fd5b6127078361270184612f1a565b83612f46565b158061271a57506001600160a01b038316155b1561214757604051638baa579f60e01b815260040160405180910390fd5b6001600160a01b0382165f8181525f80516020614c9b83398151915260209081526040808320858452909152808220805460ff19166001179055518392917f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a591a35050565b6001600160a01b0381165f9081527fb39b43abb0b115e0a59dece28477e279ee5f8e2fd55fbe200557c3ab864a030060208190526040909120805460018101909155905b50919050565b5f610d737f000000000000000000000000000000000000000000000000000000e8d4a510006001600160401b0384166149c5565b5f61282960028284866146be565b612832916149dc565b60f01c905060038114612147578282604051639a6d49cd60e01b8152600401610cd192919061470b565b5f7f000000000000000000000000000000000000000000000000000000e8d4a5100061288881846148b6565b610d7391906149c5565b5f8061289f8585856121d6565b9092509050611f213383612f9a565b6128b6613813565b5f6128c3845f01516130cc565b6020850151909150156128dd576128dd84602001516130f3565b7f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b6001600160a01b0316632637a450826040518060a001604052808b63ffffffff16815260200161292d8c61223c565b81526020018a81526020018981526020015f8960200151111515815250866040518463ffffffff1660e01b8152600401612968929190614905565b60806040518083038185885af1158015612984573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906129a99190614a0c565b979650505050505050565b80516060901515806129fd5784846040516020016129e992919091825260c01b6001600160c01b031916602082015260280190565b604051602081830303815290604052612a24565b84843385604051602001612a149493929190614a71565b6040516020818303038152906040525b9150935093915050565b5f80516020614cbb8339815191527fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d102612a678482614ab3565b5060038101612a768382614ab3565b505f8082556001909101555050565b5f54610100900460ff16612aab5760405162461bcd60e51b8152600401610cd19061486b565b61210a82826131d2565b5f54610100900460ff16612adb5760405162461bcd60e51b8152600401610cd19061486b565b611f9f81613211565b5f54610100900460ff16612b0a5760405162461bcd60e51b8152600401610cd19061486b565b6112be3361217a565b6001600160a01b038316612b755760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610cd1565b6001600160a01b038216612bd65760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610cd1565b6001600160a01b038381165f8181526066602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b5f612c4460208284866146be565b610f5b91614b72565b5f612c5c6028602084866146be565b612c6591614b8f565b60c01c9392505050565b5f612c7a8484613240565b509092915050565b6060612c9182602881866146be565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250929695505050505050565b606084848484604051602001612ce59493929190614bbd565b6040516020818303038152906040529050949350505050565b6001600160a01b038316612d625760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610cd1565b6001600160a01b038216612dc45760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610cd1565b6001600160a01b0383165f9081526065602052604090205481811015612e3b5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610cd1565b6001600160a01b038085165f8181526065602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90612e9a9086815260200190565b60405180910390a3612455565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f612ed16132ff565b612ed9613367565b60408051602081019490945283019190915260608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b5f610d73612f266124c0565b8360405161190160f01b8152600281019290925260228201526042902090565b5f805f612f5385856133a9565b90925090505f816004811115612f6b57612f6b614c0b565b148015612f895750856001600160a01b0316826001600160a01b0316145b806110fb57506110fb8686866133e8565b6001600160a01b038216612ffa5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610cd1565b6001600160a01b0382165f908152606560205260409020548181101561306d5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610cd1565b6001600160a01b0383165f8181526065602090815260408083208686039055606780548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b5f8134146130ef576040516304fb820960e51b8152346004820152602401610cd1565b5090565b5f7f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b6001600160a01b031663e4fe1d946040518163ffffffff1660e01b8152600401602060405180830381865afa158015613150573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131749190614c1f565b90506001600160a01b03811661319d576040516329b99a9560e11b815260040160405180910390fd5b61210a6001600160a01b038216337f0000000000000000000000006f475642a6e85809b1c36fa62763669b1b48dd5b856134cf565b5f54610100900460ff166131f85760405162461bcd60e51b8152600401610cd19061486b565b60686132048382614ab3565b5060696121478282614ab3565b5f54610100900460ff166132375760405162461bcd60e51b8152600401610cd19061486b565b611f9f81613529565b6001600160a01b0382166132965760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610cd1565b8060675f8282546132a791906143bb565b90915550506001600160a01b0382165f818152606560209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b5f5f80516020614cbb833981519152816133176125a7565b80519091501561332f57805160209091012092915050565b8154801561333e579392505050565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470935050505090565b5f5f80516020614cbb8339815191528161337f612667565b80519091501561339757805160209091012092915050565b6001820154801561333e579392505050565b5f8082516041036133dd576020830151604084015160608501515f1a6133d187828585613576565b94509450505050610bfe565b505f90506002610bfe565b5f805f856001600160a01b0316631626ba7e60e01b8686604051602401613410929190614c3a565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161344e9190614c52565b5f60405180830381855afa9150503d805f8114613486576040519150601f19603f3d011682016040523d82523d5f602084013e61348b565b606091505b509150915081801561349f57506020815110155b80156110fb57508051630b135d3f60e11b906134c49083016020908101908401614c63565b149695505050505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612455908590613633565b5f54610100900460ff1661354f5760405162461bcd60e51b8152600401610cd19061486b565b6001600160a01b038116611ca457604051632d618d8160e21b815260040160405180910390fd5b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156135ab57505f9050600361362a565b604080515f8082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156135fc573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b038116613624575f6001925092505061362a565b91505f90505b94509492505050565b5f613687826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166137069092919063ffffffff16565b905080515f14806136a75750808060200190518101906136a79190614850565b6121475760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610cd1565b6060611a0784845f85855f80866001600160a01b0316858760405161372b9190614c52565b5f6040518083038185875af1925050503d805f8114613765576040519150601f19603f3d011682016040523d82523d5f602084013e61376a565b606091505b50915091506129a987838387606083156137e45782515f036137dd576001600160a01b0385163b6137dd5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610cd1565b5081611a07565b611a0783838151156137f95781518083602001fd5b8060405162461bcd60e51b8152600401610cd19190613918565b60405180606001604052805f80191681526020015f6001600160401b0316815260200161385160405180604001604052805f81526020015f81525090565b905290565b5f60e082840312156127e1575f80fd5b5f8060408385031215613877575f80fd5b82356001600160401b0381111561388c575f80fd5b61389885828601613856565b95602094909401359450505050565b5f5b838110156138c15781810151838201526020016138a9565b50505f910152565b5f81518084526138e08160208601602086016138a7565b601f01601f19169290920160200192915050565b604081525f61390660408301856138c9565b828103602084015261259e81856138c9565b602081525f610f5b60208301846138c9565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b03811182821017156139605761396061392a565b60405290565b604051601f8201601f191681016001600160401b038111828210171561398e5761398e61392a565b604052919050565b5f6001600160401b038211156139ae576139ae61392a565b50601f01601f191660200190565b5f82601f8301126139cb575f80fd5b81356139de6139d982613996565b613966565b8181528460208386010111156139f2575f80fd5b816020850160208301375f918101602001919091529392505050565b6001600160a01b0381168114611f9f575f80fd5b5f805f60608486031215613a34575f80fd5b83356001600160401b0380821115613a4a575f80fd5b613a56878388016139bc565b94506020860135915080821115613a6b575f80fd5b50613a78868287016139bc565b9250506040840135613a8981613a0e565b809150509250925092565b5f8060408385031215613aa5575f80fd5b8235613ab081613a0e565b946020939093013593505050565b5f60208284031215613ace575f80fd5b81356001600160401b03811115613ae3575f80fd5b611a0784828501613856565b83518152602080850151908201525f60a08201604060a0604085015281865180845260c08601915060c08160051b870101935060208089015f5b83811015613b685788870360bf19018552815180518852830151838801879052613b55878901826138c9565b9750509382019390820190600101613b29565b50508751606088015250505060208501516080850152509050611a07565b5f60208284031215613b96575f80fd5b5035919050565b5f606082840312156127e1575f80fd5b5f8083601f840112613bbd575f80fd5b5081356001600160401b03811115613bd3575f80fd5b602083019150836020828501011115610bfe575f80fd5b5f805f805f805f60e0888a031215613c00575f80fd5b613c0a8989613b9d565b96506060880135955060808801356001600160401b0380821115613c2c575f80fd5b613c388b838c01613bad565b909750955060a08a01359150613c4d82613a0e565b90935060c08901359080821115613c62575f80fd5b50613c6f8a828b01613bad565b989b979a50959850939692959293505050565b5f805f60608486031215613c94575f80fd5b8335613c9f81613a0e565b92506020840135613caf81613a0e565b929592945050506040919091013590565b803563ffffffff81168114613cd3575f80fd5b919050565b5f8060408385031215613ce9575f80fd5b613ab083613cc0565b8015158114611f9f575f80fd5b5f8060408385031215613d10575f80fd5b82356001600160401b03811115613d25575f80fd5b613d3185828601613856565b9250506020830135613d4281613cf2565b809150509250929050565b815181526020808301519082015260408101610d73565b803561ffff81168114613cd3575f80fd5b5f8060408385031215613d86575f80fd5b613d8f83613cc0565b9150613d9d60208401613d64565b90509250929050565b803560ff81168114613cd3575f80fd5b5f805f805f60a08688031215613dca575f80fd5b8535613dd581613a0e565b945060208601359350613dea60408701613da6565b94979396509394606081013594506080013592915050565b5f60208284031215613e12575f80fd5b8135610f5b81613a0e565b60ff60f81b881681525f602060e06020840152613e3d60e084018a6138c9565b8381036040850152613e4f818a6138c9565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825260208088019350909101905f5b81811015613ea257835183529284019291840191600101613e86565b50909c9b505050505050505050505050565b5f805f805f805f60e0888a031215613eca575f80fd5b8735613ed581613a0e565b96506020880135613ee581613a0e565b955060408801359450606088013593506080880135925060a0880135915060c08801356001600160401b03811115613f1b575f80fd5b613f278a828b016139bc565b91505092959891949750929550565b5f805f805f60a08688031215613f4a575f80fd5b8535613f5581613a0e565b94506020860135613f6581613a0e565b9350604086013592506060860135915060808601356001600160401b03811115613f8d575f80fd5b613f99888289016139bc565b9150509295509295909350565b6001600160401b0381168114611f9f575f80fd5b5f60208284031215613fca575f80fd5b8135610f5b81613fa6565b5f805f60608486031215613fe7575f80fd5b8335613ff281613a0e565b92506020840135915060408401356001600160401b03811115614013575f80fd5b61401f868287016139bc565b9150509250925092565b5f8083601f840112614039575f80fd5b5081356001600160401b0381111561404f575f80fd5b6020830191508360208260051b8501011115610bfe575f80fd5b5f806020838503121561407a575f80fd5b82356001600160401b0381111561408f575f80fd5b61409b85828601614029565b90969095509350505050565b5f602082840312156140b7575f80fd5b610f5b82613cc0565b5f805f80606085870312156140d3575f80fd5b6140dc85613cc0565b93506140ea60208601613d64565b925060408501356001600160401b03811115614104575f80fd5b61411087828801613bad565b95989497509550505050565b5f805f838503608081121561412f575f80fd5b84356001600160401b03811115614144575f80fd5b61415087828801613856565b9450506040601f1982011215614164575f80fd5b506020840191506060840135613a8981613a0e565b5f60c082019050835182526001600160401b03602085015116602083015260408401516141b3604084018280518252602090810151910152565b5082516080830152602083015160a0830152610f5b565b5f805f805f805f60e0888a0312156141e0575f80fd5b87356141eb81613a0e565b965060208801356141fb81613a0e565b9550604088013594506060880135935061421760808901613da6565b925060a0880135915060c0880135905092959891949750929550565b5f8060408385031215614244575f80fd5b823561424f81613a0e565b91506020830135613d4281613a0e565b5f805f805f805f805f6101208a8c031215614278575f80fd5b893561428381613a0e565b985060208a013561429381613a0e565b975060408a0135965060608a0135955060808a0135945060a08a013593506142bd60c08b01613da6565b925060e08a013591506101008a013590509295985092959850929598565b5f805f606084860312156142ed575f80fd5b833592506020840135915061430460408501613cc0565b90509250925092565b5f6060828403121561431d575f80fd5b610f5b8383613b9d565b600181811c9082168061433b57607f821691505b6020821081036127e157634e487b7160e01b5f52602260045260245ffd5b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b634e487b7160e01b5f52601160045260245ffd5b80820180821115610d7357610d736143a7565b928352602083019190915260f81b6001600160f81b031916604082015260410190565b9687526001600160a01b0395861660208801529390941660408601526060850191909152608084015260a083019190915260c082015260e00190565b634e487b7160e01b5f52603260045260245ffd5b5f8235605e19833603018112614455575f80fd5b9190910192915050565b5f808335601e19843603018112614474575f80fd5b8301803591506001600160401b0382111561448d575f80fd5b602001915036819003821315610bfe575f80fd5b5f602082840312156144b1575f80fd5b610f5b82613d64565b601f82111561214757805f5260205f20601f840160051c810160208510156144df5750805b601f840160051c820191505b8181101561122a575f81556001016144eb565b6001600160401b038311156145155761451561392a565b614529836145238354614327565b836144ba565b5f601f84116001811461455a575f85156145435750838201355b5f19600387901b1c1916600186901b17835561122a565b5f83815260208120601f198716915b828110156145895786850135825560209485019460019092019101614569565b50868210156145a5575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60208082528181018390525f906040808401600586901b8501820187855b888110156146b057878303603f190184528135368b9003605e19018112614622575f80fd5b8a01606063ffffffff61463483613cc0565b16855261ffff614645898401613d64565b168886015286820135601e1983360301811261465f575f80fd5b9091018781019190356001600160401b0381111561467b575f80fd5b803603831315614689575f80fd5b818887015261469b82870182856145b7565b968901969550505091860191506001016145fd565b509098975050505050505050565b5f80858511156146cc575f80fd5b838611156146d8575f80fd5b5050820193919092039150565b5f84516146f68184602089016138a7565b8201838582375f930192835250909392505050565b602081525f611a076020830184866145b7565b5f823561013e19833603018112614455575f80fd5b63ffffffff61474189613cc0565b168152602088013560208201525f604089013561475d81613fa6565b6001600160401b03811660408401525087606083015260e0608083015261478860e0830187896145b7565b6001600160a01b03861660a084015282810360c08401526147aa8185876145b7565b9a9950505050505050505050565b5f602082840312156147c8575f80fd5b81516001600160401b038111156147dd575f80fd5b8201601f810184136147ed575f80fd5b80516147fb6139d982613996565b81815285602083850101111561480f575f80fd5b61259e8260208301602086016138a7565b5f60408284031215614830575f80fd5b61483861393e565b82358152602083013560208201528091505092915050565b5f60208284031215614860575f80fd5b8151610f5b81613cf2565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b5f826148d057634e487b7160e01b5f52601260045260245ffd5b500490565b60018060a01b038516815283602082015261ffff83166040820152608060608201525f6110fb60808301846138c9565b6040815263ffffffff8351166040820152602083015160608201525f604084015160a0608084015261493a60e08401826138c9565b90506060850151603f198483030160a085015261495782826138c9565b60809690960151151560c08501525050506001600160a01b039190911660209091015290565b5f6040828403121561498d575f80fd5b61499561393e565b9050815181526020820151602082015292915050565b5f604082840312156149bb575f80fd5b610f5b838361497d565b8082028115828204841417610d7357610d736143a7565b6001600160f01b03198135818116916002851015614a045780818660020360031b1b83161692505b505092915050565b5f60808284031215614a1c575f80fd5b604051606081018181106001600160401b0382111715614a3e57614a3e61392a565b604052825181526020830151614a5381613fa6565b6020820152614a65846040850161497d565b60408201529392505050565b8481526001600160401b0360c01b8460c01b1660208201528260288201525f8251614aa38160488501602087016138a7565b9190910160480195945050505050565b81516001600160401b03811115614acc57614acc61392a565b614ae081614ada8454614327565b846144ba565b602080601f831160018114614b13575f8415614afc5750858301515b5f19600386901b1c1916600185901b178555614b6a565b5f85815260208120601f198616915b82811015614b4157888601518255948401946001909101908401614b22565b5085821015614b5e57878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b80356020831015610d73575f19602084900360031b1b1692915050565b6001600160c01b03198135818116916008851015614a045760089490940360031b84901b1690921692915050565b6001600160401b0360c01b8560c01b16815263ffffffff60e01b8460e01b16600882015282600c8201525f8251614bfb81602c8501602087016138a7565b91909101602c0195945050505050565b634e487b7160e01b5f52602160045260245ffd5b5f60208284031215614c2f575f80fd5b8151610f5b81613a0e565b828152604060208201525f611a0760408301846138c9565b5f82516144558184602087016138a7565b5f60208284031215614c73575f80fd5b505191905056fe72ab1bc1039b79dc4724ffca13de82c96834302d3c7e0d4252232d4b2dd8f9006607eb842e76408d8b3956685dc6b9da5897a1d9b47edcc993ce266e603fa500a16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100a2646970667358221220f1551093d0a4fc78776efc5a6799d0f3e995df8f490a6fd6fcf58686806ca94b64736f6c63430008160033
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
239510:2757:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;241383:238;;;;;;;;;;-1:-1:-1;241383:238:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;137061:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;240060:274::-;;;;;;;;;;-1:-1:-1;240060:274:0;;;;;:::i;:::-;;:::i;:::-;;139421:201;;;;;;;;;;-1:-1:-1;139421:201:0;;;;;:::i;:::-;;:::i;:::-;;;4379:14:1;;4372:22;4354:41;;4342:2;4327:18;139421:201:0;4214:187:1;220716:1283:0;;;;;;;;;;-1:-1:-1;220716:1283:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;240850:115::-;;;;;;;;;;-1:-1:-1;240850:115:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;6612:31:1;;;6594:50;;6582:2;6567:18;240850:115:0;6450:200:1;218958:152:0;;;;;;;;;;;;;:::i;:::-;;;-1:-1:-1;;;;;6819:32:1;;;6801:51;;6789:2;6774:18;218958:152:0;6655:203:1;190775:723:0;;;;;;:::i;:::-;;:::i;217632:40::-;;;;;;;;;;;;217671:1;217632:40;;;;;8601:6:1;8589:19;;;8571:38;;8559:2;8544:18;217632:40:0;8427:188:1;236884:142:0;;;;;;;;;;-1:-1:-1;236884:142:0;;;-1:-1:-1;;;8790:52:1;;237016:1:0;8873:2:1;8858:18;;8851:59;8763:18;236884:142:0;8620:296:1;215350:265:0;;;;;;;;;;-1:-1:-1;215350:265:0;;;195611:1;9128:34:1;;;9193:2;9178:18;;9171:43;9064:18;215350:265:0;8921:299:1;138190:108:0;;;;;;;;;;-1:-1:-1;138278:12:0;;138190:108;;;9371:25:1;;;9359:2;9344:18;138190:108:0;9225: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;;;10040:4:1;10028:17;;;10010:36;;9998:2;9983:18;138032:93:0;9868:184:1;166274:206:0;;;;;;;;;;-1:-1:-1;166274:206:0;;;;;:::i;:::-;;:::i;194314:106::-;;;;;;;;;;;;;:::i;240422: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;;239702:88;;;;;;;;;;;;;:::i;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;;137280:104;;;;;;;;;;;;;:::i;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;240727:115::-;;;;;;;;;;-1:-1:-1;240727: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;240973:126::-;;;;;;;;;;-1:-1:-1;240973: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;241107:268::-;;;;;;;;;;-1:-1:-1;241107:268:0;;;;;:::i;:::-;;:::i;:::-;;;;23428:25:1;;;23484:2;23469:18;;23462:34;;;;23401:18;241107:268:0;23254:248:1;115417:201:0;;;;;;;;;;-1:-1:-1;115417:201:0;;;;;:::i;:::-;;:::i;189146:151::-;;;;;;;;;;-1:-1:-1;189146:151:0;;;;;:::i;:::-;;:::i;241383:238::-;241509:20;241531;241571:42;241591:10;241603:9;241571:19;:42::i;:::-;241564:49;;;;241383:238;;;;;;:::o;137061:100::-;137115:13;137148:5;137141:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;137061:100;:::o;240060:274::-;84696:13;;240166: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;;;;;;;:::i;:::-;;;;;;;;;84797:12;:22;;-1:-1:-1;;84830:20:0;84797:22;;;84830:20;84797:22;84830:20;;;240180:31:::1;240194:5:::0;240201:9:::1;:7;:9::i;:::-;240180:13;:31::i;:::-;240222:37;240233:5;240240:7;240249:9;240222:10;:37::i;:::-;240270:16;:14;:16::i;:::-;240297:29;240316:9;240297:18;:29::i;:::-;84889:5:::0;84873:21;;-1:-1:-1;;84873:21:0;;;84910:20;;10040:4:1;10028:17;;10010:36;;84910:20:0;;9998:2:1;9983:18;84910:20:0;;;;;;;240060:274;;;;:::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;240850:115::-;240906:15;240941:16;240947:9;240941: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;;;6801:51:1;6774:18;;191128:24:0;6655:203:1;191084:68:0;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;;24750:10:1;24738:23;;;191314:40:0;;;24720:42:1;191339:14:0;;;;24778:18:1;;;24771:34;24693:18;;191314:40:0;24548: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;;24720:42:1;;;24778:18;;24771:34;;;164123:23:0;166452:20:::1;::::0;24693: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;240422:103::-;84696:13;;240471: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;;;;;;;:::i;:::-;84797:12;:22;;-1:-1:-1;;84830:20:0;84797:22;;;84830:20;84797:22;84830:20;;;240485:32:::1;240499:6;:4;:6::i;:::-;240507:9;:7;:9::i;240485:32::-;84889:5:::0;84873:21;;-1:-1:-1;;84873:21:0;;;84910:20;;10040:4:1;10028:17;;10010:36;;84910:20:0;;9998:2:1;9983:18;84910:20:0;;;;;;;240422: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;239702:88::-;239768:14;;;;;;;;;;;;-1:-1:-1;;;239768:14:0;;;;;239702:88::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;6801:51:1;;;220363:30:0::1;::::0;6789:2:1;6774: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;;25623:2:1;131652:77:0;;;25605:21:1;25662:2;25642:18;;;25635:30;-1:-1:-1;;;25681:18:1;;;25674:51;25742:18;;131652:77:0;25421: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;;;25983:34:1;-1:-1:-1;;;;;26053:15:1;;26033:18;;;26026:43;25918:18;;180052:47:0;25771: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;137280:104::-;137336:13;137369:7;137362:14;;;;;:::i;193574:536::-;193784:8;193765:15;:27;;193757:69;;;;-1:-1:-1;;;193757:69:0;;26950:2:1;193757:69:0;;;26932:21:1;26989:2;26969:18;;;26962:30;27028:31;27008:18;;;27001:59;27077:18;;193757:69:0;26748: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;;;;;;27393:25:1;;;;-1:-1:-1;;;;;27492:15:1;;;27472:18;;;27465:43;27544:15;;;;27524:18;;;27517:43;27576:18;;;27569:34;27619:19;;;27612:35;27663:19;;;27656:35;;;27365:19;;193932:78:0;27106: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;;27904:2:1;141825:85:0;;;27886:21:1;27943:2;27923:18;;;27916:30;27982:34;27962:18;;;27955:62;-1:-1:-1;;;28033:18:1;;;28026:35;28078:19;;141825:85:0;27702: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;240727:115::-;240782:16;240818;240824:9;240818: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;;;28310:25:1;-1:-1:-1;;;;;28371:32:1;;28351:18;;;28344:60;;;;28420:18;;;28413:34;;;182065:206:0;;182116:10;;28283:18:1;;182163:60:0;28108: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;240973:126::-;241033:16;241069:22;241081:9;241069: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;;;37348:10:1;37336:23;;;37318:42;;37391:2;37376:18;;37369:34;;;37419:18;;37412:34;;;37306:2;37291: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;;;;;6819:32:1;;;167463:31:0::1;::::0;::::1;6801:51:1::0;167463:8:0::1;:20;::::0;::::1;::::0;6774: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;6801:51:1;;;209412:22:0::1;::::0;6789:2:1;6774:18;209412:22:0::1;6655: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;241107:268::-;241206:20;241228:24;241323:44;241334:9;241345:12;241359:7;241323:10;:44::i;:::-;241316:51;;;;241107: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;;37659:2:1;115498:73:0::1;::::0;::::1;37641:21:1::0;37698:2;37678:18;;;37671:30;37737:34;37717:18;;;37710:62;-1:-1:-1;;;37788:18:1;;;37781:36;37834:19;;115498:73:0::1;37457: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;129299:132::-;129385:38;129409:4;129415:7;129385:23;:38::i;:::-;129299:132;;:::o;236097:192::-;85201:13;;;;;;;85193:69;;;;-1:-1:-1;;;85193:69:0;;;;;;;:::i;:::-;236217:28:::1;236230:5;236237:7;236217:12;:28::i;:::-;236256:25;236271:9;236256:14;:25::i;:::-;236097:192:::0;;;:::o;114061:97::-;85201:13;;;;;;;85193:69;;;;-1:-1:-1;;;85193:69:0;;;;;;;:::i;:::-;114124:26:::1;:24;:26::i;115778:191::-:0;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;242073:::-;242207:49;242233:5;242240:7;242249:6;242207:25;:49::i;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;;;;;23428:25:1;;;23469:18;;;23462:34;;;23401:18;;233494:48:0;23254: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;;38922:10:1;38910:23;;167006:12:0;;;38892:42:1;38865:18;;167006:12:0;38748: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;;;24750:10:1;24738:23;;;24720:42;;24793:2;24778:18;;24771:34;;;24693: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;;39898:2:1;146465:68:0;;;39880:21:1;39937:2;39917:18;;;39910:30;39976:31;39956:18;;;39949:59;40025:18;;146465:68:0;39696: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;241852:182::-;241982:44;242009:4;242015:2;242019:6;241982: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;;40256:2:1;114739:68:0;;;40238:21:1;;;40275:18;;;40268:30;40334:34;40314:18;;;40307:62;40386:18;;114739:68:0;40054:356:1;129851:111:0;129904:7;129931:23;:21;:23::i;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;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;;;;;;;;43201:19:1;;;43276:3;43254:16;-1:-1:-1;;;;;;43250:51:1;43245:2;43236:12;;43229:73;43327:2;43318:12;;43046:290;74386:40:0;;;;;;;;;;;;;74261:165;;;74304:7;74313:13;74345:10;74358:11;74287:83;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;74261:165;74254:172;;73918:516;;;;;;:::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;136672:149::-;85201:13;;;;;;;85193:69;;;;-1:-1:-1;;;85193:69:0;;;;;;;:::i;:::-;136775:38:::1;136798:5;136805:7;136775:22;:38::i;218764:114::-:0;85201:13;;;;;;;85193:69;;;;-1:-1:-1;;;85193:69:0;;;;;;;:::i;:::-;218844:26:::1;218860:9;218844:15;:26::i;114166:113::-:0;85201:13;;;;;;;85193:69;;;;-1:-1:-1;;;85193:69:0;;;;;;;:::i;:::-;114239:32:::1;87451:10:::0;114239:18:::1;:32::i;145606:346::-:0;-1:-1:-1;;;;;145708:19:0;;145700:68;;;;-1:-1:-1;;;145700:68:0;;45428:2:1;145700:68:0;;;45410:21:1;45467:2;45447:18;;;45440:30;45506:34;45486:18;;;45479:62;-1:-1:-1;;;45557:18:1;;;45550:34;45601:19;;145700:68:0;45226:400:1;145700:68:0;-1:-1:-1;;;;;145787:21:0;;145779:68;;;;-1:-1:-1;;;145779:68:0;;45833:2:1;145779:68:0;;;45815:21:1;45872:2;45852:18;;;45845:30;45911:34;45891:18;;;45884:62;-1:-1:-1;;;45962:18:1;;;45955:32;46004:19;;145779:68:0;45631:398:1;145779:68:0;-1:-1:-1;;;;;145860:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;145912:32;;9371:25:1;;;145912:32:0;;9344: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;;47405:2:1;142608:68:0;;;47387:21:1;47444:2;47424:18;;;47417:30;47483:34;47463:18;;;47456:62;-1:-1:-1;;;47534:18:1;;;47527:35;47579:19;;142608:68:0;47203:401:1;142608:68:0;-1:-1:-1;;;;;142695:16:0;;142687:64;;;;-1:-1:-1;;;142687:64:0;;47811:2:1;142687:64:0;;;47793:21:1;47850:2;47830:18;;;47823:30;47889:34;47869:18;;;47862:62;-1:-1:-1;;;47940:18:1;;;47933:33;47983:19;;142687:64:0;47609: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;;48215:2:1;142863:72:0;;;48197:21:1;48254:2;48234:18;;;48227:30;48293:34;48273:18;;;48266:62;-1:-1:-1;;;48344:18:1;;;48337:36;48390:19;;142863:72:0;48013:402:1;142863:72:0;-1:-1:-1;;;;;142971:15:0;;;;;;;:9;:15;;;;;;142989:20;;;142971:38;;143189:13;;;;;;;;;;:23;;;;;;143241:26;;;;;;143003:6;9371:25:1;;9359:2;9344:18;;9225:177;143241:26:0;;;;;;;;143280:37;236097:192;129970:193;130025:7;127892:95;130084:17;:15;:17::i;:::-;130103:20;:18;:20::i;:::-;130062:92;;;;;;48679:25:1;;;;48720:18;;48713:34;;;;48763:18;;;48756:34;130125:13:0;48806:18:1;;;48799:34;130148:4:0;48849:19:1;;;48842:61;48651:19;;130062:92:0;;;;;;;;;;;;130052:103;;;;;;130045:110;;129970:193;:::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;;49248:2:1;144569:67:0;;;49230:21:1;49287:2;49267:18;;;49260:30;49326:34;49306:18;;;49299:62;-1:-1:-1;;;49377:18:1;;;49370:31;49418:19;;144569:67:0;49046: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;;49650:2:1;144765:71:0;;;49632:21:1;49689:2;49669:18;;;49662:30;49728:34;49708:18;;;49701:62;-1:-1:-1;;;49779:18:1;;;49772:32;49821:19;;144765:71:0;49448:398:1;144765:71:0;-1:-1:-1;;;;;144872:18:0;;;;;;:9;:18;;;;;;;;144893:23;;;144872:44;;145011:12;:22;;;;;;;145062:37;9371:25:1;;;144872:18:0;;;145062:37;;9344:18:1;145062:37:0;;;;;;;236097:192;;;:::o;199819:194::-;199885:17;199932:10;199919:9;:23;199915:62;;199951:26;;-1:-1:-1;;;199951:26:0;;199967:9;199951:26;;;9371:25:1;9344:18;;199951:26:0;9225: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;136829:162::-;85201:13;;;;;;;85193:69;;;;-1:-1:-1;;;85193:69:0;;;;;;;:::i;:::-;136942:5:::1;:13;136950:5:::0;136942;:13:::1;:::i;:::-;-1:-1:-1::0;136966:7:0::1;:17;136976:7:::0;136966;:17:::1;:::i;165004:125::-:0;85201:13;;;;;;;85193:69;;;;-1:-1:-1;;;85193:69:0;;;;;;;:::i;:::-;165085:36:::1;165111:9;165085:25;:36::i;143612:548::-:0;-1:-1:-1;;;;;143696:21:0;;143688:65;;;;-1:-1:-1;;;143688:65:0;;50309:2:1;143688:65:0;;;50291:21:1;50348:2;50328:18;;;50321:30;50387:33;50367:18;;;50360:61;50438:18;;143688:65:0;50107:355:1;143688:65:0;143844:6;143828:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;143999:18:0;;;;;;:9;:18;;;;;;;;:28;;;;;;144054:37;9371:25:1;;;144054:37:0;;9344: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;;;;;51499:15:1;;;117698:68:0;;;51481:34:1;51551:15;;51531:18;;;51524:43;51583:18;;;;51576:34;;;117698:68:0;;;;;;;;;;51416: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;165137:194::-;85201:13;;;;;;;85193:69;;;;-1:-1:-1;;;85193:69:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;165232:23:0;::::1;165228:53;;165264:17;;-1:-1:-1::0;;;165264:17:0::1;;;;;;;;;;;99497:1477:::0;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;;;;;;;;;51848:25:1;;;51921:4;51909:17;;51889:18;;;51882:45;;;;51943:18;;;51936:34;;;51986:18;;;51979:34;;;100779:24:0;;51820: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;;52226:2:1;122024:111:0;;;52208:21:1;52265:2;52245:18;;;52238:30;52304:34;52284:18;;;52277:62;-1:-1:-1;;;52355:18:1;;;52348:40;52405:19;;122024:111:0;52024: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;;53044:2:1;8423:60:0;;;53026:21:1;53083:2;53063:18;;;53056:30;53122:31;53102:18;;;53095:59;53171:18;;8423:60:0;52842: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:127::-;1807:10;1802:3;1798:20;1795:1;1788:31;1838:4;1835:1;1828:15;1862:4;1859:1;1852:15;1878:251;1950:2;1944:9;;;1980:15;;-1:-1:-1;;;;;2010:34:1;;2046:22;;;2007:62;2004:88;;;2072:18;;:::i;:::-;2108:2;2101:22;1878:251;:::o;2134:275::-;2205:2;2199:9;2270:2;2251:13;;-1:-1:-1;;2247:27:1;2235:40;;-1:-1:-1;;;;;2290:34:1;;2326:22;;;2287:62;2284:88;;;2352:18;;:::i;:::-;2388:2;2381:22;2134:275;;-1:-1:-1;2134:275:1:o;2414:187::-;2463:4;-1:-1:-1;;;;;2488:6:1;2485:30;2482:56;;;2518:18;;:::i;:::-;-1:-1:-1;2584:2:1;2563:15;-1:-1:-1;;2559:29:1;2590:4;2555:40;;2414:187::o;2606:464::-;2649:5;2702:3;2695:4;2687:6;2683:17;2679:27;2669:55;;2720:1;2717;2710:12;2669:55;2756:6;2743:20;2787:49;2803:32;2832:2;2803:32;:::i;:::-;2787:49;:::i;:::-;2861:2;2852:7;2845:19;2907:3;2900:4;2895:2;2887:6;2883:15;2879:26;2876:35;2873:55;;;2924:1;2921;2914:12;2873:55;2989:2;2982:4;2974:6;2970:17;2963:4;2954:7;2950:18;2937:55;3037:1;3012:16;;;3030:4;3008:27;3001:38;;;;3016:7;2606:464;-1:-1:-1;;;2606:464:1:o;3075:131::-;-1:-1:-1;;;;;3150:31:1;;3140:42;;3130:70;;3196:1;3193;3186:12;3211:678;3308:6;3316;3324;3377:2;3365:9;3356:7;3352:23;3348:32;3345:52;;;3393:1;3390;3383:12;3345:52;3433:9;3420:23;-1:-1:-1;;;;;3503:2:1;3495:6;3492:14;3489:34;;;3519:1;3516;3509:12;3489:34;3542:50;3584:7;3575:6;3564:9;3560:22;3542:50;:::i;:::-;3532:60;;3645:2;3634:9;3630:18;3617:32;3601:48;;3674:2;3664:8;3661:16;3658:36;;;3690:1;3687;3680:12;3658:36;;3713:52;3757:7;3746:8;3735:9;3731:24;3713:52;:::i;:::-;3703:62;;;3815:2;3804:9;3800:18;3787:32;3828:31;3853:5;3828:31;:::i;:::-;3878:5;3868:15;;;3211:678;;;;;:::o;3894:315::-;3962:6;3970;4023:2;4011:9;4002:7;3998:23;3994:32;3991:52;;;4039:1;4036;4029:12;3991:52;4078:9;4065:23;4097:31;4122:5;4097:31;:::i;:::-;4147:5;4199:2;4184:18;;;;4171:32;;-1:-1:-1;;;3894:315:1:o;4406:360::-;4494:6;4547:2;4535:9;4526:7;4522:23;4518:32;4515:52;;;4563:1;4560;4553:12;4515:52;4603:9;4590:23;-1:-1:-1;;;;;4628:6:1;4625:30;4622:50;;;4668:1;4665;4658:12;4622:50;4691:69;4752:7;4743:6;4732:9;4728:22;4691:69;:::i;4925:1335::-;4845:12;;4833:25;;4907:4;4896:16;;;4890:23;4874:14;;;4867:47;5291:4;5339:3;5324:19;;5416:2;5454:3;5449:2;5438:9;5434:18;5427:31;5478:6;5513;5507:13;5544:6;5536;5529:22;5582:3;5571:9;5567:19;5560:26;;5645:3;5635:6;5632:1;5628:14;5617:9;5613:30;5609:40;5595:54;;5668:4;5707;5699:6;5695:17;5730:1;5740:428;5754:6;5751:1;5748:13;5740:428;;;5819:22;;;-1:-1:-1;;5815:37:1;5803:50;;5876:13;;5917:9;;5902:25;;5966:11;;5960:18;5998:15;;;5991:27;;;6041:47;6072:15;;;5960:18;6041:47;:::i;:::-;6031:57;-1:-1:-1;;6146:12:1;;;;6111:15;;;;5776:1;5769:9;5740:428;;;-1:-1:-1;;4845:12:1;;6250:2;6235:18;;4833:25;-1:-1:-1;;;4907:4:1;4896:16;;4890:23;4874:14;;;4867:47;-1:-1:-1;6185:6:1;-1:-1:-1;6200:54:1;4771:149;6265:180;6324:6;6377:2;6365:9;6356:7;6352:23;6348:32;6345:52;;;6393:1;6390;6383:12;6345:52;-1:-1:-1;6416:23:1;;6265:180;-1:-1:-1;6265:180:1:o;6863:154::-;6922:5;6967:2;6958:6;6953:3;6949:16;6945:25;6942:45;;;6983:1;6980;6973:12;7022:347;7073:8;7083:6;7137:3;7130:4;7122:6;7118:17;7114:27;7104:55;;7155:1;7152;7145:12;7104:55;-1:-1:-1;7178:20:1;;-1:-1:-1;;;;;7210:30:1;;7207:50;;;7253:1;7250;7243:12;7207:50;7290:4;7282:6;7278:17;7266:29;;7342:3;7335:4;7326:6;7318;7314:19;7310:30;7307:39;7304:59;;;7359:1;7356;7349:12;7374:1048;7517:6;7525;7533;7541;7549;7557;7565;7618:3;7606:9;7597:7;7593:23;7589:33;7586:53;;;7635:1;7632;7625:12;7586:53;7658;7703:7;7692:9;7658:53;:::i;:::-;7648:63;;7758:2;7747:9;7743:18;7730:32;7720:42;;7813:3;7802:9;7798:19;7785:33;-1:-1:-1;;;;;7878:2:1;7870:6;7867:14;7864:34;;;7894:1;7891;7884:12;7864:34;7933:58;7983:7;7974:6;7963:9;7959:22;7933:58;:::i;:::-;8010:8;;-1:-1:-1;7907:84:1;-1:-1:-1;8095:3:1;8080:19;;8067:33;;-1:-1:-1;8109:31:1;8067:33;8109:31;:::i;:::-;8159:5;;-1:-1:-1;8217:3:1;8202:19;;8189:33;;8234:16;;;8231:36;;;8263:1;8260;8253:12;8231:36;;8302:60;8354:7;8343:8;8332:9;8328:24;8302:60;:::i;:::-;7374:1048;;;;-1:-1:-1;7374:1048:1;;-1:-1:-1;7374:1048:1;;;;8276:86;;-1:-1:-1;;;7374:1048:1:o;9407:456::-;9484:6;9492;9500;9553:2;9541:9;9532:7;9528:23;9524:32;9521:52;;;9569:1;9566;9559:12;9521:52;9608:9;9595:23;9627:31;9652:5;9627:31;:::i;:::-;9677:5;-1:-1:-1;9734:2:1;9719:18;;9706:32;9747:33;9706:32;9747:33;:::i;:::-;9407:456;;9799:7;;-1:-1:-1;;;9853:2:1;9838:18;;;;9825:32;;9407:456::o;10057:163::-;10124:20;;10184:10;10173:22;;10163:33;;10153:61;;10210:1;10207;10200:12;10153:61;10057:163;;;:::o;10225:252::-;10292:6;10300;10353:2;10341:9;10332:7;10328:23;10324:32;10321:52;;;10369:1;10366;10359:12;10321:52;10392:28;10410:9;10392:28;:::i;10664:118::-;10750:5;10743:13;10736:21;10729:5;10726:32;10716:60;;10772:1;10769;10762:12;10787:489;10881:6;10889;10942:2;10930:9;10921:7;10917:23;10913:32;10910:52;;;10958:1;10955;10948:12;10910:52;10998:9;10985:23;-1:-1:-1;;;;;11023:6:1;11020:30;11017:50;;;11063:1;11060;11053:12;11017:50;11086:69;11147:7;11138:6;11127:9;11123:22;11086:69;:::i;:::-;11076:79;;;11205:2;11194:9;11190:18;11177:32;11218:28;11240:5;11218:28;:::i;:::-;11265:5;11255:15;;;10787:489;;;;;:::o;11281:257::-;4845:12;;4833:25;;4907:4;4896:16;;;4890:23;4874:14;;;4867:47;11475:2;11460:18;;11487:45;4771:149;11543:159;11610:20;;11670:6;11659:18;;11649:29;;11639:57;;11692:1;11689;11682:12;11707:256;11773:6;11781;11834:2;11822:9;11813:7;11809:23;11805:32;11802:52;;;11850:1;11847;11840:12;11802:52;11873:28;11891:9;11873:28;:::i;:::-;11863:38;;11920:37;11953:2;11942:9;11938:18;11920:37;:::i;:::-;11910:47;;11707:256;;;;;:::o;12190:156::-;12256:20;;12316:4;12305:16;;12295:27;;12285:55;;12336:1;12333;12326:12;12351:523;12444:6;12452;12460;12468;12476;12529:3;12517:9;12508:7;12504:23;12500:33;12497:53;;;12546:1;12543;12536:12;12497:53;12585:9;12572:23;12604:31;12629:5;12604:31;:::i;:::-;12654:5;-1:-1:-1;12706:2:1;12691:18;;12678:32;;-1:-1:-1;12729:36:1;12761:2;12746:18;;12729:36;:::i;:::-;12351:523;;;;-1:-1:-1;12719:46:1;;12812:2;12797:18;;12784:32;;-1:-1:-1;12863:3:1;12848:19;12835:33;;12351:523;-1:-1:-1;;12351:523:1:o;13116:247::-;13175:6;13228:2;13216:9;13207:7;13203:23;13199:32;13196:52;;;13244:1;13241;13234:12;13196:52;13283:9;13270:23;13302:31;13327:5;13302:31;:::i;13368:1257::-;13774:3;13769;13765:13;13757:6;13753:26;13742:9;13735:45;13716:4;13799:2;13837:3;13832:2;13821:9;13817:18;13810:31;13864:45;13904:3;13893:9;13889:19;13881:6;13864:45;:::i;:::-;13957:9;13949:6;13945:22;13940:2;13929:9;13925:18;13918:50;13991:32;14016:6;14008;13991:32;:::i;:::-;14054:2;14039:18;;14032:34;;;-1:-1:-1;;;;;14103:32:1;;14097:3;14082:19;;14075:61;14123:3;14152:19;;14145:35;;;14217:22;;;14211:3;14196:19;;14189:51;14289:13;;14311:22;;;14361:2;14387:15;;;;-1:-1:-1;14349:15:1;;;;-1:-1:-1;14430:169:1;14444:6;14441:1;14438:13;14430:169;;;14505:13;;14493:26;;14574:15;;;;14539:12;;;;14466:1;14459:9;14430:169;;;-1:-1:-1;14616:3:1;;13368:1257;-1:-1:-1;;;;;;;;;;;;13368:1257:1:o;14630:873::-;14752:6;14760;14768;14776;14784;14792;14800;14853:3;14841:9;14832:7;14828:23;14824:33;14821:53;;;14870:1;14867;14860:12;14821:53;14909:9;14896:23;14928:31;14953:5;14928:31;:::i;:::-;14978:5;-1:-1:-1;15035:2:1;15020:18;;15007:32;15048:33;15007:32;15048:33;:::i;:::-;15100:7;-1:-1:-1;15154:2:1;15139:18;;15126:32;;-1:-1:-1;15205:2:1;15190:18;;15177:32;;-1:-1:-1;15256:3:1;15241:19;;15228:33;;-1:-1:-1;15308:3:1;15293:19;;15280:33;;-1:-1:-1;15364:3:1;15349:19;;15336:33;-1:-1:-1;;;;;15381:30:1;;15378:50;;;15424:1;15421;15414:12;15378:50;15447;15489:7;15480:6;15469:9;15465:22;15447:50;:::i;:::-;15437:60;;;14630:873;;;;;;;;;;:::o;15508:735::-;15612:6;15620;15628;15636;15644;15697:3;15685:9;15676:7;15672:23;15668:33;15665:53;;;15714:1;15711;15704:12;15665:53;15753:9;15740:23;15772:31;15797:5;15772:31;:::i;:::-;15822:5;-1:-1:-1;15879:2:1;15864:18;;15851:32;15892:33;15851:32;15892:33;:::i;:::-;15944:7;-1:-1:-1;15998:2:1;15983:18;;15970:32;;-1:-1:-1;16049:2:1;16034:18;;16021:32;;-1:-1:-1;16104:3:1;16089:19;;16076:33;-1:-1:-1;;;;;16121:30:1;;16118:50;;;16164:1;16161;16154:12;16118:50;16187;16229:7;16220:6;16209:9;16205:22;16187:50;:::i;:::-;16177:60;;;15508:735;;;;;;;;:::o;16248:129::-;-1:-1:-1;;;;;16326:5:1;16322:30;16315:5;16312:41;16302:69;;16367:1;16364;16357:12;16382:245;16440:6;16493:2;16481:9;16472:7;16468:23;16464:32;16461:52;;;16509:1;16506;16499:12;16461:52;16548:9;16535:23;16567:30;16591:5;16567:30;:::i;16632:524::-;16718:6;16726;16734;16787:2;16775:9;16766:7;16762:23;16758:32;16755:52;;;16803:1;16800;16793:12;16755:52;16842:9;16829:23;16861:31;16886:5;16861:31;:::i;:::-;16911:5;-1:-1:-1;16963:2:1;16948:18;;16935:32;;-1:-1:-1;17018:2:1;17003:18;;16990:32;-1:-1:-1;;;;;17034:30:1;;17031:50;;;17077:1;17074;17067:12;17031:50;17100;17142:7;17133:6;17122:9;17118:22;17100:50;:::i;:::-;17090:60;;;16632:524;;;;;:::o;17161:395::-;17252:8;17262:6;17316:3;17309:4;17301:6;17297:17;17293:27;17283:55;;17334:1;17331;17324:12;17283:55;-1:-1:-1;17357:20:1;;-1:-1:-1;;;;;17389:30:1;;17386:50;;;17432:1;17429;17422:12;17386:50;17469:4;17461:6;17457:17;17445:29;;17529:3;17522:4;17512:6;17509:1;17505:14;17497:6;17493:27;17489:38;17486:47;17483:67;;;17546:1;17543;17536:12;17561:504;17686:6;17694;17747:2;17735:9;17726:7;17722:23;17718:32;17715:52;;;17763:1;17760;17753:12;17715:52;17803:9;17790:23;-1:-1:-1;;;;;17828:6:1;17825:30;17822:50;;;17868:1;17865;17858:12;17822:50;17907:98;17997:7;17988:6;17977:9;17973:22;17907:98;:::i;:::-;18024:8;;17881:124;;-1:-1:-1;17561:504:1;-1:-1:-1;;;;17561:504:1:o;18070:184::-;18128:6;18181:2;18169:9;18160:7;18156:23;18152:32;18149:52;;;18197:1;18194;18187:12;18149:52;18220:28;18238:9;18220:28;:::i;18259:553::-;18345:6;18353;18361;18369;18422:2;18410:9;18401:7;18397:23;18393:32;18390:52;;;18438:1;18435;18428:12;18390:52;18461:28;18479:9;18461:28;:::i;:::-;18451:38;;18508:37;18541:2;18530:9;18526:18;18508:37;:::i;:::-;18498:47;;18596:2;18585:9;18581:18;18568:32;-1:-1:-1;;;;;18615:6:1;18612:30;18609:50;;;18655:1;18652;18645:12;18609:50;18694:58;18744:7;18735:6;18724:9;18720:22;18694:58;:::i;:::-;18259:553;;;;-1:-1:-1;18771:8:1;-1:-1:-1;;;;18259:553:1:o;19320:657::-;19458:6;19466;19474;19518:9;19509:7;19505:23;19548:3;19544:2;19540:12;19537:32;;;19565:1;19562;19555:12;19537:32;19605:9;19592:23;-1:-1:-1;;;;;19630:6:1;19627:30;19624:50;;;19670:1;19667;19660:12;19624:50;19693:69;19754:7;19745:6;19734:9;19730:22;19693:69;:::i;:::-;19683:79;-1:-1:-1;;19796:2:1;-1:-1:-1;;19778:16:1;;19774:25;19771:45;;;19812:1;19809;19802:12;19771:45;;19850:2;19839:9;19835:18;19825:28;;19903:2;19892:9;19888:18;19875:32;19916:31;19941:5;19916:31;:::i;19982:613::-;20226:4;20268:3;20257:9;20253:19;20245:27;;20305:6;20299:13;20288:9;20281:32;-1:-1:-1;;;;;20373:4:1;20365:6;20361:17;20355:24;20351:49;20344:4;20333:9;20329:20;20322:79;20448:4;20440:6;20436:17;20430:24;20463:62;20519:4;20508:9;20504:20;20490:12;4845;;4833:25;;4907:4;4896:16;;;4890:23;4874:14;;4867:47;4771:149;20463:62;-1:-1:-1;4845:12:1;;20584:3;20569:19;;4833:25;4907:4;4896:16;;4890:23;4874:14;;;4867:47;20534:55;4771:149;20600:734;20711:6;20719;20727;20735;20743;20751;20759;20812:3;20800:9;20791:7;20787:23;20783:33;20780:53;;;20829:1;20826;20819:12;20780:53;20868:9;20855:23;20887:31;20912:5;20887:31;:::i;:::-;20937:5;-1:-1:-1;20994:2:1;20979:18;;20966:32;21007:33;20966:32;21007:33;:::i;:::-;21059:7;-1:-1:-1;21113:2:1;21098:18;;21085:32;;-1:-1:-1;21164:2:1;21149:18;;21136:32;;-1:-1:-1;21187:37:1;21219:3;21204:19;;21187:37;:::i;:::-;21177:47;;21271:3;21260:9;21256:19;21243:33;21233:43;;21323:3;21312:9;21308:19;21295:33;21285:43;;20600:734;;;;;;;;;;:::o;21339:388::-;21407:6;21415;21468:2;21456:9;21447:7;21443:23;21439:32;21436:52;;;21484:1;21481;21474:12;21436:52;21523:9;21510:23;21542:31;21567:5;21542:31;:::i;:::-;21592:5;-1:-1:-1;21649:2:1;21634:18;;21621:32;21662:33;21621:32;21662:33;:::i;21732:872::-;21861:6;21869;21877;21885;21893;21901;21909;21917;21925;21978:3;21966:9;21957:7;21953:23;21949:33;21946:53;;;21995:1;21992;21985:12;21946:53;22034:9;22021:23;22053:31;22078:5;22053:31;:::i;:::-;22103:5;-1:-1:-1;22160:2:1;22145:18;;22132:32;22173:33;22132:32;22173:33;:::i;:::-;22225:7;-1:-1:-1;22279:2:1;22264:18;;22251:32;;-1:-1:-1;22330:2:1;22315:18;;22302:32;;-1:-1:-1;22381:3:1;22366:19;;22353:33;;-1:-1:-1;22433:3:1;22418:19;;22405:33;;-1:-1:-1;22457:37:1;22489:3;22474:19;;22457:37;:::i;:::-;22447:47;;22541:3;22530:9;22526:19;22513:33;22503:43;;22593:3;22582:9;22578:19;22565:33;22555:43;;21732:872;;;;;;;;;;;:::o;22929:320::-;23005:6;23013;23021;23074:2;23062:9;23053:7;23049:23;23045:32;23042:52;;;23090:1;23087;23080:12;23042:52;23126:9;23113:23;23103:33;;23183:2;23172:9;23168:18;23155:32;23145:42;;23206:37;23239:2;23228:9;23224:18;23206:37;:::i;:::-;23196:47;;22929:320;;;;;:::o;23507:236::-;23592:6;23645:2;23633:9;23624:7;23620:23;23616:32;23613:52;;;23661:1;23658;23651:12;23613:52;23684:53;23729:7;23718:9;23684:53;:::i;23748:380::-;23827:1;23823:12;;;;23870;;;23891:61;;23945:4;23937:6;23933:17;23923:27;;23891:61;23998:2;23990:6;23987:14;23967:18;23964:38;23961:161;;24044:10;24039:3;24035:20;24032:1;24025:31;24079:4;24076:1;24069:15;24107:4;24104:1;24097:15;24133:410;24335:2;24317:21;;;24374:2;24354:18;;;24347:30;24413:34;24408:2;24393:18;;24386:62;-1:-1:-1;;;24479:2:1;24464:18;;24457:44;24533:3;24518:19;;24133:410::o;24816:127::-;24877:10;24872:3;24868:20;24865:1;24858:31;24908:4;24905:1;24898:15;24932:4;24929:1;24922:15;24948:125;25013:9;;;25034:10;;;25031:36;;;25047:18;;:::i;25078:338::-;25259:19;;;25303:2;25294:12;;25287:28;;;;25371:3;25349:16;-1:-1:-1;;;;;;25345:36:1;25340:2;25331:12;;25324:58;25407:2;25398:12;;25078:338::o;26080:663::-;26395:25;;;-1:-1:-1;;;;;26494:15:1;;;26489:2;26474:18;;26467:43;26546:15;;;;26541:2;26526:18;;26519:43;26593:2;26578:18;;26571:34;;;;26636:3;26621:19;;26614:35;26447:3;26665:19;;26658:35;;;;26724:3;26709:19;;26702:35;26382:3;26367:19;;26080:663::o;28458:127::-;28519:10;28514:3;28510:20;28507:1;28500:31;28550:4;28547:1;28540:15;28574:4;28571:1;28564:15;28590:336;28695:4;28753:11;28740:25;28847:2;28843:7;28832:8;28816:14;28812:29;28808:43;28788:18;28784:68;28774:96;;28866:1;28863;28856:12;28774:96;28887:33;;;;;28590:336;-1:-1:-1;;28590:336:1:o;28931:521::-;29008:4;29014:6;29074:11;29061:25;29168:2;29164:7;29153:8;29137:14;29133:29;29129:43;29109:18;29105:68;29095:96;;29187:1;29184;29177:12;29095:96;29214:33;;29266:20;;;-1:-1:-1;;;;;;29298:30:1;;29295:50;;;29341:1;29338;29331:12;29295:50;29374:4;29362:17;;-1:-1:-1;29405:14:1;29401:27;;;29391:38;;29388:58;;;29442:1;29439;29432:12;29457:184;29515:6;29568:2;29556:9;29547:7;29543:23;29539:32;29536:52;;;29584:1;29581;29574:12;29536:52;29607:28;29625:9;29607:28;:::i;29771:517::-;29872:2;29867:3;29864:11;29861:421;;;29908:5;29905:1;29898:16;29952:4;29949:1;29939:18;30022:2;30010:10;30006:19;30003:1;29999:27;29993:4;29989:38;30058:4;30046:10;30043:20;30040:47;;;-1:-1:-1;30081:4:1;30040:47;30136:2;30131:3;30127:12;30124:1;30120:20;30114:4;30110:31;30100:41;;30191:81;30209:2;30202:5;30199:13;30191:81;;;30268:1;30254:16;;30235:1;30224:13;30191:81;;30464:1194;-1:-1:-1;;;;;30581:3:1;30578:27;30575:53;;;30608:18;;:::i;:::-;30637:93;30726:3;30686:38;30718:4;30712:11;30686:38;:::i;:::-;30680:4;30637:93;:::i;:::-;30756:1;30781:2;30776:3;30773:11;30798:1;30793:607;;;;31444:1;31461:3;31458:93;;;-1:-1:-1;31517:19:1;;;31504:33;31458:93;-1:-1:-1;;30421:1:1;30417:11;;;30413:24;30409:29;30399:40;30445:1;30441:11;;;30396:57;31564:78;;30766:886;;30793:607;29718:1;29711:14;;;29755:4;29742:18;;-1:-1:-1;;30829:17:1;;;30943:229;30957:7;30954:1;30951:14;30943:229;;;31046:19;;;31033:33;31018:49;;31153:4;31138:20;;;;31106:1;31094:14;;;;30973:12;30943:229;;;30947:3;31200;31191:7;31188:16;31185:159;;;31324:1;31320:6;31314:3;31308;31305:1;31301:11;31297:21;31293:34;31289:39;31276:9;31271:3;31267:19;31254:33;31250:79;31242:6;31235:95;31185:159;;;31387:1;31381:3;31378:1;31374:11;31370:19;31364:4;31357:33;30766:886;;30464:1194;;;:::o;31663:266::-;31751:6;31746:3;31739:19;31803:6;31796:5;31789:4;31784:3;31780:14;31767:43;-1:-1:-1;31855:1:1;31830:16;;;31848:4;31826:27;;;31819:38;;;;31911:2;31890:15;;;-1:-1:-1;;31886:29:1;31877:39;;;31873:50;;31663:266::o;31934:1774::-;32191:2;32243:21;;;32216:18;;;32299:22;;;32162:4;;32340:2;32358:18;;;32422:1;32418:14;;;32403:30;;32399:39;;32461:6;32162:4;32495:1184;32509:6;32506:1;32503:13;32495:1184;;;32574:22;;;-1:-1:-1;;32570:36:1;32558:49;;32646:20;;32721:14;32717:27;;;-1:-1:-1;;32713:41:1;32689:66;;32679:94;;32769:1;32766;32759:12;32679:94;32799:31;;32853:4;32915:10;32889:24;32799:31;32889:24;:::i;:::-;32885:41;32877:6;32870:57;33003:6;32968:33;32997:2;32990:5;32986:14;32968:33;:::i;:::-;32964:46;32959:2;32951:6;32947:15;32940:71;33076:2;33069:5;33065:14;33052:28;33165:2;33161:7;33153:5;33137:14;33133:26;33129:40;33107:20;33103:67;33093:95;;33184:1;33181;33174:12;33093:95;33216:32;;;33324:16;;;;-1:-1:-1;33275:21:1;-1:-1:-1;;;;;33356:30:1;;33353:50;;;33399:1;33396;33389:12;33353:50;33452:6;33436:14;33432:27;33423:7;33419:41;33416:61;;;33473:1;33470;33463:12;33416:61;33514:2;33509;33501:6;33497:15;33490:27;33540:59;33595:2;33587:6;33583:15;33575:6;33566:7;33540:59;:::i;:::-;33657:12;;;;33530:69;-1:-1:-1;;;33622:15:1;;;;-1:-1:-1;32531:1:1;32524:9;32495:1184;;;-1:-1:-1;33696:6:1;;31934:1774;-1:-1:-1;;;;;;;;31934:1774:1:o;33713:331::-;33818:9;33829;33871:8;33859:10;33856:24;33853:44;;;33893:1;33890;33883:12;33853:44;33922:6;33912:8;33909:20;33906:40;;;33942:1;33939;33932:12;33906:40;-1:-1:-1;;33968:23:1;;;34013:25;;;;;-1:-1:-1;33713:331:1:o;34049:476::-;34240:3;34278:6;34272:13;34294:66;34353:6;34348:3;34341:4;34333:6;34329:17;34294:66;:::i;:::-;34382:16;;34435:6;34427;34382:16;34407:35;34499:1;34461:18;;34488:13;;;-1:-1:-1;34461:18:1;;34049:476;-1:-1:-1;;;34049:476:1:o;34530:244::-;34687:2;34676:9;34669:21;34650:4;34707:61;34764:2;34753:9;34749:18;34741:6;34733;34707:61;:::i;34779:331::-;34878:4;34936:11;34923:25;35030:3;35026:8;35015;34999:14;34995:29;34991:44;34971:18;34967:69;34957:97;;35050:1;35047;35040:12;35115:992;35493:10;35466:25;35484:6;35466:25;:::i;:::-;35462:42;35451:9;35444:61;35568:4;35560:6;35556:17;35543:31;35536:4;35525:9;35521:20;35514:61;35425:4;35622;35614:6;35610:17;35597:31;35637:30;35661:5;35637:30;:::i;:::-;-1:-1:-1;;;;;35709:5:1;35705:30;35698:4;35687:9;35683:20;35676:60;;35772:6;35767:2;35756:9;35752:18;35745:34;35816:3;35810;35799:9;35795:19;35788:32;35843:62;35900:3;35889:9;35885:19;35877:6;35869;35843:62;:::i;:::-;-1:-1:-1;;;;;35942:32:1;;35962:3;35921:19;;35914:61;36012:22;;;36006:3;35991:19;;35984:51;36052:49;36016:6;36086;36078;36052:49;:::i;:::-;36044:57;35115:992;-1:-1:-1;;;;;;;;;;35115:992:1:o;36112:648::-;36191:6;36244:2;36232:9;36223:7;36219:23;36215:32;36212:52;;;36260:1;36257;36250:12;36212:52;36293:9;36287:16;-1:-1:-1;;;;;36318:6:1;36315:30;36312:50;;;36358:1;36355;36348:12;36312:50;36381:22;;36434:4;36426:13;;36422:27;-1:-1:-1;36412:55:1;;36463:1;36460;36453:12;36412:55;36492:2;36486:9;36517:49;36533:32;36562:2;36533:32;:::i;36517:49::-;36589:2;36582:5;36575:17;36629:7;36624:2;36619;36615;36611:11;36607:20;36604:33;36601:53;;;36650:1;36647;36640:12;36601:53;36663:67;36727:2;36722;36715:5;36711:14;36706:2;36702;36698:11;36663:67;:::i;36765:348::-;36854:6;36907:2;36895:9;36886:7;36882:23;36878:32;36875:52;;;36923:1;36920;36913:12;36875:52;36949:22;;:::i;:::-;37007:9;36994:23;36987:5;36980:38;37078:2;37067:9;37063:18;37050:32;37045:2;37038:5;37034:14;37027:56;37102:5;37092:15;;;36765:348;;;;:::o;37864:245::-;37931:6;37984:2;37972:9;37963:7;37959:23;37955:32;37952:52;;;38000:1;37997;37990:12;37952:52;38032:9;38026:16;38051:28;38073:5;38051:28;:::i;38114:407::-;38316:2;38298:21;;;38355:2;38335:18;;;38328:30;38394:34;38389:2;38374:18;;38367:62;-1:-1:-1;;;38460:2:1;38445:18;;38438:41;38511:3;38496:19;;38114:407::o;38526:217::-;38566:1;38592;38582:132;;38636:10;38631:3;38627:20;38624:1;38617:31;38671:4;38668:1;38661:15;38699:4;38696:1;38689:15;38582:132;-1:-1:-1;38728:9:1;;38526:217::o;38945:478::-;39212:1;39208;39203:3;39199:11;39195:19;39187:6;39183:32;39172:9;39165:51;39252:6;39247:2;39236:9;39232:18;39225:34;39307:6;39299;39295:19;39290:2;39279:9;39275:18;39268:47;39351:3;39346:2;39335:9;39331:18;39324:31;39146:4;39372:45;39412:3;39401:9;39397:19;39389:6;39372:45;:::i;40415:889::-;40638:2;40627:9;40620:21;40696:10;40687:6;40681:13;40677:30;40672:2;40661:9;40657:18;40650:58;40762:4;40754:6;40750:17;40744:24;40739:2;40728:9;40724:18;40717:52;40601:4;40816:2;40808:6;40804:15;40798:22;40857:4;40851:3;40840:9;40836:19;40829:33;40885:51;40931:3;40920:9;40916:19;40902:12;40885:51;:::i;:::-;40871:65;;40985:2;40977:6;40973:15;40967:22;41059:2;41055:7;41043:9;41035:6;41031:22;41027:36;41020:4;41009:9;41005:20;40998:66;41087:40;41120:6;41104:14;41087:40;:::i;:::-;41196:3;41184:16;;;;41178:23;41171:31;41164:39;41158:3;41143:19;;41136:68;-1:-1:-1;;;;;;;;41265:32:1;;;;41258:4;41243:20;;;41236:62;41073:54;40415:889::o;41309:284::-;41379:5;41427:4;41415:9;41410:3;41406:19;41402:30;41399:50;;;41445:1;41442;41435:12;41399:50;41467:22;;:::i;:::-;41458:31;;41518:9;41512:16;41505:5;41498:31;41582:2;41571:9;41567:18;41561:25;41556:2;41549:5;41545:14;41538:49;41309:284;;;;:::o;41598:259::-;41698:6;41751:2;41739:9;41730:7;41726:23;41722:32;41719:52;;;41767:1;41764;41757:12;41719:52;41790:61;41843:7;41832:9;41790:61;:::i;41862:168::-;41935:9;;;41966;;41983:15;;;41977:22;;41963:37;41953:71;;42004:18;;:::i;42035:318::-;-1:-1:-1;;;;;;42155:19:1;;42226:11;;;;42257:1;42249:10;;42246:101;;;42334:2;42328;42321:3;42318:1;42314:11;42311:1;42307:19;42303:28;42299:2;42295:37;42291:46;42282:55;;42246:101;;;42035:318;;;;:::o;42358:683::-;42462:6;42515:3;42503:9;42494:7;42490:23;42486:33;42483:53;;;42532:1;42529;42522:12;42483:53;42565:2;42559:9;42607:4;42599:6;42595:17;42678:6;42666:10;42663:22;-1:-1:-1;;;;;42630:10:1;42627:34;42624:62;42621:88;;;42689:18;;:::i;:::-;42725:2;42718:22;42764:16;;42749:32;;42824:2;42809:18;;42803:25;42837:30;42803:25;42837:30;:::i;:::-;42895:2;42883:15;;42876:30;42939:70;43001:7;42996:2;42981:18;;42939:70;:::i;:::-;42934:2;42922:15;;42915:95;42926:6;42358:683;-1:-1:-1;;;42358:683:1:o;43341:532::-;43582:6;43577:3;43570:19;-1:-1:-1;;;;;43645:3:1;43641:28;43632:6;43627:3;43623:16;43619:51;43614:2;43609:3;43605:12;43598:73;43701:6;43696:2;43691:3;43687:12;43680:28;43552:3;43737:6;43731:13;43753:73;43819:6;43814:2;43809:3;43805:12;43800:2;43792:6;43788:15;43753:73;:::i;:::-;43846:16;;;;43864:2;43842:25;;43341:532;-1:-1:-1;;;;;43341:532:1:o;43878:1343::-;44004:3;43998:10;-1:-1:-1;;;;;44023:6:1;44020:30;44017:56;;;44053:18;;:::i;:::-;44082:96;44171:6;44131:38;44163:4;44157:11;44131:38;:::i;:::-;44125:4;44082:96;:::i;:::-;44233:4;;44290:2;44279:14;;44307:1;44302:662;;;;45008:1;45025:6;45022:89;;;-1:-1:-1;45077:19:1;;;45071:26;45022:89;-1:-1:-1;;30421:1:1;30417:11;;;30413:24;30409:29;30399:40;30445:1;30441:11;;;30396:57;45124:81;;44272:943;;44302:662;29718:1;29711:14;;;29755:4;29742:18;;-1:-1:-1;;44338:20:1;;;44455:236;44469:7;44466:1;44463:14;44455:236;;;44558:19;;;44552:26;44537:42;;44650:27;;;;44618:1;44606:14;;;;44485:19;;44455:236;;;44459:3;44719:6;44710:7;44707:19;44704:201;;;44780:19;;;44774:26;-1:-1:-1;;44863:1:1;44859:14;;;44875:3;44855:24;44851:37;44847:42;44832:58;44817:74;;44704:201;;;44951:1;44942:6;44939:1;44935:14;44931:22;44925:4;44918:36;44272:943;;;;;43878:1343;;:::o;46034:255::-;46154:19;;46193:2;46185:11;;46182:101;;;-1:-1:-1;;46254:2:1;46250:12;;;46247:1;46243:20;46239:33;46228:45;46034:255;;;;:::o;46294:331::-;-1:-1:-1;;;;;;46414:19:1;;46498:11;;;;46529:1;46521:10;;46518:101;;;46590:1;46586:11;;;;46583:1;46579:19;46575:28;;;46567:37;46563:46;;;;46294:331;-1:-1:-1;;46294:331:1:o;46630:568::-;-1:-1:-1;;;;;46895:3:1;46891:28;46882:6;46877:3;46873:16;46869:51;46864:3;46857:64;46981:10;46976:3;46972:20;46963:6;46958:3;46954:16;46950:43;46946:1;46941:3;46937:11;46930:64;47024:6;47019:2;47014:3;47010:12;47003:28;46839:3;47060:6;47054:13;47076:75;47144:6;47139:2;47134:3;47130:12;47123:4;47115:6;47111:17;47076:75;:::i;:::-;47171:16;;;;47189:2;47167:25;;46630:568;-1:-1:-1;;;;;46630:568:1:o;48914:127::-;48975:10;48970:3;48966:20;48963:1;48956:31;49006:4;49003:1;48996:15;49030:4;49027:1;49020:15;49851:251;49921:6;49974:2;49962:9;49953:7;49949:23;49945:32;49942:52;;;49990:1;49987;49980:12;49942:52;50022:9;50016:16;50041:31;50066:5;50041:31;:::i;50467:288::-;50642:6;50631:9;50624:25;50685:2;50680;50669:9;50665:18;50658:30;50605:4;50705:44;50745:2;50734:9;50730:18;50722:6;50705:44;:::i;50760:287::-;50889:3;50927:6;50921:13;50943:66;51002:6;50997:3;50990:4;50982:6;50978:17;50943:66;:::i;51052:184::-;51122:6;51175:2;51163:9;51154:7;51150:23;51146:32;51143:52;;;51191:1;51188;51181:12;51143:52;-1:-1:-1;51214:16:1;;51052:184;-1:-1:-1;51052:184:1:o
Swarm Source
ipfs://f1551093d0a4fc78776efc5a6799d0f3e995df8f490a6fd6fcf58686806ca94b
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.