Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Multichain Info
No addresses found
Loading...
Loading
Contract Name:
OpenOceanExchange
Compiler Version
v0.8.20+commit.a1b79de6
Contract Source Code (Solidity)
/** *Submitted for verification at zkevm.polygonscan.com on 2024-12-23 */ // File: @openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @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 * ==== * * [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://diligence.consensys.net/posts/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.5.11/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 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); } } } // File: @openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol // OpenZeppelin Contracts (last updated v4.8.1) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; /** * @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] * ``` * 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; } } // File: @openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @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; } /** * @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; } // File: @openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; /** * @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 anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing 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; } // File: @openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @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); } // File: @openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @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. */ 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]. */ 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); } // File: @openzeppelin/contracts/utils/Address.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @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 * ==== * * [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://diligence.consensys.net/posts/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.5.11/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); } } } // File: @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; /** * @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; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } 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)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } 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"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } 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"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File: @openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } /** * @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; } // File: contracts/interfaces/IOpenOceanCaller.sol pragma solidity ^0.8.0; interface IOpenOceanCaller { struct CallDescription { uint256 target; uint256 gasLimit; uint256 value; bytes data; } function makeCall(CallDescription memory desc) external; function makeCalls(CallDescription[] memory desc) external payable; } // File: contracts/libraries/RevertReasonParser.sol pragma solidity ^0.8.0; library RevertReasonParser { function parse(bytes memory data, string memory prefix) internal pure returns (string memory) { // https://solidity.readthedocs.io/en/latest/control-structures.html#revert // We assume that revert reason is abi-encoded as Error(string) // 68 = 4-byte selector 0x08c379a0 + 32 bytes offset + 32 bytes length if (data.length >= 68 && data[0] == "\x08" && data[1] == "\xc3" && data[2] == "\x79" && data[3] == "\xa0") { string memory reason; // solhint-disable no-inline-assembly assembly { // 68 = 32 bytes data length + 4-byte selector + 32 bytes offset reason := add(data, 68) } /* revert reason is padded up to 32 bytes with ABI encoder: Error(string) also sometimes there is extra 32 bytes of zeros padded in the end: https://github.com/ethereum/solidity/issues/10170 because of that we can't check for equality and instead check that string length + extra 68 bytes is less than overall data length */ require(data.length >= 68 + bytes(reason).length, "Invalid revert reason"); return string(abi.encodePacked(prefix, "Error(", reason, ")")); } // 36 = 4-byte selector 0x4e487b71 + 32 bytes integer else if (data.length == 36 && data[0] == "\x4e" && data[1] == "\x48" && data[2] == "\x7b" && data[3] == "\x71") { uint256 code; // solhint-disable no-inline-assembly assembly { // 36 = 32 bytes data length + 4-byte selector code := mload(add(data, 36)) } return string(abi.encodePacked(prefix, "Panic(", _toHex(code), ")")); } return string(abi.encodePacked(prefix, "Unknown()")); } function _toHex(uint256 value) private pure returns (string memory) { return _toHex(abi.encodePacked(value)); } function _toHex(bytes memory data) private pure returns (string memory) { bytes memory alphabet = "0123456789abcdef"; bytes memory str = new bytes(2 + data.length * 2); str[0] = "0"; str[1] = "x"; for (uint256 i = 0; i < data.length; i++) { str[2 * i + 2] = alphabet[uint8(data[i] >> 4)]; str[2 * i + 3] = alphabet[uint8(data[i] & 0x0f)]; } return string(str); } } // File: @openzeppelin/contracts/utils/math/SafeMath.sol // OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol) pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } } // File: contracts/libraries/UniversalERC20.sol pragma solidity ^0.8.0; library UniversalERC20 { using SafeMath for uint256; using SafeERC20 for IERC20; IERC20 internal constant ZERO_ADDRESS = IERC20(0x0000000000000000000000000000000000000000); IERC20 internal constant ETH_ADDRESS = IERC20(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE); IERC20 internal constant MATIC_ADDRESS = IERC20(0x0000000000000000000000000000000000001010); function universalTransfer( IERC20 token, address payable to, uint256 amount ) internal { if (amount > 0) { if (isETH(token)) { (bool result, ) = to.call{value: amount}(""); require(result, "Failed to transfer ETH"); } else { token.safeTransfer(to, amount); } } } function universalApprove( IERC20 token, address to, uint256 amount ) internal { require(!isETH(token), "Approve called on ETH"); if (amount == 0) { token.safeApprove(to, 0); } else { uint256 allowance = token.allowance(address(this), to); if (allowance < amount) { if (allowance > 0) { token.safeApprove(to, 0); } token.safeApprove(to, amount); } } } function universalBalanceOf(IERC20 token, address account) internal view returns (uint256) { if (isETH(token)) { return account.balance; } else { return token.balanceOf(account); } } function isETH(IERC20 token) internal pure returns (bool) { return address(token) == address(ETH_ADDRESS) || address(token) == address(MATIC_ADDRESS) || address(token) == address(ZERO_ADDRESS); } } // File: contracts/libraries/Permitable.sol pragma solidity ^0.8.0; /// @title Interface for DAI-style permits interface IDaiLikePermit { function permit( address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s ) external; } /// @title SignatureTransfer /// @notice Handles ERC20 token transfers through signature based actions /// @dev Requires user's token approval on the Permit2 contract interface IPermit2 { /// @notice The token and amount details for a transfer signed in the permit transfer signature struct TokenPermissions { // ERC20 token address address token; // the maximum amount that can be spent uint256 amount; } /// @notice The signed permit message for a single token transfer struct PermitTransferFrom { TokenPermissions permitted; // a unique value for every token owner's signature to prevent signature replays uint256 nonce; // deadline on the permit signature uint256 deadline; } /// @notice Specifies the recipient address and amount for batched transfers. /// @dev Recipients and amounts correspond to the index of the signed token permissions array. /// @dev Reverts if the requested amount is greater than the permitted signed amount. struct SignatureTransferDetails { // recipient address address to; // spender requested amount uint256 requestedAmount; } /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce /// @dev It returns a uint256 bitmap /// @dev The index, or wordPosition is capped at type(uint248).max function nonceBitmap(address, uint256) external view returns (uint256); /// @notice Transfers a token using a signed permit message /// @dev Reverts if the requested amount is greater than the permitted signed amount /// @param permit The permit data signed over by the owner /// @param owner The owner of the tokens to transfer /// @param transferDetails The spender's requested transfer details for the permitted token /// @param signature The signature to verify function permitTransferFrom( PermitTransferFrom memory permit, SignatureTransferDetails calldata transferDetails, address owner, bytes calldata signature ) external; /// @notice Returns the domain separator for the current chain. /// @dev Uses cached version if chainid and address are unchanged from construction. function DOMAIN_SEPARATOR() external view returns (bytes32); } /// @title Base contract with common permit handling logics contract Permitable { address public permit2; function permit2DomainSeperator() external view returns (bytes32) { return IPermit2(permit2).DOMAIN_SEPARATOR(); } function _permit(address token, bytes calldata permit) internal returns (bool) { if (permit.length > 0) { if (permit.length == 32 * 7 || permit.length == 32 * 8) { (bool success, bytes memory result) = _permit1(token, permit); if (!success) { revert(RevertReasonParser.parse(result, "Permit failed: ")); } return false; } else { (bool success, bytes memory result) = _permit2(permit); if (!success) { revert(RevertReasonParser.parse(result, "Permit2 failed: ")); } return true; } } return false; } function _isPermit2(bytes calldata permit) internal pure returns (bool) { return permit.length == 32 * 11 || permit.length == 32 * 12; } function _permit1(address token, bytes calldata permit) private returns (bool success, bytes memory result) { if (permit.length == 32 * 7) { // solhint-disable-next-line avoid-low-level-calls (success, result) = token.call(abi.encodePacked(IERC20Permit.permit.selector, permit)); } else if (permit.length == 32 * 8) { // solhint-disable-next-line avoid-low-level-calls (success, result) = token.call(abi.encodePacked(IDaiLikePermit.permit.selector, permit)); } } function _permit2(bytes calldata permit) private returns (bool success, bytes memory result) { (, , address owner, ) = abi.decode( permit, (IPermit2.PermitTransferFrom, IPermit2.SignatureTransferDetails, address, bytes) ); require(owner == msg.sender, "Permit2 denied"); // solhint-disable-next-line avoid-low-level-calls (success, result) = permit2.call(abi.encodePacked(IPermit2.permitTransferFrom.selector, permit)); // TODO support batch permit } /// @notice Finds the next valid nonce for a user, starting from 0. /// @param owner The owner of the nonces /// @return nonce The first valid nonce starting from 0 function permit2NextNonce(address owner) external view returns (uint256 nonce) { nonce = _permit2NextNonce(owner, 0, 0); } /// @notice Finds the next valid nonce for a user, after from a given nonce. /// @dev This can be helpful if you're signing multiple nonces in a row and need the next nonce to sign but the start one is still valid. /// @param owner The owner of the nonces /// @param start The nonce to start from /// @return nonce The first valid nonce after the given nonce function permit2NextNonceAfter(address owner, uint256 start) external view returns (uint256 nonce) { uint248 word = uint248(start >> 8); uint8 pos = uint8(start); if (pos == type(uint8).max) { // If the position is 255, we need to move to the next word word++; pos = 0; } else { // Otherwise, we just move to the next position pos++; } nonce = _permit2NextNonce(owner, word, pos); } /// @notice Finds the next valid nonce for a user, starting from a given word and position. /// @param owner The owner of the nonces /// @param word Word to start looking from /// @param pos Position inside the word to start looking from function _permit2NextNonce(address owner, uint248 word, uint8 pos) internal view returns (uint256 nonce) { while (true) { uint256 bitmap = IPermit2(permit2).nonceBitmap(owner, word); // Check if the bitmap is completely full if (bitmap == type(uint256).max) { // If so, move to the next word ++word; pos = 0; continue; } if (pos != 0) { // If the position is not 0, we need to shift the bitmap to ignore the bits before position bitmap = bitmap >> pos; } // Find the first zero bit in the bitmap while (bitmap & 1 == 1) { bitmap = bitmap >> 1; ++pos; } return _permit2NonceFromWordAndPos(word, pos); } } /// @notice Constructs a nonce from a word and a position inside the word /// @param word The word containing the nonce /// @param pos The position of the nonce inside the word /// @return nonce The nonce constructed from the word and position function _permit2NonceFromWordAndPos(uint248 word, uint8 pos) internal pure returns (uint256 nonce) { // The last 248 bits of the word are the nonce bits nonce = uint256(word) << 8; // The first 8 bits of the word are the position inside the word nonce |= pos; } } // File: contracts/OpenOceanExchange.sol pragma solidity ^0.8.0; pragma experimental ABIEncoderV2; contract OpenOceanExchange is OwnableUpgradeable, PausableUpgradeable, Permitable { using SafeMath for uint256; using SafeERC20 for IERC20; using UniversalERC20 for IERC20; uint256 private constant _PARTIAL_FILL = 0x01; uint256 private constant _SHOULD_CLAIM = 0x02; struct SwapDescription { IERC20 srcToken; IERC20 dstToken; address srcReceiver; address dstReceiver; uint256 amount; uint256 minReturnAmount; uint256 guaranteedAmount; uint256 flags; address referrer; bytes permit; } event Swapped( address indexed sender, IERC20 indexed srcToken, IERC20 indexed dstToken, address dstReceiver, uint256 amount, uint256 spentAmount, uint256 returnAmount, uint256 minReturnAmount, uint256 guaranteedAmount, address referrer ); function initialize() public initializer { OwnableUpgradeable.__Ownable_init(); PausableUpgradeable.__Pausable_init(); } function swap( IOpenOceanCaller caller, SwapDescription calldata desc, IOpenOceanCaller.CallDescription[] calldata calls ) external payable whenNotPaused returns (uint256 returnAmount) { require(desc.minReturnAmount > 0, "Min return should not be 0"); require(calls.length > 0, "Call data should exist"); uint256 flags = desc.flags; IERC20 srcToken = desc.srcToken; IERC20 dstToken = desc.dstToken; require(msg.value == (srcToken.isETH() ? desc.amount : 0), "Invalid msg.value"); if (flags & _SHOULD_CLAIM != 0) { require(!srcToken.isETH(), "Claim token is ETH"); _claim(srcToken, desc.srcReceiver, desc.amount, desc.permit); } address dstReceiver = (desc.dstReceiver == address(0)) ? msg.sender : desc.dstReceiver; uint256 initialSrcBalance = (flags & _PARTIAL_FILL != 0) ? srcToken.universalBalanceOf(msg.sender) : 0; uint256 initialDstBalance = dstToken.universalBalanceOf(dstReceiver); caller.makeCalls{value: msg.value}(calls); uint256 spentAmount = desc.amount; returnAmount = dstToken.universalBalanceOf(dstReceiver).sub(initialDstBalance); if (flags & _PARTIAL_FILL != 0) { spentAmount = initialSrcBalance.add(desc.amount).sub(srcToken.universalBalanceOf(msg.sender)); require(returnAmount.mul(desc.amount) >= desc.minReturnAmount.mul(spentAmount), "Return amount is not enough"); } else { require(returnAmount >= desc.minReturnAmount, "Return amount is not enough"); } _emitSwapped(desc, srcToken, dstToken, dstReceiver, spentAmount, returnAmount); } function _emitSwapped( SwapDescription calldata desc, IERC20 srcToken, IERC20 dstToken, address dstReceiver, uint256 spentAmount, uint256 returnAmount ) private { emit Swapped( msg.sender, srcToken, dstToken, dstReceiver, desc.amount, spentAmount, returnAmount, desc.minReturnAmount, desc.guaranteedAmount, desc.referrer ); } function _claim(IERC20 token, address dst, uint256 amount, bytes calldata permit) private { if (!_permit(address(token), permit)) { token.safeTransferFrom(msg.sender, dst, amount); } } function rescueFunds(IERC20 token, uint256 amount) external onlyOwner { token.universalTransfer(payable(msg.sender), amount); } function pause() external onlyOwner { _pause(); } function setPermit2(address _permit2) external onlyOwner { permit2 = _permit2; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","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":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"contract IERC20","name":"srcToken","type":"address"},{"indexed":true,"internalType":"contract IERC20","name":"dstToken","type":"address"},{"indexed":false,"internalType":"address","name":"dstReceiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"spentAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"returnAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minReturnAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"guaranteedAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"referrer","type":"address"}],"name":"Swapped","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"permit2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"permit2DomainSeperator","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"permit2NextNonce","outputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"}],"name":"permit2NextNonceAfter","outputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"rescueFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_permit2","type":"address"}],"name":"setPermit2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IOpenOceanCaller","name":"caller","type":"address"},{"components":[{"internalType":"contract IERC20","name":"srcToken","type":"address"},{"internalType":"contract IERC20","name":"dstToken","type":"address"},{"internalType":"address","name":"srcReceiver","type":"address"},{"internalType":"address","name":"dstReceiver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minReturnAmount","type":"uint256"},{"internalType":"uint256","name":"guaranteedAmount","type":"uint256"},{"internalType":"uint256","name":"flags","type":"uint256"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"bytes","name":"permit","type":"bytes"}],"internalType":"struct OpenOceanExchange.SwapDescription","name":"desc","type":"tuple"},{"components":[{"internalType":"uint256","name":"target","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IOpenOceanCaller.CallDescription[]","name":"calls","type":"tuple[]"}],"name":"swap","outputs":[{"internalType":"uint256","name":"returnAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561000f575f80fd5b50611fb48061001d5f395ff3fe6080604052600436106100bf575f3560e01c8063844fb31c1161007c57806390411a321161005757806390411a32146101dc578063be698cfc146101ef578063f2fde38b1461020e578063ff3a920f1461022d575f80fd5b8063844fb31c146101895780638456cb59146101ab5780638da5cb5b146101bf575f80fd5b8063101ec30a146100c357806312261ee7146100e45780635c975abb14610120578063715018a61461014257806378e3214f146101565780638129fc1c14610175575b5f80fd5b3480156100ce575f80fd5b506100e26100dd366004611907565b61024c565b005b3480156100ef575f80fd5b50609754610103906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561012b575f80fd5b5060655460ff166040519015158152602001610117565b34801561014d575f80fd5b506100e2610276565b348015610161575f80fd5b506100e2610170366004611922565b610289565b348015610180575f80fd5b506100e26102a9565b348015610194575f80fd5b5061019d6103c1565b604051908152602001610117565b3480156101b6575f80fd5b506100e2610431565b3480156101ca575f80fd5b506033546001600160a01b0316610103565b61019d6101ea36600461194c565b610441565b3480156101fa575f80fd5b5061019d610209366004611922565b6107fe565b348015610219575f80fd5b506100e2610228366004611907565b610848565b348015610238575f80fd5b5061019d610247366004611907565b6108be565b6102546108d0565b609780546001600160a01b0319166001600160a01b0392909216919091179055565b61027e6108d0565b6102875f61092a565b565b6102916108d0565b6102a56001600160a01b038316338361097b565b5050565b5f54610100900460ff16158080156102c757505f54600160ff909116105b806102e05750303b1580156102e057505f5460ff166001145b6103485760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b5f805460ff191660011790558015610369575f805461ff0019166101001790555b610371610a46565b610379610a74565b80156103be575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b60975460408051633644e51560e01b815290515f926001600160a01b031691633644e5159160048083019260209291908290030181865afa158015610408573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061042c91906119f3565b905090565b6104396108d0565b610287610aa2565b5f61044a610afc565b5f8460a001351161049d5760405162461bcd60e51b815260206004820152601a60248201527f4d696e2072657475726e2073686f756c64206e6f742062652030000000000000604482015260640161033f565b816104e35760405162461bcd60e51b815260206004820152601660248201527510d85b1b0819185d18481cda1bdd5b1908195e1a5cdd60521b604482015260640161033f565b60e08401355f6104f66020870187611907565b90505f6105096040880160208901611907565b905061051d826001600160a01b0316610b42565b610527575f61052d565b86608001355b341461056f5760405162461bcd60e51b8152602060048201526011602482015270496e76616c6964206d73672e76616c756560781b604482015260640161033f565b60028316156105f85761058a826001600160a01b0316610b42565b156105cc5760405162461bcd60e51b8152602060048201526012602482015271086d8c2d2da40e8ded6cadc40d2e6408aa8960731b604482015260640161033f565b6105f8826105e060608a0160408b01611907565b60808a01356105f36101208c018c611a0a565b610b8c565b5f8061060a60808a0160608b01611907565b6001600160a01b03161461062d576106286080890160608a01611907565b61062f565b335b90505f600185165f03610642575f610655565b6106556001600160a01b03851633610bb7565b90505f61066b6001600160a01b03851684610bb7565b90508a6001600160a01b031663a8920d2b348b8b6040518463ffffffff1660e01b815260040161069c929190611a7c565b5f604051808303818588803b1580156106b3575f80fd5b505af11580156106c5573d5f803e3d5ffd5b5050505060808b013590506106ed826106e76001600160a01b03881687610bb7565b90610c46565b9750600187161561078d5761071c61070e6001600160a01b03881633610bb7565b6106e78560808f0135610c51565b905061072c60a08c013582610c5c565b61073a8960808e0135610c5c565b10156107885760405162461bcd60e51b815260206004820152601b60248201527f52657475726e20616d6f756e74206973206e6f7420656e6f7567680000000000604482015260640161033f565b6107e1565b8a60a001358810156107e15760405162461bcd60e51b815260206004820152601b60248201527f52657475726e20616d6f756e74206973206e6f7420656e6f7567680000000000604482015260640161033f565b6107ef8b878787858d610c67565b50505050505050949350505050565b5f600882901c8260fe1960ff821601610826578161081b81611b64565b9250505f9050610834565b8061083081611b91565b9150505b61083f858383610d18565b95945050505050565b6108506108d0565b6001600160a01b0381166108b55760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161033f565b6103be8161092a565b5f6108ca825f80610d18565b92915050565b6033546001600160a01b031633146102875760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161033f565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b8015610a415761098a83610b42565b15610a2d575f826001600160a01b0316826040515f6040518083038185875af1925050503d805f81146109d8576040519150601f19603f3d011682016040523d82523d5f602084013e6109dd565b606091505b5050905080610a275760405162461bcd60e51b815260206004820152601660248201527508cc2d2d8cac840e8de40e8e4c2dce6cccae4408aa8960531b604482015260640161033f565b50505050565b610a416001600160a01b0384168383610df7565b505050565b5f54610100900460ff16610a6c5760405162461bcd60e51b815260040161033f90611baf565b610287610e5a565b5f54610100900460ff16610a9a5760405162461bcd60e51b815260040161033f90611baf565b610287610e89565b610aaa610afc565b6065805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610adf3390565b6040516001600160a01b03909116815260200160405180910390a1565b60655460ff16156102875760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161033f565b5f6001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1480610b7857506001600160a01b038216611010145b806108ca5750506001600160a01b03161590565b610b97858383610ebb565b610bb057610bb06001600160a01b038616338686610f9c565b5050505050565b5f610bc183610b42565b15610bd757506001600160a01b038116316108ca565b6040516370a0823160e01b81526001600160a01b0383811660048301528416906370a0823190602401602060405180830381865afa158015610c1b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c3f91906119f3565b9392505050565b5f610c3f8284611bfa565b5f610c3f8284611c0d565b5f610c3f8284611c20565b836001600160a01b0316856001600160a01b0316336001600160a01b03167f76af224a143865a50b41496e1a73622698692c565c1214bc862f18e22d829c5e868a6080013587878d60a001358e60c001358f610100016020810190610ccc9190611907565b604080516001600160a01b03988916815260208101979097528601949094526060850192909252608084015260a083015290911660c082015260e00160405180910390a4505050505050565b5f5b6097546040516313f80ad160e21b81526001600160a01b0386811660048301526001600160f81b03861660248301525f921690634fe02b4490604401602060405180830381865afa158015610d71573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d9591906119f3565b90505f198103610db357610da884611b64565b93505f925050610d1a565b60ff831615610dc25760ff83161c5b80600116600103610de05760011c610dd983611b91565b9250610dc2565b505060ff811660ff19600884901b16179392505050565b6040516001600160a01b038316602482015260448101829052610a4190849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152610fd4565b5f54610100900460ff16610e805760405162461bcd60e51b815260040161033f90611baf565b6102873361092a565b5f54610100900460ff16610eaf5760405162461bcd60e51b815260040161033f90611baf565b6065805460ff19169055565b5f8115610f935760e0821480610ed2575061010082145b15610f41575f80610ee48686866110a5565b9150915081610f3757610f1e816040518060400160405280600f81526020016e02832b936b4ba103330b4b632b21d1608d1b8152506111d3565b60405162461bcd60e51b815260040161033f9190611c59565b5f92505050610c3f565b5f80610f4d858561143d565b9150915081610f8857610f1e816040518060400160405280601081526020016f02832b936b4ba19103330b4b632b21d160851b8152506111d3565b600192505050610c3f565b505f9392505050565b6040516001600160a01b0380851660248301528316604482015260648101829052610a279085906323b872dd60e01b90608401610e23565b5f611028826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661152b9092919063ffffffff16565b805190915015610a4157808060200190518101906110469190611c8b565b610a415760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161033f565b5f606060e083900361113b576040516001600160a01b038616906110d89063d505accf60e01b9087908790602001611caa565b60408051601f19818403018152908290526110f291611ccd565b5f604051808303815f865af19150503d805f811461112b576040519150601f19603f3d011682016040523d82523d5f602084013e611130565b606091505b5090925090506111cb565b6101008390036111cb576040516001600160a01b0386169061116c906323f2ebc360e21b9087908790602001611caa565b60408051601f198184030181529082905261118691611ccd565b5f604051808303815f865af19150503d805f81146111bf576040519150601f19603f3d011682016040523d82523d5f602084013e6111c4565b606091505b5090925090505b935093915050565b6060604483511015801561120b5750825f815181106111f4576111f4611ce8565b6020910101516001600160f81b031916600160fb1b145b801561123c57508260018151811061122557611225611ce8565b6020910101516001600160f81b03191660c360f81b145b801561126d57508260028151811061125657611256611ce8565b6020910101516001600160f81b031916607960f81b145b801561129e57508260038151811061128757611287611ce8565b6020910101516001600160f81b031916600560fd1b145b15611328576044838101805190916112b69190611c0d565b845110156112fe5760405162461bcd60e51b815260206004820152601560248201527424b73b30b634b2103932bb32b93a103932b0b9b7b760591b604482015260640161033f565b8281604051602001611311929190611cfc565b6040516020818303038152906040529150506108ca565b8251602414801561135d5750825f8151811061134657611346611ce8565b6020910101516001600160f81b031916602760f91b145b801561138e57508260018151811061137757611377611ce8565b6020910101516001600160f81b031916600960fb1b145b80156113bf5750826002815181106113a8576113a8611ce8565b6020910101516001600160f81b031916607b60f81b145b80156113f05750826003815181106113d9576113d9611ce8565b6020910101516001600160f81b031916607160f81b145b156114155760248301518261140482611541565b604051602001611311929190611d4a565b816040516020016114269190611d7e565b604051602081830303815290604052905092915050565b5f60608161144d84860186611e6f565b50925050506001600160a01b038116331461149b5760405162461bcd60e51b815260206004820152600e60248201526d14195c9b5a5d0c8819195b9a595960921b604482015260640161033f565b6097546040516001600160a01b03909116906114c69063187945bd60e11b9088908890602001611caa565b60408051601f19818403018152908290526114e091611ccd565b5f604051808303815f865af19150503d805f8114611519576040519150601f19603f3d011682016040523d82523d5f602084013e61151e565b606091505b5090969095509350505050565b606061153984845f8561156d565b949350505050565b60606108ca8260405160200161155991815260200190565b604051602081830303815290604052611644565b6060824710156115ce5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161033f565b5f80866001600160a01b031685876040516115e99190611ccd565b5f6040518083038185875af1925050503d805f8114611623576040519150601f19603f3d011682016040523d82523d5f602084013e611628565b606091505b509150915061163987838387611856565b979650505050505050565b60408051808201909152601081526f181899199a1a9b1b9c1cb0b131b232b360811b60208201528151606091905f9061167e906002611c20565b611689906002611c0d565b67ffffffffffffffff8111156116a1576116a1611daa565b6040519080825280601f01601f1916602001820160405280156116cb576020820181803683370190505b509050600360fc1b815f815181106116e5576116e5611ce8565b60200101906001600160f81b03191690815f1a905350600f60fb1b8160018151811061171357611713611ce8565b60200101906001600160f81b03191690815f1a9053505f5b845181101561184e5782600486838151811061174957611749611ce8565b016020015182516001600160f81b031990911690911c60f81c90811061177157611771611ce8565b01602001516001600160f81b0319168261178c836002611c20565b611797906002611c0d565b815181106117a7576117a7611ce8565b60200101906001600160f81b03191690815f1a905350828582815181106117d0576117d0611ce8565b602091010151815160f89190911c600f169081106117f0576117f0611ce8565b01602001516001600160f81b0319168261180b836002611c20565b611816906003611c0d565b8151811061182657611826611ce8565b60200101906001600160f81b03191690815f1a9053508061184681611f66565b91505061172b565b509392505050565b606083156118c45782515f036118bd576001600160a01b0385163b6118bd5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161033f565b5081611539565b61153983838151156118d95781518083602001fd5b8060405162461bcd60e51b815260040161033f9190611c59565b6001600160a01b03811681146103be575f80fd5b5f60208284031215611917575f80fd5b8135610c3f816118f3565b5f8060408385031215611933575f80fd5b823561193e816118f3565b946020939093013593505050565b5f805f806060858703121561195f575f80fd5b843561196a816118f3565b9350602085013567ffffffffffffffff80821115611986575f80fd5b90860190610140828903121561199a575f80fd5b909350604086013590808211156119af575f80fd5b818701915087601f8301126119c2575f80fd5b8135818111156119d0575f80fd5b8860208260051b85010111156119e4575f80fd5b95989497505060200194505050565b5f60208284031215611a03575f80fd5b5051919050565b5f808335601e19843603018112611a1f575f80fd5b83018035915067ffffffffffffffff821115611a39575f80fd5b602001915036819003821315611a4d575f80fd5b9250929050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60208082528181018390525f906040808401600586901b8501820187855b88811015611b4257878303603f190184528135368b9003607e19018112611abf575f80fd5b8a018035845286810135878501528581013586850152608060608083013536849003601e19018112611aef575f80fd5b90920188810192903567ffffffffffffffff811115611b0c575f80fd5b803603841315611b1a575f80fd5b8282880152611b2c8388018286611a54565b978a019796505050928701925050600101611a9a565b509098975050505050505050565b634e487b7160e01b5f52601160045260245ffd5b5f6001600160f81b038281166002600160f81b03198101611b8757611b87611b50565b6001019392505050565b5f60ff821660ff8103611ba657611ba6611b50565b60010192915050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b818103818111156108ca576108ca611b50565b808201808211156108ca576108ca611b50565b80820281158282048414176108ca576108ca611b50565b5f5b83811015611c51578181015183820152602001611c39565b50505f910152565b602081525f8251806020840152611c77816040850160208701611c37565b601f01601f19169190910160400192915050565b5f60208284031215611c9b575f80fd5b81518015158114610c3f575f80fd5b6001600160e01b031984168152818360048301375f910160040190815292915050565b5f8251611cde818460208701611c37565b9190910192915050565b634e487b7160e01b5f52603260045260245ffd5b5f8351611d0d818460208801611c37565b6508ae4e4dee4560d31b9083019081528351611d30816006840160208801611c37565b602960f81b60069290910191820152600701949350505050565b5f8351611d5b818460208801611c37565b650a0c2dcd2c6560d31b9083019081528351611d30816006840160208801611c37565b5f8251611d8f818460208701611c37565b68556e6b6e6f776e282960b81b920191825250600901919050565b634e487b7160e01b5f52604160045260245ffd5b6040516060810167ffffffffffffffff81118282101715611de157611de1611daa565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611e1057611e10611daa565b604052919050565b5f60408284031215611e28575f80fd5b6040516040810181811067ffffffffffffffff82111715611e4b57611e4b611daa565b6040529050808235611e5c816118f3565b8152602092830135920191909152919050565b5f805f80848603610100811215611e84575f80fd5b6080811215611e91575f80fd5b50611e9a611dbe565b611ea48787611e18565b8152602060408701358183015260608701356040830152819550611ecb8860808901611e18565b945060c08701359150611edd826118f3565b90925060e08601359067ffffffffffffffff80831115611efb575f80fd5b828801925088601f840112611f0e575f80fd5b823581811115611f2057611f20611daa565b611f32601f8201601f19168401611de7565b91508082528983828601011115611f47575f80fd5b80838501848401375f8382840101525080935050505092959194509250565b5f60018201611f7757611f77611b50565b506001019056fea26469706673582212204dfc20343858ed1c05e71d9618f5dd517f4e9e8dac1f44a5660e11caba03e11764736f6c63430008140033
Deployed Bytecode
0x6080604052600436106100bf575f3560e01c8063844fb31c1161007c57806390411a321161005757806390411a32146101dc578063be698cfc146101ef578063f2fde38b1461020e578063ff3a920f1461022d575f80fd5b8063844fb31c146101895780638456cb59146101ab5780638da5cb5b146101bf575f80fd5b8063101ec30a146100c357806312261ee7146100e45780635c975abb14610120578063715018a61461014257806378e3214f146101565780638129fc1c14610175575b5f80fd5b3480156100ce575f80fd5b506100e26100dd366004611907565b61024c565b005b3480156100ef575f80fd5b50609754610103906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561012b575f80fd5b5060655460ff166040519015158152602001610117565b34801561014d575f80fd5b506100e2610276565b348015610161575f80fd5b506100e2610170366004611922565b610289565b348015610180575f80fd5b506100e26102a9565b348015610194575f80fd5b5061019d6103c1565b604051908152602001610117565b3480156101b6575f80fd5b506100e2610431565b3480156101ca575f80fd5b506033546001600160a01b0316610103565b61019d6101ea36600461194c565b610441565b3480156101fa575f80fd5b5061019d610209366004611922565b6107fe565b348015610219575f80fd5b506100e2610228366004611907565b610848565b348015610238575f80fd5b5061019d610247366004611907565b6108be565b6102546108d0565b609780546001600160a01b0319166001600160a01b0392909216919091179055565b61027e6108d0565b6102875f61092a565b565b6102916108d0565b6102a56001600160a01b038316338361097b565b5050565b5f54610100900460ff16158080156102c757505f54600160ff909116105b806102e05750303b1580156102e057505f5460ff166001145b6103485760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b5f805460ff191660011790558015610369575f805461ff0019166101001790555b610371610a46565b610379610a74565b80156103be575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b60975460408051633644e51560e01b815290515f926001600160a01b031691633644e5159160048083019260209291908290030181865afa158015610408573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061042c91906119f3565b905090565b6104396108d0565b610287610aa2565b5f61044a610afc565b5f8460a001351161049d5760405162461bcd60e51b815260206004820152601a60248201527f4d696e2072657475726e2073686f756c64206e6f742062652030000000000000604482015260640161033f565b816104e35760405162461bcd60e51b815260206004820152601660248201527510d85b1b0819185d18481cda1bdd5b1908195e1a5cdd60521b604482015260640161033f565b60e08401355f6104f66020870187611907565b90505f6105096040880160208901611907565b905061051d826001600160a01b0316610b42565b610527575f61052d565b86608001355b341461056f5760405162461bcd60e51b8152602060048201526011602482015270496e76616c6964206d73672e76616c756560781b604482015260640161033f565b60028316156105f85761058a826001600160a01b0316610b42565b156105cc5760405162461bcd60e51b8152602060048201526012602482015271086d8c2d2da40e8ded6cadc40d2e6408aa8960731b604482015260640161033f565b6105f8826105e060608a0160408b01611907565b60808a01356105f36101208c018c611a0a565b610b8c565b5f8061060a60808a0160608b01611907565b6001600160a01b03161461062d576106286080890160608a01611907565b61062f565b335b90505f600185165f03610642575f610655565b6106556001600160a01b03851633610bb7565b90505f61066b6001600160a01b03851684610bb7565b90508a6001600160a01b031663a8920d2b348b8b6040518463ffffffff1660e01b815260040161069c929190611a7c565b5f604051808303818588803b1580156106b3575f80fd5b505af11580156106c5573d5f803e3d5ffd5b5050505060808b013590506106ed826106e76001600160a01b03881687610bb7565b90610c46565b9750600187161561078d5761071c61070e6001600160a01b03881633610bb7565b6106e78560808f0135610c51565b905061072c60a08c013582610c5c565b61073a8960808e0135610c5c565b10156107885760405162461bcd60e51b815260206004820152601b60248201527f52657475726e20616d6f756e74206973206e6f7420656e6f7567680000000000604482015260640161033f565b6107e1565b8a60a001358810156107e15760405162461bcd60e51b815260206004820152601b60248201527f52657475726e20616d6f756e74206973206e6f7420656e6f7567680000000000604482015260640161033f565b6107ef8b878787858d610c67565b50505050505050949350505050565b5f600882901c8260fe1960ff821601610826578161081b81611b64565b9250505f9050610834565b8061083081611b91565b9150505b61083f858383610d18565b95945050505050565b6108506108d0565b6001600160a01b0381166108b55760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161033f565b6103be8161092a565b5f6108ca825f80610d18565b92915050565b6033546001600160a01b031633146102875760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161033f565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b8015610a415761098a83610b42565b15610a2d575f826001600160a01b0316826040515f6040518083038185875af1925050503d805f81146109d8576040519150601f19603f3d011682016040523d82523d5f602084013e6109dd565b606091505b5050905080610a275760405162461bcd60e51b815260206004820152601660248201527508cc2d2d8cac840e8de40e8e4c2dce6cccae4408aa8960531b604482015260640161033f565b50505050565b610a416001600160a01b0384168383610df7565b505050565b5f54610100900460ff16610a6c5760405162461bcd60e51b815260040161033f90611baf565b610287610e5a565b5f54610100900460ff16610a9a5760405162461bcd60e51b815260040161033f90611baf565b610287610e89565b610aaa610afc565b6065805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610adf3390565b6040516001600160a01b03909116815260200160405180910390a1565b60655460ff16156102875760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161033f565b5f6001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1480610b7857506001600160a01b038216611010145b806108ca5750506001600160a01b03161590565b610b97858383610ebb565b610bb057610bb06001600160a01b038616338686610f9c565b5050505050565b5f610bc183610b42565b15610bd757506001600160a01b038116316108ca565b6040516370a0823160e01b81526001600160a01b0383811660048301528416906370a0823190602401602060405180830381865afa158015610c1b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c3f91906119f3565b9392505050565b5f610c3f8284611bfa565b5f610c3f8284611c0d565b5f610c3f8284611c20565b836001600160a01b0316856001600160a01b0316336001600160a01b03167f76af224a143865a50b41496e1a73622698692c565c1214bc862f18e22d829c5e868a6080013587878d60a001358e60c001358f610100016020810190610ccc9190611907565b604080516001600160a01b03988916815260208101979097528601949094526060850192909252608084015260a083015290911660c082015260e00160405180910390a4505050505050565b5f5b6097546040516313f80ad160e21b81526001600160a01b0386811660048301526001600160f81b03861660248301525f921690634fe02b4490604401602060405180830381865afa158015610d71573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d9591906119f3565b90505f198103610db357610da884611b64565b93505f925050610d1a565b60ff831615610dc25760ff83161c5b80600116600103610de05760011c610dd983611b91565b9250610dc2565b505060ff811660ff19600884901b16179392505050565b6040516001600160a01b038316602482015260448101829052610a4190849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152610fd4565b5f54610100900460ff16610e805760405162461bcd60e51b815260040161033f90611baf565b6102873361092a565b5f54610100900460ff16610eaf5760405162461bcd60e51b815260040161033f90611baf565b6065805460ff19169055565b5f8115610f935760e0821480610ed2575061010082145b15610f41575f80610ee48686866110a5565b9150915081610f3757610f1e816040518060400160405280600f81526020016e02832b936b4ba103330b4b632b21d1608d1b8152506111d3565b60405162461bcd60e51b815260040161033f9190611c59565b5f92505050610c3f565b5f80610f4d858561143d565b9150915081610f8857610f1e816040518060400160405280601081526020016f02832b936b4ba19103330b4b632b21d160851b8152506111d3565b600192505050610c3f565b505f9392505050565b6040516001600160a01b0380851660248301528316604482015260648101829052610a279085906323b872dd60e01b90608401610e23565b5f611028826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661152b9092919063ffffffff16565b805190915015610a4157808060200190518101906110469190611c8b565b610a415760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161033f565b5f606060e083900361113b576040516001600160a01b038616906110d89063d505accf60e01b9087908790602001611caa565b60408051601f19818403018152908290526110f291611ccd565b5f604051808303815f865af19150503d805f811461112b576040519150601f19603f3d011682016040523d82523d5f602084013e611130565b606091505b5090925090506111cb565b6101008390036111cb576040516001600160a01b0386169061116c906323f2ebc360e21b9087908790602001611caa565b60408051601f198184030181529082905261118691611ccd565b5f604051808303815f865af19150503d805f81146111bf576040519150601f19603f3d011682016040523d82523d5f602084013e6111c4565b606091505b5090925090505b935093915050565b6060604483511015801561120b5750825f815181106111f4576111f4611ce8565b6020910101516001600160f81b031916600160fb1b145b801561123c57508260018151811061122557611225611ce8565b6020910101516001600160f81b03191660c360f81b145b801561126d57508260028151811061125657611256611ce8565b6020910101516001600160f81b031916607960f81b145b801561129e57508260038151811061128757611287611ce8565b6020910101516001600160f81b031916600560fd1b145b15611328576044838101805190916112b69190611c0d565b845110156112fe5760405162461bcd60e51b815260206004820152601560248201527424b73b30b634b2103932bb32b93a103932b0b9b7b760591b604482015260640161033f565b8281604051602001611311929190611cfc565b6040516020818303038152906040529150506108ca565b8251602414801561135d5750825f8151811061134657611346611ce8565b6020910101516001600160f81b031916602760f91b145b801561138e57508260018151811061137757611377611ce8565b6020910101516001600160f81b031916600960fb1b145b80156113bf5750826002815181106113a8576113a8611ce8565b6020910101516001600160f81b031916607b60f81b145b80156113f05750826003815181106113d9576113d9611ce8565b6020910101516001600160f81b031916607160f81b145b156114155760248301518261140482611541565b604051602001611311929190611d4a565b816040516020016114269190611d7e565b604051602081830303815290604052905092915050565b5f60608161144d84860186611e6f565b50925050506001600160a01b038116331461149b5760405162461bcd60e51b815260206004820152600e60248201526d14195c9b5a5d0c8819195b9a595960921b604482015260640161033f565b6097546040516001600160a01b03909116906114c69063187945bd60e11b9088908890602001611caa565b60408051601f19818403018152908290526114e091611ccd565b5f604051808303815f865af19150503d805f8114611519576040519150601f19603f3d011682016040523d82523d5f602084013e61151e565b606091505b5090969095509350505050565b606061153984845f8561156d565b949350505050565b60606108ca8260405160200161155991815260200190565b604051602081830303815290604052611644565b6060824710156115ce5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161033f565b5f80866001600160a01b031685876040516115e99190611ccd565b5f6040518083038185875af1925050503d805f8114611623576040519150601f19603f3d011682016040523d82523d5f602084013e611628565b606091505b509150915061163987838387611856565b979650505050505050565b60408051808201909152601081526f181899199a1a9b1b9c1cb0b131b232b360811b60208201528151606091905f9061167e906002611c20565b611689906002611c0d565b67ffffffffffffffff8111156116a1576116a1611daa565b6040519080825280601f01601f1916602001820160405280156116cb576020820181803683370190505b509050600360fc1b815f815181106116e5576116e5611ce8565b60200101906001600160f81b03191690815f1a905350600f60fb1b8160018151811061171357611713611ce8565b60200101906001600160f81b03191690815f1a9053505f5b845181101561184e5782600486838151811061174957611749611ce8565b016020015182516001600160f81b031990911690911c60f81c90811061177157611771611ce8565b01602001516001600160f81b0319168261178c836002611c20565b611797906002611c0d565b815181106117a7576117a7611ce8565b60200101906001600160f81b03191690815f1a905350828582815181106117d0576117d0611ce8565b602091010151815160f89190911c600f169081106117f0576117f0611ce8565b01602001516001600160f81b0319168261180b836002611c20565b611816906003611c0d565b8151811061182657611826611ce8565b60200101906001600160f81b03191690815f1a9053508061184681611f66565b91505061172b565b509392505050565b606083156118c45782515f036118bd576001600160a01b0385163b6118bd5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161033f565b5081611539565b61153983838151156118d95781518083602001fd5b8060405162461bcd60e51b815260040161033f9190611c59565b6001600160a01b03811681146103be575f80fd5b5f60208284031215611917575f80fd5b8135610c3f816118f3565b5f8060408385031215611933575f80fd5b823561193e816118f3565b946020939093013593505050565b5f805f806060858703121561195f575f80fd5b843561196a816118f3565b9350602085013567ffffffffffffffff80821115611986575f80fd5b90860190610140828903121561199a575f80fd5b909350604086013590808211156119af575f80fd5b818701915087601f8301126119c2575f80fd5b8135818111156119d0575f80fd5b8860208260051b85010111156119e4575f80fd5b95989497505060200194505050565b5f60208284031215611a03575f80fd5b5051919050565b5f808335601e19843603018112611a1f575f80fd5b83018035915067ffffffffffffffff821115611a39575f80fd5b602001915036819003821315611a4d575f80fd5b9250929050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60208082528181018390525f906040808401600586901b8501820187855b88811015611b4257878303603f190184528135368b9003607e19018112611abf575f80fd5b8a018035845286810135878501528581013586850152608060608083013536849003601e19018112611aef575f80fd5b90920188810192903567ffffffffffffffff811115611b0c575f80fd5b803603841315611b1a575f80fd5b8282880152611b2c8388018286611a54565b978a019796505050928701925050600101611a9a565b509098975050505050505050565b634e487b7160e01b5f52601160045260245ffd5b5f6001600160f81b038281166002600160f81b03198101611b8757611b87611b50565b6001019392505050565b5f60ff821660ff8103611ba657611ba6611b50565b60010192915050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b818103818111156108ca576108ca611b50565b808201808211156108ca576108ca611b50565b80820281158282048414176108ca576108ca611b50565b5f5b83811015611c51578181015183820152602001611c39565b50505f910152565b602081525f8251806020840152611c77816040850160208701611c37565b601f01601f19169190910160400192915050565b5f60208284031215611c9b575f80fd5b81518015158114610c3f575f80fd5b6001600160e01b031984168152818360048301375f910160040190815292915050565b5f8251611cde818460208701611c37565b9190910192915050565b634e487b7160e01b5f52603260045260245ffd5b5f8351611d0d818460208801611c37565b6508ae4e4dee4560d31b9083019081528351611d30816006840160208801611c37565b602960f81b60069290910191820152600701949350505050565b5f8351611d5b818460208801611c37565b650a0c2dcd2c6560d31b9083019081528351611d30816006840160208801611c37565b5f8251611d8f818460208701611c37565b68556e6b6e6f776e282960b81b920191825250600901919050565b634e487b7160e01b5f52604160045260245ffd5b6040516060810167ffffffffffffffff81118282101715611de157611de1611daa565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611e1057611e10611daa565b604052919050565b5f60408284031215611e28575f80fd5b6040516040810181811067ffffffffffffffff82111715611e4b57611e4b611daa565b6040529050808235611e5c816118f3565b8152602092830135920191909152919050565b5f805f80848603610100811215611e84575f80fd5b6080811215611e91575f80fd5b50611e9a611dbe565b611ea48787611e18565b8152602060408701358183015260608701356040830152819550611ecb8860808901611e18565b945060c08701359150611edd826118f3565b90925060e08601359067ffffffffffffffff80831115611efb575f80fd5b828801925088601f840112611f0e575f80fd5b823581811115611f2057611f20611daa565b611f32601f8201601f19168401611de7565b91508082528983828601011115611f47575f80fd5b80838501848401375f8382840101525080935050505092959194509250565b5f60018201611f7757611f77611b50565b506001019056fea26469706673582212204dfc20343858ed1c05e71d9618f5dd517f4e9e8dac1f44a5660e11caba03e11764736f6c63430008140033
Deployed Bytecode Sourcemap
62706:3950:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66559:94;;;;;;;;;;-1:-1:-1;66559:94:0;;;;;:::i;:::-;;:::i;:::-;;57459:22;;;;;;;;;;-1:-1:-1;57459:22:0;;;;-1:-1:-1;;;;;57459:22:0;;;;;;-1:-1:-1;;;;;566:32:1;;;548:51;;536:2;521:18;57459:22:0;;;;;;;;41035:86;;;;;;;;;;-1:-1:-1;41106:7:0;;;;41035:86;;775:14:1;;768:22;750:41;;738:2;723:18;41035:86:0;610:187:1;18857:103:0;;;;;;;;;;;;;:::i;66339:141::-;;;;;;;;;;-1:-1:-1;66339:141:0;;;;;:::i;:::-;;:::i;63668:143::-;;;;;;;;;;;;;:::i;57490:128::-;;;;;;;;;;;;;:::i;:::-;;;1282:25:1;;;1270:2;1255:18;57490:128:0;1136:177:1;66488:63:0;;;;;;;;;;;;;:::i;18209:87::-;;;;;;;;;;-1:-1:-1;18282:6:0;;-1:-1:-1;;;;;18282:6:0;18209:87;;63819:1739;;;;;;:::i;:::-;;:::i;60334:506::-;;;;;;;;;;-1:-1:-1;60334:506:0;;;;;:::i;:::-;;:::i;19115:201::-;;;;;;;;;;-1:-1:-1;19115:201:0;;;;;:::i;:::-;;:::i;59806:136::-;;;;;;;;;;-1:-1:-1;59806:136:0;;;;;:::i;:::-;;:::i;66559:94::-;18095:13;:11;:13::i;:::-;66627:7:::1;:18:::0;;-1:-1:-1;;;;;;66627:18:0::1;-1:-1:-1::0;;;;;66627:18:0;;;::::1;::::0;;;::::1;::::0;;66559:94::o;18857:103::-;18095:13;:11;:13::i;:::-;18922:30:::1;18949:1;18922:18;:30::i;:::-;18857:103::o:0;66339:141::-;18095:13;:11;:13::i;:::-;66420:52:::1;-1:-1:-1::0;;;;;66420:23:0;::::1;66452:10;66465:6:::0;66420:23:::1;:52::i;:::-;66339:141:::0;;:::o;63668:143::-;11930:19;11953:13;;;;;;11952:14;;12000:34;;;;-1:-1:-1;12018:12:0;;12033:1;12018:12;;;;:16;12000:34;11999:108;;;-1:-1:-1;12079:4:0;1593:19;:23;;;12040:66;;-1:-1:-1;12089:12:0;;;;;:17;12040:66;11977:204;;;;-1:-1:-1;;;11977:204:0;;3110:2:1;11977:204:0;;;3092:21:1;3149:2;3129:18;;;3122:30;3188:34;3168:18;;;3161:62;-1:-1:-1;;;3239:18:1;;;3232:44;3293:19;;11977:204:0;;;;;;;;;12192:12;:16;;-1:-1:-1;;12192:16:0;12207:1;12192:16;;;12219:67;;;;12254:13;:20;;-1:-1:-1;;12254:20:0;;;;;12219:67;63720:35:::1;:33;:35::i;:::-;63766:37;:35;:37::i;:::-;12312:14:::0;12308:102;;;12359:5;12343:21;;-1:-1:-1;;12343:21:0;;;12384:14;;-1:-1:-1;3475:36:1;;12384:14:0;;3463:2:1;3448:18;12384:14:0;;;;;;;12308:102;11919:498;63668:143::o;57490:128::-;57583:7;;57574:36;;;-1:-1:-1;;;57574:36:0;;;;57547:7;;-1:-1:-1;;;;;57583:7:0;;57574:34;;:36;;;;;;;;;;;;;;57583:7;57574:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57567:43;;57490:128;:::o;66488:63::-;18095:13;:11;:13::i;:::-;66535:8:::1;:6;:8::i;63819:1739::-:0;64014:20;40640:19;:17;:19::i;:::-;64078:1:::1;64055:4;:20;;;:24;64047:63;;;::::0;-1:-1:-1;;;64047:63:0;;3913:2:1;64047:63:0::1;::::0;::::1;3895:21:1::0;3952:2;3932:18;;;3925:30;3991:28;3971:18;;;3964:56;4037:18;;64047:63:0::1;3711:350:1::0;64047:63:0::1;64129:16:::0;64121:51:::1;;;::::0;-1:-1:-1;;;64121:51:0;;4268:2:1;64121:51:0::1;::::0;::::1;4250:21:1::0;4307:2;4287:18;;;4280:30;-1:-1:-1;;;4326:18:1;;;4319:52;4388:18;;64121:51:0::1;4066:346:1::0;64121:51:0::1;64201:10;::::0;::::1;;64185:13;64240;;::::0;::::1;64201:4:::0;64240:13:::1;:::i;:::-;64222:31:::0;-1:-1:-1;64264:15:0::1;64282:13;::::0;;;::::1;::::0;::::1;;:::i;:::-;64264:31;;64330:16;:8;-1:-1:-1::0;;;;;64330:14:0::1;;:16::i;:::-;:34;;64363:1;64330:34;;;64349:4;:11;;;64330:34;64316:9;:49;64308:79;;;::::0;-1:-1:-1;;;64308:79:0;;4885:2:1;64308:79:0::1;::::0;::::1;4867:21:1::0;4924:2;4904:18;;;4897:30;-1:-1:-1;;;4943:18:1;;;4936:47;5000:18;;64308:79:0::1;4683:341:1::0;64308:79:0::1;62994:4;64404:21:::0;::::1;:26:::0;64400:182:::1;;64456:16;:8;-1:-1:-1::0;;;;;64456:14:0::1;;:16::i;:::-;64455:17;64447:48;;;::::0;-1:-1:-1;;;64447:48:0;;5231:2:1;64447:48:0::1;::::0;::::1;5213:21:1::0;5270:2;5250:18;;;5243:30;-1:-1:-1;;;5289:18:1;;;5282:48;5347:18;;64447:48:0::1;5029:342:1::0;64447:48:0::1;64510:60;64517:8:::0;64527:16:::1;::::0;;;::::1;::::0;::::1;;:::i;:::-;64545:11;::::0;::::1;;64558;;::::0;::::1;64545:4:::0;64558:11:::1;:::i;:::-;64510:6;:60::i;:::-;64594:19;::::0;64617:16:::1;::::0;;;::::1;::::0;::::1;;:::i;:::-;-1:-1:-1::0;;;;;64617:30:0::1;;64616:64;;64664:16;::::0;;;::::1;::::0;::::1;;:::i;:::-;64616:64;;;64651:10;64616:64;64594:86;;64691:25;62942:4;64720:5;:21;64745:1;64720:26:::0;64719:74:::1;;64792:1;64719:74;;;64750:39;-1:-1:-1::0;;;;;64750:27:0;::::1;64778:10;64750:27;:39::i;:::-;64691:102:::0;-1:-1:-1;64804:25:0::1;64832:40;-1:-1:-1::0;;;;;64832:27:0;::::1;64860:11:::0;64832:27:::1;:40::i;:::-;64804:68;;64885:6;-1:-1:-1::0;;;;;64885:16:0::1;;64909:9;64920:5;;64885:41;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;;;64961:11:0::1;::::0;::::1;;::::0;-1:-1:-1;64998:63:0::1;65043:17:::0;64998:40:::1;-1:-1:-1::0;;;;;64998:27:0;::::1;65026:11:::0;64998:27:::1;:40::i;:::-;:44:::0;::::1;:63::i;:::-;64983:78:::0;-1:-1:-1;62942:4:0::1;65078:21:::0;::::1;:26:::0;65074:386:::1;;65135:79;65174:39;-1:-1:-1::0;;;;;65174:27:0;::::1;65202:10;65174:27;:39::i;:::-;65135:34;:17:::0;65157:11:::1;::::0;::::1;;65135:21;:34::i;:79::-;65121:93:::0;-1:-1:-1;65270:37:0::1;:20;::::0;::::1;;65121:93:::0;65270:24:::1;:37::i;:::-;65237:29;:12:::0;65254:11:::1;::::0;::::1;;65237:16;:29::i;:::-;:70;;65229:110;;;::::0;-1:-1:-1;;;65229:110:0;;8200:2:1;65229:110:0::1;::::0;::::1;8182:21:1::0;8239:2;8219:18;;;8212:30;8278:29;8258:18;;;8251:57;8325:18;;65229:110:0::1;7998:351:1::0;65229:110:0::1;65074:386;;;65396:4;:20;;;65380:12;:36;;65372:76;;;::::0;-1:-1:-1;;;65372:76:0;;8200:2:1;65372:76:0::1;::::0;::::1;8182:21:1::0;8239:2;8219:18;;;8212:30;8278:29;8258:18;;;8251:57;8325:18;;65372:76:0::1;7998:351:1::0;65372:76:0::1;65472:78;65485:4;65491:8;65501;65511:11;65524;65537:12;65472;:78::i;:::-;64036:1522;;;;;;;63819:1739:::0;;;;;;:::o;60334:506::-;60418:13;60476:1;60467:10;;;:5;-1:-1:-1;;60535:15:0;60528:22;;;60524:255;;60640:6;;;;:::i;:::-;;;;60667:1;60661:7;;60524:255;;;60762:5;;;;:::i;:::-;;;;60524:255;60797:35;60815:5;60822:4;60828:3;60797:17;:35::i;:::-;60789:43;60334:506;-1:-1:-1;;;;;60334:506:0:o;19115:201::-;18095:13;:11;:13::i;:::-;-1:-1:-1;;;;;19204:22:0;::::1;19196:73;;;::::0;-1:-1:-1;;;19196:73:0;;9084:2:1;19196:73:0::1;::::0;::::1;9066:21:1::0;9123:2;9103:18;;;9096:30;9162:34;9142:18;;;9135:62;-1:-1:-1;;;9213:18:1;;;9206:36;9259:19;;19196:73:0::1;8882:402:1::0;19196:73:0::1;19280:28;19299:8;19280:18;:28::i;59806:136::-:0;59870:13;59904:30;59922:5;59929:1;59932;59904:17;:30::i;:::-;59896:38;59806:136;-1:-1:-1;;59806:136:0:o;18374:132::-;18282:6;;-1:-1:-1;;;;;18282:6:0;16329:10;18438:23;18430:68;;;;-1:-1:-1;;;18430:68:0;;9491:2:1;18430:68:0;;;9473:21:1;;;9510:18;;;9503:30;9569:34;9549:18;;;9542:62;9621:18;;18430:68:0;9289:356:1;19476:191:0;19569:6;;;-1:-1:-1;;;;;19586:17:0;;;-1:-1:-1;;;;;;19586:17:0;;;;;;;19619:40;;19569:6;;;19586:17;19569:6;;19619:40;;19550:16;;19619:40;19539:128;19476:191;:::o;52839:408::-;52974:10;;52970:270;;53005:12;53011:5;53005;:12::i;:::-;53001:228;;;53039:11;53056:2;-1:-1:-1;;;;;53056:7:0;53071:6;53056:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53038:44;;;53109:6;53101:41;;;;-1:-1:-1;;;53101:41:0;;10062:2:1;53101:41:0;;;10044:21:1;10101:2;10081:18;;;10074:30;-1:-1:-1;;;10120:18:1;;;10113:52;10182:18;;53101:41:0;9860:346:1;53101:41:0;53019:139;52839:408;;;:::o;53001:228::-;53183:30;-1:-1:-1;;;;;53183:18:0;;53202:2;53206:6;53183:18;:30::i;:::-;52839:408;;;:::o;17752:97::-;14073:13;;;;;;;14065:69;;;;-1:-1:-1;;;14065:69:0;;;;;;;:::i;:::-;17815:26:::1;:24;:26::i;40205:99::-:0;14073:13;;;;;;;14065:69;;;;-1:-1:-1;;;14065:69:0;;;;;;;:::i;:::-;40269:27:::1;:25;:27::i;41631:118::-:0;40640:19;:17;:19::i;:::-;41691:7:::1;:14:::0;;-1:-1:-1;;41691:14:0::1;41701:4;41691:14;::::0;;41721:20:::1;41728:12;16329:10:::0;;16249:98;41728:12:::1;41721:20;::::0;-1:-1:-1;;;;;566:32:1;;;548:51;;536:2;521:18;41721:20:0::1;;;;;;;41631:118::o:0;41194:108::-;41106:7;;;;41264:9;41256:38;;;;-1:-1:-1;;;41256:38:0;;10825:2:1;41256:38:0;;;10807:21:1;10864:2;10844:18;;;10837:30;-1:-1:-1;;;10883:18:1;;;10876:46;10939:18;;41256:38:0;10623:340:1;54061:248:0;54113:4;-1:-1:-1;;;;;54150:38:0;;52689:42;54150:38;;:95;;-1:-1:-1;;;;;;54205:40:0;;52787:42;54205:40;54150:95;:151;;;-1:-1:-1;;;;;;;54262:39:0;;;54061:248::o;66111:220::-;66217:31;66233:5;66241:6;;66217:7;:31::i;:::-;66212:112;;66265:47;-1:-1:-1;;;;;66265:22:0;;66288:10;66300:3;66305:6;66265:22;:47::i;:::-;66111:220;;;;;:::o;53813:240::-;53895:7;53919:12;53925:5;53919;:12::i;:::-;53915:131;;;-1:-1:-1;;;;;;53955:15:0;;;53948:22;;53915:131;54010:24;;-1:-1:-1;;;54010:24:0;;-1:-1:-1;;;;;566:32:1;;;54010:24:0;;;548:51:1;54010:15:0;;;;;521:18:1;;54010:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54003:31;53813:240;-1:-1:-1;;;53813:240:0:o;48580:98::-;48638:7;48665:5;48669:1;48665;:5;:::i;48199:98::-;48257:7;48284:5;48288:1;48284;:5;:::i;48937:98::-;48995:7;49022:5;49026:1;49022;:5;:::i;65566:537::-;65872:8;-1:-1:-1;;;;;65802:293:0;65849:8;-1:-1:-1;;;;;65802:293:0;65824:10;-1:-1:-1;;;;;65802:293:0;;65895:11;65921:4;:11;;;65947;65973:12;66000:4;:20;;;66035:4;:21;;;66071:4;:13;;;;;;;;;;:::i;:::-;65802:293;;;-1:-1:-1;;;;;11964:15:1;;;11946:34;;12011:2;11996:18;;11989:34;;;;12039:18;;12032:34;;;;12097:2;12082:18;;12075:34;;;;12140:3;12125:19;;12118:35;11926:3;12169:19;;12162:35;12234:15;;;12228:3;12213:19;;12206:44;11895:3;11880:19;65802:293:0;;;;;;;65566:537;;;;;;:::o;61106:896::-;61196:13;61222:773;61276:7;;61267:42;;-1:-1:-1;;;61267:42:0;;-1:-1:-1;;;;;12453:32:1;;;61267:42:0;;;12435:51:1;-1:-1:-1;;;;;12522:32:1;;12502:18;;;12495:60;61250:14:0;;61276:7;;61267:29;;12408:18:1;;61267:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61250:59;;-1:-1:-1;;61385:6:0;:27;61381:176;;61482:6;;;:::i;:::-;;;61513:1;61507:7;;61533:8;;;61381:176;61575:8;;;;61571:180;;61722:13;;;;61571:180;61826:6;61835:1;61826:10;61840:1;61826:15;61819:103;;61881:1;61871:11;61901:5;;;:::i;:::-;;;61819:103;;;-1:-1:-1;;62557:12:0;;;-1:-1:-1;;62471:1:0;62454:18;;;;62557:12;61106:896;;;;;:::o;35356:211::-;35500:58;;-1:-1:-1;;;;;12758:32:1;;35500:58:0;;;12740:51:1;12807:18;;;12800:34;;;35473:86:0;;35493:5;;-1:-1:-1;;;35523:23:0;12713:18:1;;35500:58:0;;;;-1:-1:-1;;35500:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;35500:58:0;-1:-1:-1;;;;;;35500:58:0;;;;;;;;;;35473:19;:86::i;17857:113::-;14073:13;;;;;;;14065:69;;;;-1:-1:-1;;;14065:69:0;;;;;;;:::i;:::-;17930:32:::1;16329:10:::0;17930:18:::1;:32::i;40312:97::-:0;14073:13;;;;;;;14065:69;;;;-1:-1:-1;;;14065:69:0;;;;;;;:::i;:::-;40386:7:::1;:15:::0;;-1:-1:-1;;40386:15:0::1;::::0;;40312:97::o;57626:746::-;57699:4;57720:17;;57716:626;;57775:6;57758:23;;;:50;;-1:-1:-1;57802:6:0;57785:23;;57758:50;57754:577;;;57830:12;57844:19;57867:23;57876:5;57883:6;;57867:8;:23::i;:::-;57829:61;;;;57914:7;57909:116;;57953:51;57978:6;57953:51;;;;;;;;;;;;;-1:-1:-1;;;57953:51:0;;;:24;:51::i;:::-;57946:59;;-1:-1:-1;;;57946:59:0;;;;;;;;:::i;57909:116::-;58050:5;58043:12;;;;;;57754:577;58097:12;58111:19;58134:16;58143:6;;58134:8;:16::i;:::-;58096:54;;;;58174:7;58169:117;;58213:52;58238:6;58213:52;;;;;;;;;;;;;-1:-1:-1;;;58213:52:0;;;:24;:52::i;58169:117::-;58311:4;58304:11;;;;;;57754:577;-1:-1:-1;58359:5:0;57626:746;;;;;:::o;35575:248::-;35746:68;;-1:-1:-1;;;;;13759:15:1;;;35746:68:0;;;13741:34:1;13811:15;;13791:18;;;13784:43;13843:18;;;13836:34;;;35719:96:0;;35739:5;;-1:-1:-1;;;35769:27:0;13676:18:1;;35746:68:0;13501:375:1;38423:716:0;38847:23;38873:69;38901:4;38873:69;;;;;;;;;;;;;;;;;38881:5;-1:-1:-1;;;;;38873:27:0;;;:69;;;;;:::i;:::-;38957:17;;38847:95;;-1:-1:-1;38957:21:0;38953:179;;39054:10;39043:30;;;;;;;;;;;;:::i;:::-;39035:85;;;;-1:-1:-1;;;39035:85:0;;14365:2:1;39035:85:0;;;14347:21:1;14404:2;14384:18;;;14377:30;14443:34;14423:18;;;14416:62;-1:-1:-1;;;14494:18:1;;;14487:40;14544:19;;39035:85:0;14163:406:1;58538:546:0;58611:12;58625:19;58678:6;58661:23;;;58657:420;;58796:54;;-1:-1:-1;;;;;58785:10:0;;;58796:54;;-1:-1:-1;;;58813:28:0;58843:6;;;;58796:54;;;:::i;:::-;;;;-1:-1:-1;;58796:54:0;;;;;;;;;;58785:66;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;58765:86:0;;-1:-1:-1;58765:86:0;-1:-1:-1;58657:420:0;;;58890:6;58873:23;;;58869:208;;59008:56;;-1:-1:-1;;;;;58997:10:0;;;59008:56;;-1:-1:-1;;;59025:30:0;59057:6;;;;59008:56;;;:::i;:::-;;;;-1:-1:-1;;59008:56:0;;;;;;;;;;58997:68;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;58977:88:0;;-1:-1:-1;58977:88:0;-1:-1:-1;58869:208:0;58538:546;;;;;;:::o;42826:1893::-;42905:13;43190:2;43175:4;:11;:17;;:38;;;;;43196:4;43201:1;43196:7;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;;;;;43196:7:0;-1:-1:-1;;;43196:17:0;43175:38;:59;;;;;43217:4;43222:1;43217:7;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;;;;;43217:7:0;-1:-1:-1;;;43217:17:0;43175:59;:80;;;;;43238:4;43243:1;43238:7;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;;;;;43238:7:0;-1:-1:-1;;;43238:17:0;43175:80;:101;;;;;43259:4;43264:1;43259:7;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;;;;;43259:7:0;-1:-1:-1;;;43259:17:0;43175:101;43171:1476;;;43509:2;43499:13;;;44005:20;;43499:13;;44000:25;;44005:20;44000:25;:::i;:::-;43985:4;:11;:40;;43977:74;;;;-1:-1:-1;;;43977:74:0;;15573:2:1;43977:74:0;;;15555:21:1;15612:2;15592:18;;;15585:30;-1:-1:-1;;;15631:18:1;;;15624:51;15692:18;;43977:74:0;15371:345:1;43977:74:0;44097:6;44115;44080:47;;;;;;;;;:::i;:::-;;;;;;;;;;;;;44066:62;;;;;43171:1476;44222:4;:11;44237:2;44222:17;:38;;;;;44243:4;44248:1;44243:7;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;;;;;44243:7:0;-1:-1:-1;;;44243:17:0;44222:38;:59;;;;;44264:4;44269:1;44264:7;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;;;;;44264:7:0;-1:-1:-1;;;44264:17:0;44222:59;:80;;;;;44285:4;44290:1;44285:7;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;;;;;44285:7:0;-1:-1:-1;;;44285:17:0;44222:80;:101;;;;;44306:4;44311:1;44306:7;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;;;;;44306:7:0;-1:-1:-1;;;44306:17:0;44222:101;44218:429;;;44534:2;44524:13;;44518:20;44598:6;44616:12;44518:20;44616:6;:12::i;:::-;44581:53;;;;;;;;;:::i;44218:429::-;44690:6;44673:37;;;;;;;;:::i;:::-;;;;;;;;;;;;;44659:52;;42826:1893;;;;:::o;59092:526::-;59150:12;59164:19;59150:12;59220:137;;;;59245:6;59220:137;:::i;:::-;-1:-1:-1;59196:161:0;-1:-1:-1;;;;;;;;59376:19:0;;59385:10;59376:19;59368:46;;;;-1:-1:-1;;;59368:46:0;;20697:2:1;59368:46:0;;;20679:21:1;20736:2;20716:18;;;20709:30;-1:-1:-1;;;20755:18:1;;;20748:44;20809:18;;59368:46:0;20495:338:1;59368:46:0;59505:7;;59518:62;;-1:-1:-1;;;;;59505:7:0;;;;59518:62;;-1:-1:-1;;;59535:36:0;59573:6;;;;59518:62;;;:::i;:::-;;;;-1:-1:-1;;59518:62:0;;;;;;;;;;59505:76;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59485:96:0;;;;-1:-1:-1;59092:526:0;-1:-1:-1;;;;59092:526:0:o;29206:229::-;29343:12;29375:52;29397:6;29405:4;29411:1;29414:12;29375:21;:52::i;:::-;29368:59;29206:229;-1:-1:-1;;;;29206:229:0:o;44727:125::-;44780:13;44813:31;44837:5;44820:23;;;;;;20967:19:1;;21011:2;21002:12;;20838:182;44820:23:0;;;;;;;;;;;;;44813:6;:31::i;30326:455::-;30496:12;30554:5;30529:21;:30;;30521:81;;;;-1:-1:-1;;;30521:81:0;;21227:2:1;30521:81:0;;;21209:21:1;21266:2;21246:18;;;21239:30;21305:34;21285:18;;;21278:62;-1:-1:-1;;;21356:18:1;;;21349:36;21402:19;;30521:81:0;21025:402:1;30521:81:0;30614:12;30628:23;30655:6;-1:-1:-1;;;;;30655:11:0;30674:5;30681:4;30655:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30613:73;;;;30704:69;30731:6;30739:7;30748:10;30760:12;30704:26;:69::i;:::-;30697:76;30326:455;-1:-1:-1;;;;;;;30326:455:0:o;44860:456::-;44943:42;;;;;;;;;;;;-1:-1:-1;;;44943:42:0;;;;45029:11;;44917:13;;44943:42;:21;;45029:15;;45043:1;45029:15;:::i;:::-;45025:19;;:1;:19;:::i;:::-;45015:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45015:30:0;;44996:49;;-1:-1:-1;;;45056:3:0;45060:1;45056:6;;;;;;;;:::i;:::-;;;;:12;-1:-1:-1;;;;;45056:12:0;;;;;;;;;-1:-1:-1;;;45079:3:0;45083:1;45079:6;;;;;;;;:::i;:::-;;;;:12;-1:-1:-1;;;;;45079:12:0;;;;;;;;;45107:9;45102:178;45126:4;:11;45122:1;:15;45102:178;;;45176:8;45202:1;45191:4;45196:1;45191:7;;;;;;;;:::i;:::-;;;;;45176:29;;-1:-1:-1;;;;;;45191:7:0;;;:12;;;:7;45185:19;;45176:29;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;45176:29:0;45159:3;45163:5;45167:1;45163;:5;:::i;:::-;:9;;45171:1;45163:9;:::i;:::-;45159:14;;;;;;;;:::i;:::-;;;;:46;-1:-1:-1;;;;;45159:46:0;;;;;;;;;45237:8;45252:4;45257:1;45252:7;;;;;;;;:::i;:::-;;;;;;45237:31;;45252:7;;;;;45262:4;45246:21;;45237:31;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;45237:31:0;45220:3;45224:5;45228:1;45224;:5;:::i;:::-;:9;;45232:1;45224:9;:::i;:::-;45220:14;;;;;;;;:::i;:::-;;;;:48;-1:-1:-1;;;;;45220:48:0;;;;;;;;-1:-1:-1;45139:3:0;;;;:::i;:::-;;;;45102:178;;;-1:-1:-1;45304:3:0;44860:456;-1:-1:-1;;;44860:456:0:o;32899:644::-;33084:12;33113:7;33109:427;;;33141:10;:17;33162:1;33141:22;33137:290;;-1:-1:-1;;;;;1593:19:0;;;33351:60;;;;-1:-1:-1;;;33351:60:0;;21774:2:1;33351:60:0;;;21756:21:1;21813:2;21793:18;;;21786:30;21852:31;21832:18;;;21825:59;21901:18;;33351:60:0;21572:353:1;33351:60:0;-1:-1:-1;33448:10:0;33441:17;;33109:427;33491:33;33499:10;33511:12;34246:17;;:21;34242:388;;34478:10;34472:17;34535:15;34522:10;34518:2;34514:19;34507:44;34242:388;34605:12;34598:20;;-1:-1:-1;;;34598:20:0;;;;;;;;:::i;14:131:1:-;-1:-1:-1;;;;;89:31:1;;79:42;;69:70;;135:1;132;125:12;150:247;209:6;262:2;250:9;241:7;237:23;233:32;230:52;;;278:1;275;268:12;230:52;317:9;304:23;336:31;361:5;336:31;:::i;802:329::-;884:6;892;945:2;933:9;924:7;920:23;916:32;913:52;;;961:1;958;951:12;913:52;1000:9;987:23;1019:31;1044:5;1019:31;:::i;:::-;1069:5;1121:2;1106:18;;;;1093:32;;-1:-1:-1;;;802:329:1:o;1318:1083::-;1517:6;1525;1533;1541;1594:2;1582:9;1573:7;1569:23;1565:32;1562:52;;;1610:1;1607;1600:12;1562:52;1649:9;1636:23;1668:31;1693:5;1668:31;:::i;:::-;1718:5;-1:-1:-1;1774:2:1;1759:18;;1746:32;1797:18;1827:14;;;1824:34;;;1854:1;1851;1844:12;1824:34;1877:22;;;;1933:3;1915:16;;;1911:26;1908:46;;;1950:1;1947;1940:12;1908:46;1973:2;;-1:-1:-1;2028:2:1;2013:18;;2000:32;;2044:16;;;2041:36;;;2073:1;2070;2063:12;2041:36;2111:8;2100:9;2096:24;2086:34;;2158:7;2151:4;2147:2;2143:13;2139:27;2129:55;;2180:1;2177;2170:12;2129:55;2220:2;2207:16;2246:2;2238:6;2235:14;2232:34;;;2262:1;2259;2252:12;2232:34;2315:7;2310:2;2300:6;2297:1;2293:14;2289:2;2285:23;2281:32;2278:45;2275:65;;;2336:1;2333;2326:12;2275:65;1318:1083;;;;-1:-1:-1;;2367:2:1;2359:11;;-1:-1:-1;;;1318:1083:1:o;3522:184::-;3592:6;3645:2;3633:9;3624:7;3620:23;3616:32;3613:52;;;3661:1;3658;3651:12;3613:52;-1:-1:-1;3684:16:1;;3522:184;-1:-1:-1;3522:184:1:o;5376:521::-;5453:4;5459:6;5519:11;5506:25;5613:2;5609:7;5598:8;5582:14;5578:29;5574:43;5554:18;5550:68;5540:96;;5632:1;5629;5622:12;5540:96;5659:33;;5711:20;;;-1:-1:-1;5754:18:1;5743:30;;5740:50;;;5786:1;5783;5776:12;5740:50;5819:4;5807:17;;-1:-1:-1;5850:14:1;5846:27;;;5836:38;;5833:58;;;5887:1;5884;5877:12;5833:58;5376:521;;;;;:::o;5902:266::-;5990:6;5985:3;5978:19;6042:6;6035:5;6028:4;6023:3;6019:14;6006:43;-1:-1:-1;6094:1:1;6069:16;;;6087:4;6065:27;;;6058:38;;;;6150:2;6129:15;;;-1:-1:-1;;6125:29:1;6116:39;;;6112:50;;5902:266::o;6173:1820::-;6422:2;6474:21;;;6447:18;;;6530:22;;;6393:4;;6571:2;6589:18;;;6653:1;6649:14;;;6634:30;;6630:39;;6692:6;6393:4;6726:1238;6740:6;6737:1;6734:13;6726:1238;;;6805:22;;;-1:-1:-1;;6801:36:1;6789:49;;6877:20;;6952:14;6948:27;;;-1:-1:-1;;6944:42:1;6920:67;;6910:95;;7001:1;6998;6991:12;6910:95;7031:31;;7117:19;;7102:35;;7187:14;;;7174:28;7157:15;;;7150:53;7253:14;;;7240:28;7223:15;;;7216:53;7085:4;7292;7350:14;;;7337:28;7422:14;7418:26;;;-1:-1:-1;;7414:40:1;7388:67;;7378:95;;7469:1;7466;7459:12;7378:95;7501:32;;;7609:16;;;;-1:-1:-1;7560:21:1;7652:18;7641:30;;7638:50;;;7684:1;7681;7674:12;7638:50;7737:6;7721:14;7717:27;7708:7;7704:41;7701:61;;;7758:1;7755;7748:12;7701:61;7799:2;7794;7786:6;7782:15;7775:27;7825:59;7880:2;7872:6;7868:15;7860:6;7851:7;7825:59;:::i;:::-;7942:12;;;;7815:69;-1:-1:-1;;;7907:15:1;;;;-1:-1:-1;;6762:1:1;6755:9;6726:1238;;;-1:-1:-1;7981:6:1;;6173:1820;-1:-1:-1;;;;;;;;6173:1820:1:o;8354:127::-;8415:10;8410:3;8406:20;8403:1;8396:31;8446:4;8443:1;8436:15;8470:4;8467:1;8460:15;8486:211;8525:3;-1:-1:-1;;;;;8596:14:1;;;-1:-1:-1;;;;;;8622:15:1;;8619:41;;8640:18;;:::i;:::-;8689:1;8676:15;;8486:211;-1:-1:-1;;;8486:211:1:o;8702:175::-;8739:3;8783:4;8776:5;8772:16;8812:4;8803:7;8800:17;8797:43;;8820:18;;:::i;:::-;8869:1;8856:15;;8702:175;-1:-1:-1;;8702:175:1:o;10211:407::-;10413:2;10395:21;;;10452:2;10432:18;;;10425:30;10491:34;10486:2;10471:18;;10464:62;-1:-1:-1;;;10557:2:1;10542:18;;10535:41;10608:3;10593:19;;10211:407::o;11157:128::-;11224:9;;;11245:11;;;11242:37;;;11259:18;;:::i;11290:125::-;11355:9;;;11376:10;;;11373:36;;;11389:18;;:::i;11420:168::-;11493:9;;;11524;;11541:15;;;11535:22;;11521:37;11511:71;;11562:18;;:::i;12845:250::-;12930:1;12940:113;12954:6;12951:1;12948:13;12940:113;;;13030:11;;;13024:18;13011:11;;;13004:39;12976:2;12969:10;12940:113;;;-1:-1:-1;;13087:1:1;13069:16;;13062:27;12845:250::o;13100:396::-;13249:2;13238:9;13231:21;13212:4;13281:6;13275:13;13324:6;13319:2;13308:9;13304:18;13297:34;13340:79;13412:6;13407:2;13396:9;13392:18;13387:2;13379:6;13375:15;13340:79;:::i;:::-;13480:2;13459:15;-1:-1:-1;;13455:29:1;13440:45;;;;13487:2;13436:54;;13100:396;-1:-1:-1;;13100:396:1:o;13881:277::-;13948:6;14001:2;13989:9;13980:7;13976:23;13972:32;13969:52;;;14017:1;14014;14007:12;13969:52;14049:9;14043:16;14102:5;14095:13;14088:21;14081:5;14078:32;14068:60;;14124:1;14121;14114:12;14574:368;-1:-1:-1;;;;;;14769:33:1;;14757:46;;14846:6;14838;14834:1;14825:11;;14812:41;14739:3;14876:16;;14894:1;14872:24;14905:13;;;14872:24;14574:368;-1:-1:-1;;14574:368:1:o;14947:287::-;15076:3;15114:6;15108:13;15130:66;15189:6;15184:3;15177:4;15169:6;15165:17;15130:66;:::i;:::-;15212:16;;;;;14947:287;-1:-1:-1;;14947:287:1:o;15239:127::-;15300:10;15295:3;15291:20;15288:1;15281:31;15331:4;15328:1;15321:15;15355:4;15352:1;15345:15;15721:799;16102:3;16140:6;16134:13;16156:66;16215:6;16210:3;16203:4;16195:6;16191:17;16156:66;:::i;:::-;-1:-1:-1;;;16244:16:1;;;16269:23;;;16317:13;;16339:78;16317:13;16404:1;16393:13;;16386:4;16374:17;;16339:78;:::i;:::-;-1:-1:-1;;;16480:1:1;16436:20;;;;16472:10;;;16465:23;16512:1;16504:10;;15721:799;-1:-1:-1;;;;15721:799:1:o;16525:::-;16906:3;16944:6;16938:13;16960:66;17019:6;17014:3;17007:4;16999:6;16995:17;16960:66;:::i;:::-;-1:-1:-1;;;17048:16:1;;;17073:23;;;17121:13;;17143:78;17121:13;17208:1;17197:13;;17190:4;17178:17;;17143:78;:::i;17329:460::-;17561:3;17599:6;17593:13;17615:66;17674:6;17669:3;17662:4;17654:6;17650:17;17615:66;:::i;:::-;-1:-1:-1;;;17703:16:1;;17728:26;;;-1:-1:-1;17781:1:1;17770:13;;17329:460;-1:-1:-1;17329:460:1:o;17794:127::-;17855:10;17850:3;17846:20;17843:1;17836:31;17886:4;17883:1;17876:15;17910:4;17907:1;17900:15;17926:253;17998:2;17992:9;18040:4;18028:17;;18075:18;18060:34;;18096:22;;;18057:62;18054:88;;;18122:18;;:::i;:::-;18158:2;18151:22;17926:253;:::o;18184:275::-;18255:2;18249:9;18320:2;18301:13;;-1:-1:-1;;18297:27:1;18285:40;;18355:18;18340:34;;18376:22;;;18337:62;18334:88;;;18402:18;;:::i;:::-;18438:2;18431:22;18184:275;;-1:-1:-1;18184:275:1:o;18464:558::-;18527:5;18575:4;18563:9;18558:3;18554:19;18550:30;18547:50;;;18593:1;18590;18583:12;18547:50;18626:4;18620:11;18670:4;18662:6;18658:17;18741:6;18729:10;18726:22;18705:18;18693:10;18690:34;18687:62;18684:88;;;18752:18;;:::i;:::-;18788:4;18781:24;18823:6;-1:-1:-1;18823:6:1;18853:23;;18885:33;18853:23;18885:33;:::i;:::-;18927:23;;19011:2;18996:18;;;18983:32;18966:15;;18959:57;;;;18464:558;;-1:-1:-1;18464:558:1:o;19027:1463::-;19208:6;19216;19224;19232;19276:9;19267:7;19263:23;19306:3;19302:2;19298:12;19295:32;;;19323:1;19320;19313:12;19295:32;19347:4;19343:2;19339:13;19336:33;;;19365:1;19362;19355:12;19336:33;;19391:22;;:::i;:::-;19436:54;19482:7;19471:9;19436:54;:::i;:::-;19429:5;19422:69;19510:4;19574:2;19563:9;19559:18;19546:32;19541:2;19534:5;19530:14;19523:56;19639:4;19628:9;19624:20;19611:34;19606:2;19599:5;19595:14;19588:58;19665:5;19655:15;;19689:65;19746:7;19739:4;19728:9;19724:20;19689:65;:::i;:::-;19679:75;;19806:3;19795:9;19791:19;19778:33;19763:48;;19820:33;19845:7;19820:33;:::i;:::-;19872:7;;-1:-1:-1;19930:3:1;19915:19;;19902:33;;19954:18;19984:14;;;19981:34;;;20011:1;20008;20001:12;19981:34;20049:6;20038:9;20034:22;20024:32;;20094:7;20087:4;20083:2;20079:13;20075:27;20065:55;;20116:1;20113;20106:12;20065:55;20152:2;20139:16;20174:2;20170;20167:10;20164:36;;;20180:18;;:::i;:::-;20222:53;20265:2;20246:13;;-1:-1:-1;;20242:27:1;20238:36;;20222:53;:::i;:::-;20209:66;;20298:2;20291:5;20284:17;20338:7;20333:2;20328;20324;20320:11;20316:20;20313:33;20310:53;;;20359:1;20356;20349:12;20310:53;20414:2;20409;20405;20401:11;20396:2;20389:5;20385:14;20372:45;20458:1;20453:2;20448;20441:5;20437:14;20433:23;20426:34;;20479:5;20469:15;;;;;19027:1463;;;;;;;:::o;21432:135::-;21471:3;21492:17;;;21489:43;;21512:18;;:::i;:::-;-1:-1:-1;21559:1:1;21548:13;;21432:135::o
Swarm Source
ipfs://4dfc20343858ed1c05e71d9618f5dd517f4e9e8dac1f44a5660e11caba03e117
Loading...
Loading
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.