Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Loading...
Loading
Contract Name:
Pool
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity)
/** *Submitted for verification at sepolia-optimism.etherscan.io on 2023-11-01 */ // OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } } // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } } pragma solidity ^0.8.8; type ShortString is bytes32; /** * @dev This library provides functions to convert short memory strings * into a `ShortString` type that can be used as an immutable variable. * Strings of arbitrary length can be optimized if they are short enough by * the addition of a storage variable used as fallback. * * Usage example: * * ```solidity * contract Named { * using ShortStrings for *; * * ShortString private immutable _name; * string private _nameFallback; * * constructor(string memory contractName) { * _name = contractName.toShortStringWithFallback(_nameFallback); * } * * function name() external view returns (string memory) { * return _name.toStringWithFallback(_nameFallback); * } * } * ``` */ library ShortStrings { error StringTooLong(string str); /** * @dev Encode a string of at most 31 chars into a `ShortString`. * * This will trigger a `StringTooLong` error is the input string is too long. */ function toShortString(string memory str) internal pure returns (ShortString) { bytes memory bstr = bytes(str); if (bstr.length > 31) { revert StringTooLong(str); } return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length)); } /** * @dev Decode a `ShortString` back to a "normal" string. */ function toString(ShortString sstr) internal pure returns (string memory) { uint256 len = length(sstr); // using `new string(len)` would work locally but is not memory safe. string memory str = new string(32); /// @solidity memory-safe-assembly assembly { mstore(str, len) mstore(add(str, 0x20), sstr) } return str; } /** * @dev Return the length of a `ShortString`. */ function length(ShortString sstr) internal pure returns (uint256) { return uint256(ShortString.unwrap(sstr)) & 0xFF; } /** * @dev Encode a string into a `ShortString`, or write it to storage if it is too long. */ function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) { if (bytes(value).length < 32) { return toShortString(value); } else { StorageSlot.getStringSlot(store).value = value; return ShortString.wrap(0); } } /** * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}. */ function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) { if (length(value) > 0) { return toString(value); } else { return store; } } } // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } } // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } } // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IERC5267 { /** * @dev MAY be emitted to signal that the domain could have changed. */ event EIP712DomainChanged(); /** * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712 * signature. */ function eip712Domain() external view returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ); } // OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/EIP712.sol) pragma solidity ^0.8.8; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding * they need in their contracts using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the * separator from the immutable values, which is cheaper than accessing a cached version in cold storage. * * _Available since v3.4._ * * @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment */ abstract contract EIP712 is IERC5267 { using ShortStrings for *; bytes32 private constant _TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); /* solhint-disable var-name-mixedcase */ // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to // invalidate the cached domain separator if the chain id changes. bytes32 private immutable _cachedDomainSeparator; uint256 private immutable _cachedChainId; address private immutable _cachedThis; ShortString private immutable _name; ShortString private immutable _version; string private _nameFallback; string private _versionFallback; bytes32 private immutable _hashedName; bytes32 private immutable _hashedVersion; /* solhint-enable var-name-mixedcase */ /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ constructor(string memory name, string memory version) { _name = name.toShortStringWithFallback(_nameFallback); _version = version.toShortStringWithFallback(_versionFallback); _hashedName = keccak256(bytes(name)); _hashedVersion = keccak256(bytes(version)); _cachedChainId = block.chainid; _cachedDomainSeparator = _buildDomainSeparator(); _cachedThis = address(this); } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { if (address(this) == _cachedThis && block.chainid == _cachedChainId) { return _cachedDomainSeparator; } else { return _buildDomainSeparator(); } } function _buildDomainSeparator() private view returns (bytes32) { return keccak256(abi.encode(_TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash); } /** * @dev See {EIP-5267}. */ function eip712Domain() public view virtual override returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ) { return ( hex"0f", // 01111 _name.toStringWithFallback(_nameFallback), _version.toStringWithFallback(_versionFallback), block.chainid, address(this), bytes32(0), new uint256[](0) ); } } // OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) { // 32 is the length in bytes of hash, // enforced by the type signature above /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") mstore(0x1c, hash) message := keccak256(0x00, 0x3c) } } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, "\x19\x01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) data := keccak256(ptr, 0x42) } } /** * @dev Returns an Ethereum Signed Data with intended validator, created from a * `validator` and `data` according to the version 0 of EIP-191. * * See {recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x00", validator, data)); } } // 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 Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // 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); } // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // 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 * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.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); } } } // OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } } // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/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); } // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/ERC20Permit.sol) // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the default value returned by this function, unless * it's overridden. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer(address from, address to, uint256 amount) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by // decrementing then incrementing. _balances[to] += amount; } emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; unchecked { // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. _balances[account] += amount; } emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; // Overflow not possible: amount <= accountBalance <= totalSupply. _totalSupply -= amount; } emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 amount) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {} } pragma solidity ^0.8.0; /** * @dev Implementation 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. * * _Available since v3.4._ */ abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 { using Counters for Counters.Counter; mapping(address => Counters.Counter) private _nonces; // solhint-disable-next-line var-name-mixedcase bytes32 private constant _PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); /** * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`. * However, to ensure consistency with the upgradeable transpiler, we will continue * to reserve a slot. * @custom:oz-renamed-from _PERMIT_TYPEHASH */ // solhint-disable-next-line var-name-mixedcase bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT; /** * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`. * * It's a good idea to use the same `name` that is defined as the ERC20 token name. */ constructor(string memory name) EIP712(name, "1") {} /** * @dev See {IERC20Permit-permit}. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual override { require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline)); bytes32 hash = _hashTypedDataV4(structHash); address signer = ECDSA.recover(hash, v, r, s); require(signer == owner, "ERC20Permit: invalid signature"); _approve(owner, spender, value); } /** * @dev See {IERC20Permit-nonces}. */ function nonces(address owner) public view virtual override returns (uint256) { return _nonces[owner].current(); } /** * @dev See {IERC20Permit-DOMAIN_SEPARATOR}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view override returns (bytes32) { return _domainSeparatorV4(); } /** * @dev "Consume a nonce": return the current value and increment. * * _Available since v4.1._ */ function _useNonce(address owner) internal virtual returns (uint256 current) { Counters.Counter storage nonce = _nonces[owner]; current = nonce.current(); nonce.increment(); } } // 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"); } } } pragma solidity 0.8.19; /// @title PoolFees /// @notice Contract used as 1:1 pool relationship to split out fees. /// @notice Ensures curve does not need to be modified for LP shares. contract PoolFees { using SafeERC20 for IERC20; address internal immutable pool; // The pool it is bonded to address internal immutable token0; // token0 of pool, saved localy and statically for gas optimization address internal immutable token1; // Token1 of pool, saved localy and statically for gas optimization error NotPool(); constructor(address _token0, address _token1) { pool = msg.sender; token0 = _token0; token1 = _token1; } /// @notice Allow the pool to transfer fees to users function claimFeesFor(address _recipient, uint256 _amount0, uint256 _amount1) external { if (msg.sender != pool) revert NotPool(); if (_amount0 > 0) IERC20(token0).safeTransfer(_recipient, _amount0); if (_amount1 > 0) IERC20(token1).safeTransfer(_recipient, _amount1); } } pragma solidity ^0.8.0; interface IPoolFactory { event SetFeeManager(address feeManager); event SetPauser(address pauser); event SetPauseState(bool state); event SetVoter(address voter); event PoolCreated(address indexed token0, address indexed token1, bool indexed stable, address pool, uint256); event SetCustomFee(address indexed pool, uint256 fee); error FeeInvalid(); error FeeTooHigh(); error InvalidPool(); error NotFeeManager(); error NotPauser(); error NotSinkConverter(); error NotVoter(); error PoolAlreadyExists(); error SameAddress(); error ZeroFee(); error ZeroAddress(); /// @notice returns the number of pools created from this factory function allPoolsLength() external view returns (uint256); /// @notice Is a valid pool created by this factory. /// @param . function isPool(address pool) external view returns (bool); /// @notice Support for Velodrome v1 which wraps around isPool(pool); /// @param . function isPair(address pool) external view returns (bool); /// @notice Return address of pool created by this factory /// @param tokenA . /// @param tokenB . /// @param stable True if stable, false if volatile function getPool(address tokenA, address tokenB, bool stable) external view returns (address); /// @notice Support for v3-style pools which wraps around getPool(tokenA,tokenB,stable) /// @dev fee is converted to stable boolean. /// @param tokenA . /// @param tokenB . /// @param fee 1 if stable, 0 if volatile, else returns address(0) function getPool(address tokenA, address tokenB, uint24 fee) external view returns (address); /// @notice Support for Velodrome v1 pools as a "pool" was previously referenced as "pair" /// @notice Wraps around getPool(tokenA,tokenB,stable) function getPair(address tokenA, address tokenB, bool stable) external view returns (address); /// @dev Only called once to set to Voter.sol - Voter does not have a function /// to call this contract method, so once set it's immutable. /// This also follows convention of setVoterAndDistributor() in VotingEscrow.sol /// @param _voter . function setVoter(address _voter) external; function setSinkConverter(address _sinkConvert, address _velo, address _veloV2) external; function setPauser(address _pauser) external; function setPauseState(bool _state) external; function setFeeManager(address _feeManager) external; /// @notice Set default fee for stable and volatile pools. /// @dev Throws if higher than maximum fee. /// Throws if fee is zero. /// @param _stable Stable or volatile pool. /// @param _fee . function setFee(bool _stable, uint256 _fee) external; /// @notice Set overriding fee for a pool from the default /// @dev A custom fee of zero means the default fee will be used. function setCustomFee(address _pool, uint256 _fee) external; /// @notice Returns fee for a pool, as custom fees are possible. function getFee(address _pool, bool _stable) external view returns (uint256); /// @notice Create a pool given two tokens and if they're stable/volatile /// @dev token order does not matter /// @param tokenA . /// @param tokenB . /// @param stable . function createPool(address tokenA, address tokenB, bool stable) external returns (address pool); /// @notice Support for v3-style pools which wraps around createPool(tokena,tokenB,stable) /// @dev fee is converted to stable boolean /// @dev token order does not matter /// @param tokenA . /// @param tokenB . /// @param fee 1 if stable, 0 if volatile, else revert function createPool(address tokenA, address tokenB, uint24 fee) external returns (address pool); /// @notice Support for Velodrome v1 which wraps around createPool(tokenA,tokenB,stable) function createPair(address tokenA, address tokenB, bool stable) external returns (address pool); function isPaused() external view returns (bool); function velo() external view returns (address); function veloV2() external view returns (address); function voter() external view returns (address); function sinkConverter() external view returns (address); function implementation() external view returns (address); } pragma solidity ^0.8.0; interface IPoolCallee { function hook(address sender, uint256 amount0, uint256 amount1, bytes calldata data) external; } pragma solidity ^0.8.0; interface IVoter { error AlreadyVotedOrDeposited(); error DistributeWindow(); error FactoryPathNotApproved(); error GaugeAlreadyKilled(); error GaugeAlreadyRevived(); error GaugeExists(); error GaugeDoesNotExist(address _pool); error GaugeNotAlive(address _gauge); error InactiveManagedNFT(); error MaximumVotingNumberTooLow(); error NonZeroVotes(); error NotAPool(); error NotApprovedOrOwner(); error NotGovernor(); error NotEmergencyCouncil(); error NotMinter(); error NotWhitelistedNFT(); error NotWhitelistedToken(); error SameValue(); error SpecialVotingWindow(); error TooManyPools(); error UnequalLengths(); error ZeroBalance(); error ZeroAddress(); event GaugeCreated( address indexed poolFactory, address indexed votingRewardsFactory, address indexed gaugeFactory, address pool, address bribeVotingReward, address feeVotingReward, address gauge, address creator ); event GaugeKilled(address indexed gauge); event GaugeRevived(address indexed gauge); event Voted( address indexed voter, address indexed pool, uint256 indexed tokenId, uint256 weight, uint256 totalWeight, uint256 timestamp ); event Abstained( address indexed voter, address indexed pool, uint256 indexed tokenId, uint256 weight, uint256 totalWeight, uint256 timestamp ); event NotifyReward(address indexed sender, address indexed reward, uint256 amount); event DistributeReward(address indexed sender, address indexed gauge, uint256 amount); event WhitelistToken(address indexed whitelister, address indexed token, bool indexed _bool); event WhitelistNFT(address indexed whitelister, uint256 indexed tokenId, bool indexed _bool); // mappings function gauges(address pool) external view returns (address); function poolForGauge(address gauge) external view returns (address); function gaugeToFees(address gauge) external view returns (address); function gaugeToBribe(address gauge) external view returns (address); function weights(address pool) external view returns (uint256); function votes(uint256 tokenId, address pool) external view returns (uint256); function usedWeights(uint256 tokenId) external view returns (uint256); function lastVoted(uint256 tokenId) external view returns (uint256); function isGauge(address) external view returns (bool); function isWhitelistedToken(address token) external view returns (bool); function isWhitelistedNFT(uint256 tokenId) external view returns (bool); function isAlive(address gauge) external view returns (bool); function ve() external view returns (address); function governor() external view returns (address); function epochGovernor() external view returns (address); function emergencyCouncil() external view returns (address); function length() external view returns (uint256); /// @notice Called by Minter to distribute weekly emissions rewards for disbursement amongst gauges. /// @dev Assumes totalWeight != 0 (Will never be zero as long as users are voting). /// Throws if not called by minter. /// @param _amount Amount of rewards to distribute. function notifyRewardAmount(uint256 _amount) external; /// @dev Utility to distribute to gauges of pools in range _start to _finish. /// @param _start Starting index of gauges to distribute to. /// @param _finish Ending index of gauges to distribute to. function distribute(uint256 _start, uint256 _finish) external; /// @dev Utility to distribute to gauges of pools in array. /// @param _gauges Array of gauges to distribute to. function distribute(address[] memory _gauges) external; /// @notice Called by users to update voting balances in voting rewards contracts. /// @param _tokenId Id of veNFT whose balance you wish to update. function poke(uint256 _tokenId) external; /// @notice Called by users to vote for pools. Votes distributed proportionally based on weights. /// Can only vote or deposit into a managed NFT once per epoch. /// Can only vote for gauges that have not been killed. /// @dev Weights are distributed proportional to the sum of the weights in the array. /// Throws if length of _poolVote and _weights do not match. /// @param _tokenId Id of veNFT you are voting with. /// @param _poolVote Array of pools you are voting for. /// @param _weights Weights of pools. function vote(uint256 _tokenId, address[] calldata _poolVote, uint256[] calldata _weights) external; /// @notice Called by users to reset voting state. Required if you wish to make changes to /// veNFT state (e.g. merge, split, deposit into managed etc). /// Cannot reset in the same epoch that you voted in. /// Can vote or deposit into a managed NFT again after reset. /// @param _tokenId Id of veNFT you are reseting. function reset(uint256 _tokenId) external; /// @notice Called by users to deposit into a managed NFT. /// Can only vote or deposit into a managed NFT once per epoch. /// Note that NFTs deposited into a managed NFT will be re-locked /// to the maximum lock time on withdrawal. /// @dev Throws if not approved or owner. /// Throws if managed NFT is inactive. /// Throws if depositing within privileged window (one hour prior to epoch flip). function depositManaged(uint256 _tokenId, uint256 _mTokenId) external; /// @notice Called by users to withdraw from a managed NFT. /// Cannot do it in the same epoch that you deposited into a managed NFT. /// Can vote or deposit into a managed NFT again after withdrawing. /// Note that the NFT withdrawn is re-locked to the maximum lock time. function withdrawManaged(uint256 _tokenId) external; /// @notice Claim emissions from gauges. /// @param _gauges Array of gauges to collect emissions from. function claimRewards(address[] memory _gauges) external; /// @notice Claim bribes for a given NFT. /// @dev Utility to help batch bribe claims. /// @param _bribes Array of BribeVotingReward contracts to collect from. /// @param _tokens Array of tokens that are used as bribes. /// @param _tokenId Id of veNFT that you wish to claim bribes for. function claimBribes(address[] memory _bribes, address[][] memory _tokens, uint256 _tokenId) external; /// @notice Claim fees for a given NFT. /// @dev Utility to help batch fee claims. /// @param _fees Array of FeesVotingReward contracts to collect from. /// @param _tokens Array of tokens that are used as fees. /// @param _tokenId Id of veNFT that you wish to claim fees for. function claimFees(address[] memory _fees, address[][] memory _tokens, uint256 _tokenId) external; /// @notice Set new governor. /// @dev Throws if not called by governor. /// @param _governor . function setGovernor(address _governor) external; /// @notice Set new epoch based governor. /// @dev Throws if not called by governor. /// @param _epochGovernor . function setEpochGovernor(address _epochGovernor) external; /// @notice Set new emergency council. /// @dev Throws if not called by emergency council. /// @param _emergencyCouncil . function setEmergencyCouncil(address _emergencyCouncil) external; /// @notice Whitelist (or unwhitelist) token for use in bribes. /// @dev Throws if not called by governor. /// @param _token . /// @param _bool . function whitelistToken(address _token, bool _bool) external; /// @notice Whitelist (or unwhitelist) token id for voting in last hour prior to epoch flip. /// @dev Throws if not called by governor. /// Throws if already whitelisted. /// @param _tokenId . /// @param _bool . function whitelistNFT(uint256 _tokenId, bool _bool) external; /// @notice Create a new gauge (unpermissioned). /// @dev Governor can create a new gauge for a pool with any address. /// @dev V1 gauges can only be created by governor. /// @param _poolFactory . /// @param _pool . function createGauge(address _poolFactory, address _pool) external returns (address); /// @notice Kills a gauge. The gauge will not receive any new emissions and cannot be deposited into. /// Can still withdraw from gauge. /// @dev Throws if not called by emergency council. /// Throws if gauge already killed. /// @param _gauge . function killGauge(address _gauge) external; /// @notice Revives a killed gauge. Gauge will can receive emissions and deposits again. /// @dev Throws if not called by emergency council. /// Throws if gauge is not killed. /// @param _gauge . function reviveGauge(address _gauge) external; /// @dev Update claims to emissions for an array of gauges. /// @param _gauges Array of gauges to update emissions for. function updateFor(address[] memory _gauges) external; /// @dev Update claims to emissions for gauges based on their pool id as stored in Voter. /// @param _start Starting index of pools. /// @param _end Ending index of pools. function updateFor(uint256 _start, uint256 _end) external; /// @dev Update claims to emissions for single gauge /// @param _gauge . function updateFor(address _gauge) external; } // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } } pragma solidity ^0.8.0; interface IPool { error DepositsNotEqual(); error BelowMinimumK(); error FactoryAlreadySet(); error InsufficientLiquidity(); error InsufficientLiquidityMinted(); error InsufficientLiquidityBurned(); error InsufficientOutputAmount(); error InsufficientInputAmount(); error IsPaused(); error InvalidTo(); error K(); error NotEmergencyCouncil(); event Fees(address indexed sender, uint256 amount0, uint256 amount1); event Mint(address indexed sender, uint256 amount0, uint256 amount1); event Burn(address indexed sender, address indexed to, uint256 amount0, uint256 amount1); event Swap( address indexed sender, address indexed to, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out ); event Sync(uint256 reserve0, uint256 reserve1); event Claim(address indexed sender, address indexed recipient, uint256 amount0, uint256 amount1); function metadata() external view returns (uint256 dec0, uint256 dec1, uint256 r0, uint256 r1, bool st, address t0, address t1); function claimFees() external returns (uint256, uint256); function tokens() external view returns (address, address); function token0() external view returns (address); function token1() external view returns (address); function stable() external view returns (bool); function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external; function burn(address to) external returns (uint256 amount0, uint256 amount1); function mint(address to) external returns (uint256 liquidity); function getReserves() external view returns (uint256 _reserve0, uint256 _reserve1, uint256 _blockTimestampLast); function getAmountOut(uint256, address) external view returns (uint256); function skim(address to) external; function initialize(address _token0, address _token1, bool _stable) external; } pragma solidity 0.8.19; /// @title Pool /// @author velodrome.finance, @figs999, @pegahcarter /// @notice Veldrome V2 token pool, either stable or volatile contract Pool is IPool, ERC20Permit, ReentrancyGuard { using SafeERC20 for IERC20; string private _name; string private _symbol; address private _voter; // Used to denote stable or volatile pool bool public stable; uint256 internal constant MINIMUM_LIQUIDITY = 10 ** 3; uint256 internal constant MINIMUM_K = 10 ** 10; address public token0; address public token1; address public poolFees; address public factory; // Structure to capture time period obervations every 30 minutes, used for local oracles struct Observation { uint256 timestamp; uint256 reserve0Cumulative; uint256 reserve1Cumulative; } // Capture oracle reading every 30 minutes uint256 constant periodSize = 1800; Observation[] public observations; uint256 internal decimals0; uint256 internal decimals1; uint256 public reserve0; uint256 public reserve1; uint256 public blockTimestampLast; uint256 public reserve0CumulativeLast; uint256 public reserve1CumulativeLast; // index0 and index1 are used to accumulate fees, this is split out from normal trades to keep the swap "clean" // this further allows LP holders to easily claim fees for tokens they have/staked uint256 public index0 = 0; uint256 public index1 = 0; // position assigned to each LP to track their current index0 & index1 vs the global position mapping(address => uint256) public supplyIndex0; mapping(address => uint256) public supplyIndex1; // tracks the amount of unclaimed, but claimable tokens off of fees for token0 and token1 mapping(address => uint256) public claimable0; mapping(address => uint256) public claimable1; constructor() ERC20("", "") ERC20Permit("") {} function initialize(address _token0, address _token1, bool _stable) external { if (factory != address(0)) revert FactoryAlreadySet(); factory = _msgSender(); _voter = IPoolFactory(factory).voter(); (token0, token1, stable) = (_token0, _token1, _stable); poolFees = address(new PoolFees(_token0, _token1)); string memory symbol0 = ERC20(_token0).symbol(); string memory symbol1 = ERC20(_token1).symbol(); if (_stable) { _name = string(abi.encodePacked("StableV2 AMM - ", symbol0, "/", symbol1)); _symbol = string(abi.encodePacked("sAMMV2-", symbol0, "/", symbol1)); } else { _name = string(abi.encodePacked("VolatileV2 AMM - ", symbol0, "/", symbol1)); _symbol = string(abi.encodePacked("vAMMV2-", symbol0, "/", symbol1)); } decimals0 = 10 ** ERC20(_token0).decimals(); decimals1 = 10 ** ERC20(_token1).decimals(); observations.push(Observation(block.timestamp, 0, 0)); } function setName(string calldata __name) external { if (msg.sender != IVoter(_voter).emergencyCouncil()) revert NotEmergencyCouncil(); _name = __name; } function setSymbol(string calldata __symbol) external { if (msg.sender != IVoter(_voter).emergencyCouncil()) revert NotEmergencyCouncil(); _symbol = __symbol; } function observationLength() external view returns (uint256) { return observations.length; } function lastObservation() public view returns (Observation memory) { return observations[observations.length - 1]; } function metadata() external view returns (uint256 dec0, uint256 dec1, uint256 r0, uint256 r1, bool st, address t0, address t1) { return (decimals0, decimals1, reserve0, reserve1, stable, token0, token1); } function tokens() external view returns (address, address) { return (token0, token1); } // claim accumulated but unclaimed fees (viewable via claimable0 and claimable1) function claimFees() external returns (uint256 claimed0, uint256 claimed1) { address sender = _msgSender(); _updateFor(sender); claimed0 = claimable0[sender]; claimed1 = claimable1[sender]; if (claimed0 > 0 || claimed1 > 0) { claimable0[sender] = 0; claimable1[sender] = 0; PoolFees(poolFees).claimFeesFor(sender, claimed0, claimed1); emit Claim(sender, sender, claimed0, claimed1); } } // Accrue fees on token0 function _update0(uint256 amount) internal { // Only update on this pool if there is a fee if (amount == 0) return; IERC20(token0).safeTransfer(poolFees, amount); // transfer the fees out to PoolFees uint256 _ratio = (amount * 1e18) / totalSupply(); // 1e18 adjustment is removed during claim if (_ratio > 0) { index0 += _ratio; } emit Fees(_msgSender(), amount, 0); } // Accrue fees on token1 function _update1(uint256 amount) internal { // Only update on this pool if there is a fee if (amount == 0) return; IERC20(token1).safeTransfer(poolFees, amount); uint256 _ratio = (amount * 1e18) / totalSupply(); if (_ratio > 0) { index1 += _ratio; } emit Fees(_msgSender(), 0, amount); } // this function MUST be called on any balance changes, otherwise can be used to infinitely claim fees // Fees are segregated from core funds, so fees can never put liquidity at risk function _updateFor(address recipient) internal { uint256 _supplied = balanceOf(recipient); // get LP balance of `recipient` if (_supplied > 0) { uint256 _supplyIndex0 = supplyIndex0[recipient]; // get last adjusted index0 for recipient uint256 _supplyIndex1 = supplyIndex1[recipient]; uint256 _index0 = index0; // get global index0 for accumulated fees uint256 _index1 = index1; supplyIndex0[recipient] = _index0; // update user current position to global position supplyIndex1[recipient] = _index1; uint256 _delta0 = _index0 - _supplyIndex0; // see if there is any difference that need to be accrued uint256 _delta1 = _index1 - _supplyIndex1; if (_delta0 > 0) { uint256 _share = (_supplied * _delta0) / 1e18; // add accrued difference for each supplied token claimable0[recipient] += _share; } if (_delta1 > 0) { uint256 _share = (_supplied * _delta1) / 1e18; claimable1[recipient] += _share; } } else { supplyIndex0[recipient] = index0; // new users are set to the default global state supplyIndex1[recipient] = index1; } } function getReserves() public view returns (uint256 _reserve0, uint256 _reserve1, uint256 _blockTimestampLast) { _reserve0 = reserve0; _reserve1 = reserve1; _blockTimestampLast = blockTimestampLast; } // update reserves and, on the first call per block, price accumulators function _update(uint256 balance0, uint256 balance1, uint256 _reserve0, uint256 _reserve1) internal { uint256 blockTimestamp = block.timestamp; uint256 timeElapsed = blockTimestamp - blockTimestampLast; if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) { reserve0CumulativeLast += _reserve0 * timeElapsed; reserve1CumulativeLast += _reserve1 * timeElapsed; } Observation memory _point = lastObservation(); timeElapsed = blockTimestamp - _point.timestamp; // compare the last observation with current timestamp, if greater than 30 minutes, record a new event if (timeElapsed > periodSize) { observations.push(Observation(blockTimestamp, reserve0CumulativeLast, reserve1CumulativeLast)); } reserve0 = balance0; reserve1 = balance1; blockTimestampLast = blockTimestamp; emit Sync(reserve0, reserve1); } // produces the cumulative price using counterfactuals to save gas and avoid a call to sync. function currentCumulativePrices() public view returns (uint256 reserve0Cumulative, uint256 reserve1Cumulative, uint256 blockTimestamp) { blockTimestamp = block.timestamp; reserve0Cumulative = reserve0CumulativeLast; reserve1Cumulative = reserve1CumulativeLast; // if time has elapsed since the last update on the pool, mock the accumulated price values (uint256 _reserve0, uint256 _reserve1, uint256 _blockTimestampLast) = getReserves(); if (_blockTimestampLast != blockTimestamp) { // subtraction overflow is desired uint256 timeElapsed = blockTimestamp - _blockTimestampLast; reserve0Cumulative += _reserve0 * timeElapsed; reserve1Cumulative += _reserve1 * timeElapsed; } } // provides twap price with user configured granularity, up to the full window size function quote(address tokenIn, uint256 amountIn, uint256 granularity) external view returns (uint256 amountOut) { uint256[] memory _prices = sample(tokenIn, amountIn, granularity, 1); uint256 priceAverageCumulative; uint256 _length = _prices.length; for (uint256 i = 0; i < _length; i++) { priceAverageCumulative += _prices[i]; } return priceAverageCumulative / granularity; } // returns a memory set of twap prices function prices(address tokenIn, uint256 amountIn, uint256 points) external view returns (uint256[] memory) { return sample(tokenIn, amountIn, points, 1); } function sample( address tokenIn, uint256 amountIn, uint256 points, uint256 window ) public view returns (uint256[] memory) { uint256[] memory _prices = new uint256[](points); uint256 length = observations.length - 1; uint256 i = length - (points * window); uint256 nextIndex = 0; uint256 index = 0; for (; i < length; i += window) { nextIndex = i + window; uint256 timeElapsed = observations[nextIndex].timestamp - observations[i].timestamp; uint256 _reserve0 = (observations[nextIndex].reserve0Cumulative - observations[i].reserve0Cumulative) / timeElapsed; uint256 _reserve1 = (observations[nextIndex].reserve1Cumulative - observations[i].reserve1Cumulative) / timeElapsed; _prices[index] = _getAmountOut(amountIn, tokenIn, _reserve0, _reserve1); // index < length; length cannot overflow unchecked { index = index + 1; } } return _prices; } // this low-level function should be called by addLiquidity functions in Router.sol, which performs important safety checks // standard uniswap v2 implementation function mint(address to) external nonReentrant returns (uint256 liquidity) { (uint256 _reserve0, uint256 _reserve1) = (reserve0, reserve1); uint256 _balance0 = IERC20(token0).balanceOf(address(this)); uint256 _balance1 = IERC20(token1).balanceOf(address(this)); uint256 _amount0 = _balance0 - _reserve0; uint256 _amount1 = _balance1 - _reserve1; uint256 _totalSupply = totalSupply(); // gas savings, must be defined here since totalSupply can update in _mintFee if (_totalSupply == 0) { liquidity = Math.sqrt(_amount0 * _amount1) - MINIMUM_LIQUIDITY; _mint(address(1), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens - cannot be address(0) if (stable) { if ((_amount0 * 1e18) / decimals0 != (_amount1 * 1e18) / decimals1) revert DepositsNotEqual(); if (_k(_amount0, _amount1) <= MINIMUM_K) revert BelowMinimumK(); } } else { liquidity = Math.min((_amount0 * _totalSupply) / _reserve0, (_amount1 * _totalSupply) / _reserve1); } if (liquidity == 0) revert InsufficientLiquidityMinted(); _mint(to, liquidity); _update(_balance0, _balance1, _reserve0, _reserve1); emit Mint(_msgSender(), _amount0, _amount1); } // this low-level function should be called from a contract which performs important safety checks // standard uniswap v2 implementation function burn(address to) external nonReentrant returns (uint256 amount0, uint256 amount1) { (uint256 _reserve0, uint256 _reserve1) = (reserve0, reserve1); (address _token0, address _token1) = (token0, token1); uint256 _balance0 = IERC20(_token0).balanceOf(address(this)); uint256 _balance1 = IERC20(_token1).balanceOf(address(this)); uint256 _liquidity = balanceOf(address(this)); uint256 _totalSupply = totalSupply(); // gas savings, must be defined here since totalSupply can update in _mintFee amount0 = (_liquidity * _balance0) / _totalSupply; // using balances ensures pro-rata distribution amount1 = (_liquidity * _balance1) / _totalSupply; // using balances ensures pro-rata distribution if (amount0 == 0 || amount1 == 0) revert InsufficientLiquidityBurned(); _burn(address(this), _liquidity); IERC20(_token0).safeTransfer(to, amount0); IERC20(_token1).safeTransfer(to, amount1); _balance0 = IERC20(_token0).balanceOf(address(this)); _balance1 = IERC20(_token1).balanceOf(address(this)); _update(_balance0, _balance1, _reserve0, _reserve1); emit Burn(_msgSender(), to, amount0, amount1); } // this low-level function should be called from a contract which performs important safety checks function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external nonReentrant { if (IPoolFactory(factory).isPaused()) revert IsPaused(); if (amount0Out == 0 && amount1Out == 0) revert InsufficientOutputAmount(); (uint256 _reserve0, uint256 _reserve1) = (reserve0, reserve1); if (amount0Out >= _reserve0 || amount1Out >= _reserve1) revert InsufficientLiquidity(); uint256 _balance0; uint256 _balance1; { // scope for _token{0,1}, avoids stack too deep errors (address _token0, address _token1) = (token0, token1); if (to == _token0 || to == _token1) revert InvalidTo(); if (amount0Out > 0) IERC20(_token0).safeTransfer(to, amount0Out); // optimistically transfer tokens if (amount1Out > 0) IERC20(_token1).safeTransfer(to, amount1Out); // optimistically transfer tokens if (data.length > 0) IPoolCallee(to).hook(_msgSender(), amount0Out, amount1Out, data); // callback, used for flash loans _balance0 = IERC20(_token0).balanceOf(address(this)); _balance1 = IERC20(_token1).balanceOf(address(this)); } uint256 amount0In = _balance0 > _reserve0 - amount0Out ? _balance0 - (_reserve0 - amount0Out) : 0; uint256 amount1In = _balance1 > _reserve1 - amount1Out ? _balance1 - (_reserve1 - amount1Out) : 0; if (amount0In == 0 && amount1In == 0) revert InsufficientInputAmount(); { // scope for reserve{0,1}Adjusted, avoids stack too deep errors (address _token0, address _token1) = (token0, token1); if (amount0In > 0) _update0((amount0In * IPoolFactory(factory).getFee(address(this), stable)) / 10000); // accrue fees for token0 and move them out of pool if (amount1In > 0) _update1((amount1In * IPoolFactory(factory).getFee(address(this), stable)) / 10000); // accrue fees for token1 and move them out of pool _balance0 = IERC20(_token0).balanceOf(address(this)); // since we removed tokens, we need to reconfirm balances, can also simply use previous balance - amountIn/ 10000, but doing balanceOf again as safety check _balance1 = IERC20(_token1).balanceOf(address(this)); // The curve, either x3y+y3x for stable pools, or x*y for volatile pools if (_k(_balance0, _balance1) < _k(_reserve0, _reserve1)) revert K(); } _update(_balance0, _balance1, _reserve0, _reserve1); emit Swap(_msgSender(), to, amount0In, amount1In, amount0Out, amount1Out); } // force balances to match reserves function skim(address to) external nonReentrant { (address _token0, address _token1) = (token0, token1); IERC20(_token0).safeTransfer(to, IERC20(_token0).balanceOf(address(this)) - (reserve0)); IERC20(_token1).safeTransfer(to, IERC20(_token1).balanceOf(address(this)) - (reserve1)); } // force reserves to match balances function sync() external nonReentrant { _update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)), reserve0, reserve1); } function _f(uint256 x0, uint256 y) internal pure returns (uint256) { uint256 _a = (x0 * y) / 1e18; uint256 _b = ((x0 * x0) / 1e18 + (y * y) / 1e18); return (_a * _b) / 1e18; } function _d(uint256 x0, uint256 y) internal pure returns (uint256) { return (3 * x0 * ((y * y) / 1e18)) / 1e18 + ((((x0 * x0) / 1e18) * x0) / 1e18); } function _get_y(uint256 x0, uint256 xy, uint256 y) internal view returns (uint256) { for (uint256 i = 0; i < 255; i++) { uint256 k = _f(x0, y); if (k < xy) { // there are two cases where dy == 0 // case 1: The y is converged and we find the correct answer // case 2: _d(x0, y) is too large compare to (xy - k) and the rounding error // screwed us. // In this case, we need to increase y by 1 uint256 dy = ((xy - k) * 1e18) / _d(x0, y); if (dy == 0) { if (k == xy) { // We found the correct answer. Return y return y; } if (_k(x0, y + 1) > xy) { // If _k(x0, y + 1) > xy, then we are close to the correct answer. // There's no closer answer than y + 1 return y + 1; } dy = 1; } y = y + dy; } else { uint256 dy = ((k - xy) * 1e18) / _d(x0, y); if (dy == 0) { if (k == xy || _f(x0, y - 1) < xy) { // Likewise, if k == xy, we found the correct answer. // If _f(x0, y - 1) < xy, then we are close to the correct answer. // There's no closer answer than "y" // It's worth mentioning that we need to find y where f(x0, y) >= xy // As a result, we can't return y - 1 even it's closer to the correct answer return y; } dy = 1; } y = y - dy; } } revert("!y"); } function getAmountOut(uint256 amountIn, address tokenIn) external view returns (uint256) { (uint256 _reserve0, uint256 _reserve1) = (reserve0, reserve1); amountIn -= (amountIn * IPoolFactory(factory).getFee(address(this), stable)) / 10000; // remove fee from amount received return _getAmountOut(amountIn, tokenIn, _reserve0, _reserve1); } function _getAmountOut( uint256 amountIn, address tokenIn, uint256 _reserve0, uint256 _reserve1 ) internal view returns (uint256) { if (stable) { uint256 xy = _k(_reserve0, _reserve1); _reserve0 = (_reserve0 * 1e18) / decimals0; _reserve1 = (_reserve1 * 1e18) / decimals1; (uint256 reserveA, uint256 reserveB) = tokenIn == token0 ? (_reserve0, _reserve1) : (_reserve1, _reserve0); amountIn = tokenIn == token0 ? (amountIn * 1e18) / decimals0 : (amountIn * 1e18) / decimals1; uint256 y = reserveB - _get_y(amountIn + reserveA, xy, reserveB); return (y * (tokenIn == token0 ? decimals1 : decimals0)) / 1e18; } else { (uint256 reserveA, uint256 reserveB) = tokenIn == token0 ? (_reserve0, _reserve1) : (_reserve1, _reserve0); return (amountIn * reserveB) / (reserveA + amountIn); } } function _k(uint256 x, uint256 y) internal view returns (uint256) { if (stable) { uint256 _x = (x * 1e18) / decimals0; uint256 _y = (y * 1e18) / decimals1; uint256 _a = (_x * _y) / 1e18; uint256 _b = ((_x * _x) / 1e18 + (_y * _y) / 1e18); return (_a * _b) / 1e18; // x3y+y3x >= k } else { return x * y; // xy >= k } } /* @dev OZ inheritance overrides These are needed as _name and _symbol are set privately before logic is executed within the constructor to set _name and _symbol. */ function name() public view override returns (string memory) { return _name; } function symbol() public view override returns (string memory) { return _symbol; } function _beforeTokenTransfer(address from, address to, uint256) internal override { _updateFor(from); _updateFor(to); } }
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BelowMinimumK","type":"error"},{"inputs":[],"name":"DepositsNotEqual","type":"error"},{"inputs":[],"name":"FactoryAlreadySet","type":"error"},{"inputs":[],"name":"InsufficientInputAmount","type":"error"},{"inputs":[],"name":"InsufficientLiquidity","type":"error"},{"inputs":[],"name":"InsufficientLiquidityBurned","type":"error"},{"inputs":[],"name":"InsufficientLiquidityMinted","type":"error"},{"inputs":[],"name":"InsufficientOutputAmount","type":"error"},{"inputs":[],"name":"InvalidTo","type":"error"},{"inputs":[],"name":"IsPaused","type":"error"},{"inputs":[],"name":"K","type":"error"},{"inputs":[],"name":"NotEmergencyCouncil","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"Fees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0In","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1In","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount0Out","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1Out","type":"uint256"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reserve0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"reserve1","type":"uint256"}],"name":"Sync","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blockTimestampLast","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"burn","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimFees","outputs":[{"internalType":"uint256","name":"claimed0","type":"uint256"},{"internalType":"uint256","name":"claimed1","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimable0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimable1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentCumulativePrices","outputs":[{"internalType":"uint256","name":"reserve0Cumulative","type":"uint256"},{"internalType":"uint256","name":"reserve1Cumulative","type":"uint256"},{"internalType":"uint256","name":"blockTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address","name":"tokenIn","type":"address"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReserves","outputs":[{"internalType":"uint256","name":"_reserve0","type":"uint256"},{"internalType":"uint256","name":"_reserve1","type":"uint256"},{"internalType":"uint256","name":"_blockTimestampLast","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"index0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"index1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token0","type":"address"},{"internalType":"address","name":"_token1","type":"address"},{"internalType":"bool","name":"_stable","type":"bool"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastObservation","outputs":[{"components":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"reserve0Cumulative","type":"uint256"},{"internalType":"uint256","name":"reserve1Cumulative","type":"uint256"}],"internalType":"struct Pool.Observation","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"metadata","outputs":[{"internalType":"uint256","name":"dec0","type":"uint256"},{"internalType":"uint256","name":"dec1","type":"uint256"},{"internalType":"uint256","name":"r0","type":"uint256"},{"internalType":"uint256","name":"r1","type":"uint256"},{"internalType":"bool","name":"st","type":"bool"},{"internalType":"address","name":"t0","type":"address"},{"internalType":"address","name":"t1","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"observationLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"observations","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"reserve0Cumulative","type":"uint256"},{"internalType":"uint256","name":"reserve1Cumulative","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"poolFees","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"points","type":"uint256"}],"name":"prices","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"granularity","type":"uint256"}],"name":"quote","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reserve0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reserve0CumulativeLast","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reserve1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reserve1CumulativeLast","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"points","type":"uint256"},{"internalType":"uint256","name":"window","type":"uint256"}],"name":"sample","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"__name","type":"string"}],"name":"setName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"__symbol","type":"string"}],"name":"setSymbol","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"skim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"supplyIndex0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"supplyIndex1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount0Out","type":"uint256"},{"internalType":"uint256","name":"amount1Out","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"swap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sync","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token0","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokens","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
61016060405260006019556000601a553480156200001c57600080fd5b50604080516020808201835260008083528351808501855260018152603160f81b818401528451808401865282815285519384019095529082529192839291600362000069838262000269565b50600462000078828262000269565b506200008a915083905060056200013f565b60e0526200009a8160066200013f565b61010052815160208084019190912061012052815190820120610140524660a0526200012a6101205161014051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c052506001600955620003aa565b60006020835110156200015f57620001578362000178565b905062000172565b816200016c848262000269565b50600090505b92915050565b600080829050601f81511115620001af578260405163305a27a960e01b8152600401620001a6919062000335565b60405180910390fd5b8051620001bc8262000385565b179392505050565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620001ef57607f821691505b6020821081036200021057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200026457600081815260208120601f850160051c810160208610156200023f5750805b601f850160051c820191505b8181101562000260578281556001016200024b565b5050505b505050565b81516001600160401b03811115620002855762000285620001c4565b6200029d81620002968454620001da565b8462000216565b602080601f831160018114620002d55760008415620002bc5750858301515b600019600386901b1c1916600185901b17855562000260565b600085815260208120601f198616915b828110156200030657888601518255948401946001909101908401620002e5565b5085821015620003255787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208083528351808285015260005b81811015620003645785810183015185820160400152820162000346565b506000604082860101526040601f19601f8301168501019250505092915050565b80516020808301519190811015620002105760001960209190910360031b1b16919050565b60805160a05160c05160e0516101005161012051610140516151cf6200040560003960006131ff015260006131d7015260006115fe015260006115d10152600061312f0152600061315a0152600061318501526151cf6000f3fe60806040523480156200001157600080fd5b5060043610620003305760003560e01c806384b0196e11620001bf578063bf944dbc11620000fc578063d294f09311620000af578063e4bbb5a81162000086578063e4bbb5a814620007f0578063ebeb31db1462000807578063f140a35a1462000810578063fff6cae9146200082757600080fd5b8063d294f09314620007b8578063d505accf14620007c2578063dd62ed3e14620007d957600080fd5b8063bf944dbc146200075b578063c245febc1462000765578063c45a0155146200076f578063c47f00271462000783578063c5700a02146200079a578063d21220a714620007a457600080fd5b80639f767c881162000172578063a9059cbb1162000149578063a9059cbb146200070c578063b84c82461462000723578063bc25cf77146200073a578063bda39cad146200075157600080fd5b80639f767c8814620006af578063a1ac4d1314620006d2578063a457c2d714620006f557600080fd5b806384b0196e14620005ee57806389afcb44146200060d5780638a7b8cf2146200063a57806395d89b4114620006675780639d63848a14620006715780639e8cc04b146200069857600080fd5b8063313ce567116200028e578063443cb4bc11620002415780635a76f25e11620002185780635a76f25e146200058a5780636a627842146200059457806370a0823114620005ab5780637ecebe0014620005d757600080fd5b8063443cb4bc14620005465780634d5a9f8a14620005505780635881c475146200057357600080fd5b8063313ce567146200049457806332c0defd14620004a45780633358095914620004ae5780633644e51514620004c2578063392f37e914620004cc57806339509351146200052f57600080fd5b806318160ddd11620002e757806318160ddd14620004115780631df8c7171462000424578063205aabf1146200042e57806322be3de1146200045157806323b872dd1462000466578063252c09d7146200047d57600080fd5b8063022c0d9f146200033557806306fdde03146200034e5780630902f1ac1462000370578063095ea7b314620003965780630dfe168114620003be57806313345fe114620003eb575b600080fd5b6200034c62000346366004620040d9565b62000831565b005b6200035862000ebb565b6040516200036791906200419d565b60405180910390f35b6014546015546016545b6040805193845260208401929092529082015260600162000367565b620003ad620003a7366004620041b2565b62000f55565b604051901515815260200162000367565b600d54620003d2906001600160a01b031681565b6040516001600160a01b03909116815260200162000367565b62000402620003fc366004620041e1565b62000f71565b6040516200036791906200425c565b6002545b60405190815260200162000367565b6200037a6200119e565b620004156200043f36600462004271565b601c6020526000908152604090205481565b600c54620003ad90600160a01b900460ff1681565b620003ad6200047736600462004291565b62001219565b6200037a6200048e366004620042d7565b62001243565b6040516012815260200162000367565b6200041560195481565b600f54620003d2906001600160a01b031681565b6200041562001277565b601254601354601454601554600c54600d54600e54604080519788526020880196909652948601939093526060850191909152600160a01b900460ff16151560808401526001600160a01b0390811660a08401521660c082015260e00162000367565b620003ad62000540366004620041b2565b62001288565b6200041560145481565b620004156200056136600462004271565b601d6020526000908152604090205481565b6200040262000584366004620042f1565b620012b0565b6200041560155481565b62000415620005a536600462004271565b620012c1565b62000415620005bc36600462004271565b6001600160a01b031660009081526020819052604090205490565b62000415620005e836600462004271565b620015a3565b620005f8620015c2565b60405162000367979695949392919062004329565b620006246200061e36600462004271565b6200164f565b6040805192835260208301919091520162000367565b6200064462001945565b604080518251815260208084015190820152918101519082015260600162000367565b62000358620019cb565b600d54600e54604080516001600160a01b0393841681529290911660208301520162000367565b62000415620006a9366004620042f1565b620019dc565b62000415620006c036600462004271565b601b6020526000908152604090205481565b62000415620006e336600462004271565b601e6020526000908152604090205481565b620003ad62000706366004620041b2565b62001a5a565b620003ad6200071d366004620041b2565b62001aea565b6200034c620007343660046200439f565b62001afa565b6200034c6200074b36600462004271565b62001bba565b62000415601a5481565b6200041560175481565b6200041560185481565b601054620003d2906001600160a01b031681565b6200034c620007943660046200439f565b62001d07565b6200041560165481565b600e54620003d2906001600160a01b031681565b6200062462001dc2565b6200034c620007d3366004620043f5565b62001eed565b62000415620007ea3660046200446d565b6200205d565b6200034c62000801366004620044ba565b62002088565b60115462000415565b62000415620008213660046200450c565b62002536565b6200034c62002606565b6200083b6200270a565b601060009054906101000a90046001600160a01b03166001600160a01b031663b187bd266040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200088f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620008b5919062004534565b15620008d457604051631309a56360e01b815260040160405180910390fd5b84158015620008e1575083155b1562000900576040516342301c2360e01b815260040160405180910390fd5b6014546015548187101580620009165750808610155b15620009355760405163bb55fd2760e01b815260040160405180910390fd5b600d54600e5460009182916001600160a01b0391821691908116908916821480620009715750806001600160a01b0316896001600160a01b0316145b156200099057604051630521f43160e31b815260040160405180910390fd5b8a15620009ad57620009ad6001600160a01b0383168a8d62002765565b8915620009ca57620009ca6001600160a01b0382168a8c62002765565b861562000a3c57604051639a7bff7960e01b81526001600160a01b038a1690639a7bff799062000a079033908f908f908e908e9060040162004554565b600060405180830381600087803b15801562000a2257600080fd5b505af115801562000a37573d6000803e3d6000fd5b505050505b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa15801562000a81573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000aa79190620045a0565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a0823190602401602060405180830381865afa15801562000aef573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b159190620045a0565b925050506000898562000b299190620045d0565b831162000b3857600062000b50565b62000b448a86620045d0565b62000b509084620045d0565b9050600062000b608a86620045d0565b831162000b6f57600062000b87565b62000b7b8a86620045d0565b62000b879084620045d0565b90508115801562000b96575080155b1562000bb55760405163098fb56160e01b815260040160405180910390fd5b600d54600e546001600160a01b039182169116831562000c7a57601054600c5460405163cc56b2c560e01b8152306004820152600160a01b90910460ff161515602482015262000c7a91612710916001600160a01b039091169063cc56b2c590604401602060405180830381865afa15801562000c36573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000c5c9190620045a0565b62000c689087620045e6565b62000c74919062004616565b620027b9565b821562000d2c57601054600c5460405163cc56b2c560e01b8152306004820152600160a01b90910460ff161515602482015262000d2c91612710916001600160a01b039091169063cc56b2c590604401602060405180830381865afa15801562000ce8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d0e9190620045a0565b62000d1a9086620045e6565b62000d26919062004616565b62002873565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa15801562000d71573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d979190620045a0565b6040516370a0823160e01b81523060048201529096506001600160a01b038216906370a0823190602401602060405180830381865afa15801562000ddf573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e059190620045a0565b945062000e13888862002927565b62000e1f878762002927565b101562000e3f5760405163a932492f60e01b815260040160405180910390fd5b505062000e4f8484888862002a46565b60408051838152602081018390528082018d9052606081018c905290516001600160a01b038b169133917fb3e2773606abfd36b5bd91394b3a54d1398336c65005baf7bf7a05efeffaf75b9181900360800190a350505050505062000eb46001600955565b5050505050565b6060600a805462000ecc9062004639565b80601f016020809104026020016040519081016040528092919081815260200182805462000efa9062004639565b801562000f4b5780601f1062000f1f5761010080835404028352916020019162000f4b565b820191906000526020600020905b81548152906001019060200180831162000f2d57829003601f168201915b5050505050905090565b60003362000f6581858562002bec565b60019150505b92915050565b606060008367ffffffffffffffff81111562000f915762000f916200466f565b60405190808252806020026020018201604052801562000fbb578160200160208202803683370190505b5060115490915060009062000fd390600190620045d0565b9050600062000fe38587620045e6565b62000fef9083620045d0565b90506000805b838310156200118e576200100a878462004685565b91506000601184815481106200102457620010246200469b565b906000526020600020906003020160000154601184815481106200104c576200104c6200469b565b9060005260206000209060030201600001546200106a9190620045d0565b9050600081601186815481106200108557620010856200469b565b90600052602060002090600302016001015460118681548110620010ad57620010ad6200469b565b906000526020600020906003020160010154620010cb9190620045d0565b620010d7919062004616565b905060008260118781548110620010f257620010f26200469b565b906000526020600020906003020160020154601187815481106200111a576200111a6200469b565b906000526020600020906003020160020154620011389190620045d0565b62001144919062004616565b9050620011548c8e848462002d14565b8885815181106200116957620011696200469b565b602090810291909101015250505060010162001186878462004685565b925062000ff5565b509293505050505b949350505050565b6017546018544260008080620011bd6014546015546016549192909190565b92509250925083811462001211576000620011d98286620045d0565b9050620011e78185620045e6565b620011f3908862004685565b9650620012018184620045e6565b6200120d908762004685565b9550505b505050909192565b6000336200122985828562002ee9565b6200123685858562002f6a565b60019150505b9392505050565b601181815481106200125457600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b60006200128362003122565b905090565b60003362000f658185856200129e83836200205d565b620012aa919062004685565b62002bec565b606062001196848484600162000f71565b6000620012cd6200270a565b601454601554600d546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156200131d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620013439190620045a0565b600e546040516370a0823160e01b81523060048201529192506000916001600160a01b03909116906370a0823190602401602060405180830381865afa15801562001392573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620013b89190620045a0565b90506000620013c88584620045d0565b90506000620013d88584620045d0565b90506000620013e660025490565b905080600003620014d6576103e86200140a620014048486620045e6565b62003250565b620014169190620045d0565b97506200142760016103e862003355565b600c54600160a01b900460ff1615620014d0576013546200145183670de0b6b3a7640000620045e6565b6200145d919062004616565b6012546200147485670de0b6b3a7640000620045e6565b62001480919062004616565b146200149f576040516305026bfd60e11b815260040160405180910390fd5b6402540be400620014b1848462002927565b11620014d0576040516321c69d6f60e11b815260040160405180910390fd5b62001515565b6200151287620014e78386620045e6565b620014f3919062004616565b87620015008486620045e6565b6200150c919062004616565b62003426565b97505b876000036200153757604051633489be7560e21b815260040160405180910390fd5b62001543898962003355565b620015518585898962002a46565b604080518481526020810184905233917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a2505050505050506200159e6001600955565b919050565b6001600160a01b03811660009081526007602052604081205462000f6b565b600060608082808083620015f87f000000000000000000000000000000000000000000000000000000000000000060056200343e565b620016257f000000000000000000000000000000000000000000000000000000000000000060066200343e565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b6000806200165c6200270a565b601454601554600d54600e546040516370a0823160e01b81523060048201526001600160a01b03928316929091169060009083906370a0823190602401602060405180830381865afa158015620016b7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620016dd9190620045a0565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a0823190602401602060405180830381865afa15801562001728573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200174e9190620045a0565b306000908152602081905260409020546002549192509080620017728584620045e6565b6200177e919062004616565b9950806200178d8484620045e6565b62001799919062004616565b9850891580620017a7575088155b15620017c65760405163749383ad60e01b815260040160405180910390fd5b620017d23083620034ef565b620017e86001600160a01b0387168c8c62002765565b620017fe6001600160a01b0386168c8b62002765565b6040516370a0823160e01b81523060048201526001600160a01b038716906370a0823190602401602060405180830381865afa15801562001843573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018699190620045a0565b6040516370a0823160e01b81523060048201529094506001600160a01b038616906370a0823190602401602060405180830381865afa158015620018b1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018d79190620045a0565b9250620018e784848a8a62002a46565b604080518b8152602081018b90526001600160a01b038d169133917f5d624aa9c148153ab3446c1b154f660ee7701e549fe9b62dab7171b1c80e6fa2910160405180910390a35050505050505050620019406001600955565b915091565b6200196a60405180606001604052806000815260200160008152602001600081525090565b601180546200197c90600190620045d0565b815481106200198f576200198f6200469b565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905090565b6060600b805462000ecc9062004639565b600080620019ee858585600162000f71565b8051909150600090815b8181101562001a425783818151811062001a165762001a166200469b565b60200260200101518362001a2b919062004685565b92508062001a3981620046b1565b915050620019f8565b5062001a4f858362004616565b979650505050505050565b6000338162001a6a82866200205d565b90508381101562001ad05760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084015b60405180910390fd5b62001adf828686840362002bec565b506001949350505050565b60003362000f6581858562002f6a565b600c60009054906101000a90046001600160a01b03166001600160a01b0316637778960e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001b4e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001b749190620046cd565b6001600160a01b0316336001600160a01b03161462001ba65760405163c560129360e01b815260040160405180910390fd5b600b62001bb58284836200473f565b505050565b62001bc46200270a565b600d54600e546014546040516370a0823160e01b81523060048201526001600160a01b03938416939092169162001c6491859185906370a0823190602401602060405180830381865afa15801562001c20573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001c469190620045a0565b62001c529190620045d0565b6001600160a01b038516919062002765565b6015546040516370a0823160e01b815230600482015262001cf79185916001600160a01b038516906370a0823190602401602060405180830381865afa15801562001cb3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001cd99190620045a0565b62001ce59190620045d0565b6001600160a01b038416919062002765565b505062001d046001600955565b50565b600c60009054906101000a90046001600160a01b03166001600160a01b0316637778960e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001d5b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001d819190620046cd565b6001600160a01b0316336001600160a01b03161462001db35760405163c560129360e01b815260040160405180910390fd5b600a62001bb58284836200473f565b6000803362001dd18162003633565b6001600160a01b0381166000908152601d6020908152604080832054601e9092529091205490935091508215158062001e0a5750600082115b1562001ee8576001600160a01b038181166000818152601d60209081526040808320839055601e90915280822091909155600f54905163299e7ae760e11b8152600481019290925260248201869052604482018590529091169063533cf5ce90606401600060405180830381600087803b15801562001e8857600080fd5b505af115801562001e9d573d6000803e3d6000fd5b505060408051868152602081018690526001600160a01b03851693508392507f865ca08d59f5cb456e85cd2f7ef63664ea4f73327414e9d8152c4158b0e94645910160405180910390a35b509091565b8342111562001f3f5760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e65000000604482015260640162001ac7565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c988888862001f708c620037a6565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600062001fcd82620037ce565b9050600062001fdf82878787620037fe565b9050896001600160a01b0316816001600160a01b031614620020445760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e61747572650000604482015260640162001ac7565b620020518a8a8a62002bec565b50505050505050505050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6010546001600160a01b031615620020b3576040516302a98a3760e31b815260040160405180910390fd5b601080546001600160a01b03191633908117909155604080516311b25aab60e21b815290516346c96aac916004808201926020929091908290030181865afa15801562002104573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200212a9190620046cd565b600c80546001600160a01b039283166001600160a81b031990911617600160a01b84151502179055600e80546001600160a01b031990811685841617909155600d8054909116918516919091179055604051839083906200218b9062004069565b6001600160a01b03928316815291166020820152604001604051809103906000f080158015620021bf573d6000803e3d6000fd5b50600f60006101000a8154816001600160a01b0302191690836001600160a01b031602179055506000836001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562002227573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200225191908101906200480c565b90506000836001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562002294573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620022be91908101906200480c565b9050821562002337578181604051602001620022dc929190620048ba565b604051602081830303815290604052600a9081620022fb919062004915565b50818160405160200162002311929190620049e2565b604051602081830303815290604052600b908162002330919062004915565b50620023a2565b81816040516020016200234c92919062004a35565b604051602081830303815290604052600a90816200236b919062004915565b5081816040516020016200238192919062004a92565b604051602081830303815290604052600b9081620023a0919062004915565b505b846001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620023e1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002407919062004ab6565b6200241490600a62004bd3565b601281905550836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562002459573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200247f919062004ab6565b6200248c90600a62004bd3565b60135550506040805160608101825242815260006020820181815292820181815260118054600181018255925291517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6860039092029182015591517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c69830155517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6a90910155505050565b601454601554601054600c5460405163cc56b2c560e01b8152306004820152600160a01b90910460ff16151560248201526000939291612710916001600160a01b039091169063cc56b2c590604401602060405180830381865afa158015620025a3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620025c99190620045a0565b620025d59087620045e6565b620025e1919062004616565b620025ed9086620045d0565b9450620025fd8585848462002d14565b95945050505050565b620026106200270a565b600d546040516370a0823160e01b8152306004820152620026fd916001600160a01b0316906370a0823190602401602060405180830381865afa1580156200265c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620026829190620045a0565b600e546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015620026cb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620026f19190620045a0565b60145460155462002a46565b620027086001600955565b565b6002600954036200275e5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640162001ac7565b6002600955565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905262001bb59084906200382a565b80600003620027c55750565b600f54600d54620027e4916001600160a01b0391821691168362002765565b6000620027f060025490565b6200280483670de0b6b3a7640000620045e6565b62002810919062004616565b90508015620028335780601960008282546200282d919062004685565b90915550505b604080518381526000602082015233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291015b60405180910390a25050565b806000036200287f5750565b600f54600e546200289e916001600160a01b0391821691168362002765565b6000620028aa60025490565b620028be83670de0b6b3a7640000620045e6565b620028ca919062004616565b90508015620028ed5780601a6000828254620028e7919062004685565b90915550505b60408051600081526020810184905233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a8602910162002867565b600c54600090600160a01b900460ff161562002a32576012546000906200295785670de0b6b3a7640000620045e6565b62002963919062004616565b9050600060135484670de0b6b3a7640000620029809190620045e6565b6200298c919062004616565b90506000670de0b6b3a7640000620029a58385620045e6565b620029b1919062004616565b90506000670de0b6b3a7640000620029ca8480620045e6565b620029d6919062004616565b670de0b6b3a7640000620029eb8680620045e6565b620029f7919062004616565b62002a03919062004685565b9050670de0b6b3a764000062002a1a8284620045e6565b62002a26919062004616565b94505050505062000f6b565b62002a3e8284620045e6565b905062000f6b565b601654429060009062002a5a9083620045d0565b905060008111801562002a6c57508315155b801562002a7857508215155b1562002ac85762002a8a8185620045e6565b6017600082825462002a9d919062004685565b9091555062002aaf90508184620045e6565b6018600082825462002ac2919062004685565b90915550505b600062002ad462001945565b805190915062002ae59084620045d0565b915061070882111562002b9b5760408051606081018252848152601754602082019081526018549282019283526011805460018101825560009190915291517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c68600390930292830155517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6982015590517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6a909101555b60148790556015869055601683905560408051888152602081018890527fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a150505050505050565b6001600160a01b03831662002c505760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840162001ac7565b6001600160a01b03821662002cb35760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840162001ac7565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b600c54600090600160a01b900460ff161562002e9057600062002d38848462002927565b60125490915062002d5285670de0b6b3a7640000620045e6565b62002d5e919062004616565b60135490945062002d7884670de0b6b3a7640000620045e6565b62002d84919062004616565b600d5490935060009081906001600160a01b0388811691161462002daa57848662002dad565b85855b600d5491935091506001600160a01b0388811691161462002df15760135462002ddf89670de0b6b3a7640000620045e6565b62002deb919062004616565b62002e14565b60125462002e0889670de0b6b3a7640000620045e6565b62002e14919062004616565b9750600062002e3062002e28848b62004685565b858462003903565b62002e3c9083620045d0565b600d54909150670de0b6b3a7640000906001600160a01b038a811691161462002e685760125462002e6c565b6013545b62002e789083620045e6565b62002e84919062004616565b94505050505062001196565b600d5460009081906001600160a01b0387811691161462002eb357838562002eb6565b84845b909250905062002ec7878362004685565b62002ed38289620045e6565b62002edf919062004616565b9250505062001196565b600062002ef784846200205d565b9050600019811462002f64578181101562002f555760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640162001ac7565b62002f64848484840362002bec565b50505050565b6001600160a01b03831662002fd05760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840162001ac7565b6001600160a01b038216620030345760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840162001ac7565b6200304183838362003aa9565b6001600160a01b03831660009081526020819052604090205481811015620030bb5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840162001ac7565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a362002f64565b6000306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161480156200317c57507f000000000000000000000000000000000000000000000000000000000000000046145b15620031a757507f000000000000000000000000000000000000000000000000000000000000000090565b62001283604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b6000816000036200326357506000919050565b60006001620032728462003abf565b901c6001901b905060018184816200328e576200328e62004600565b048201901c90506001818481620032a957620032a962004600565b048201901c90506001818481620032c457620032c462004600565b048201901c90506001818481620032df57620032df62004600565b048201901c90506001818481620032fa57620032fa62004600565b048201901c9050600181848162003315576200331562004600565b048201901c9050600181848162003330576200333062004600565b048201901c90506200123c818285816200334e576200334e62004600565b0462003426565b6001600160a01b038216620033ad5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640162001ac7565b620033bb6000838362003aa9565b8060026000828254620033cf919062004685565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b60008183106200343757816200123c565b5090919050565b606060ff831615620034555762002a3e8362003b5b565b818054620034639062004639565b80601f0160208091040260200160405190810160405280929190818152602001828054620034919062004639565b8015620034e25780601f10620034b657610100808354040283529160200191620034e2565b820191906000526020600020905b815481529060010190602001808311620034c457829003601f168201915b5050505050905062000f6b565b6001600160a01b038216620035515760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840162001ac7565b6200355f8260008362003aa9565b6001600160a01b03821660009081526020819052604090205481811015620035d55760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840162001ac7565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6001600160a01b038116600090815260208190526040902054801562003774576001600160a01b0382166000908152601b602090815260408083208054601c8085529285208054601954601a54948190559490955282905593620036988584620045d0565b90506000620036a88584620045d0565b905081156200370a576000670de0b6b3a7640000620036c8848a620045e6565b620036d4919062004616565b6001600160a01b038a166000908152601d60205260408120805492935083929091906200370390849062004685565b9091555050505b80156200376a576000670de0b6b3a764000062003728838a620045e6565b62003734919062004616565b6001600160a01b038a166000908152601e60205260408120805492935083929091906200376390849062004685565b9091555050505b5050505050505050565b6019546001600160a01b0383166000908152601b6020908152604080832093909355601a54601c909152919020555050565b6001600160a01b03811660009081526007602052604090208054600181018255905b50919050565b600062000f6b620037de62003122565b8360405161190160f01b8152600281019290925260228201526042902090565b6000806000620038118787878762003b90565b91509150620038208162003c59565b5095945050505050565b600062003881826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031662003db69092919063ffffffff16565b80519091501562001bb55780806020019051810190620038a2919062004534565b62001bb55760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162001ac7565b6000805b60ff81101562003a7a5760006200391f868562003dc7565b905084811015620039d457600062003938878662003e60565b620039448388620045d0565b6200395890670de0b6b3a7640000620045e6565b62003964919062004616565b905080600003620039bf5785820362003983578493505050506200123c565b856200399c886200399688600162004685565b62002927565b1115620039bb57620039b085600162004685565b93505050506200123c565b5060015b620039cb818662004685565b94505062003a64565b6000620039e2878662003e60565b620039ee8784620045d0565b62003a0290670de0b6b3a7640000620045e6565b62003a0e919062004616565b90508060000362003a54578582148062003a3e57508562003a3c8862003a36600189620045d0565b62003dc7565b105b1562003a50578493505050506200123c565b5060015b62003a608186620045d0565b9450505b508062003a7181620046b1565b91505062003907565b5060405162461bcd60e51b8152602060048201526002602482015261217960f01b604482015260640162001ac7565b62003ab48362003633565b62001bb58262003633565b600080608083901c1562003ad557608092831c92015b604083901c1562003ae857604092831c92015b602083901c1562003afb57602092831c92015b601083901c1562003b0e57601092831c92015b600883901c1562003b2157600892831c92015b600483901c1562003b3457600492831c92015b600283901c1562003b4757600292831c92015b600183901c1562000f6b5760010192915050565b60408051602080825281830190925260609160ff84169160009180820181803683375050509182525060208101929092525090565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111562003bc9575060009050600362003c50565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801562003c1e573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811662003c495760006001925092505062003c50565b9150600090505b94509492505050565b600081600481111562003c705762003c7062004be4565b0362003c795750565b600181600481111562003c905762003c9062004be4565b0362003cdf5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640162001ac7565b600281600481111562003cf65762003cf662004be4565b0362003d455760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640162001ac7565b600381600481111562003d5c5762003d5c62004be4565b0362001d045760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840162001ac7565b606062001196848460008562003ef0565b600080670de0b6b3a764000062003ddf8486620045e6565b62003deb919062004616565b90506000670de0b6b3a764000062003e048580620045e6565b62003e10919062004616565b670de0b6b3a764000062003e258780620045e6565b62003e31919062004616565b62003e3d919062004685565b9050670de0b6b3a764000062003e548284620045e6565b620025fd919062004616565b6000670de0b6b3a7640000838162003e798280620045e6565b62003e85919062004616565b62003e919190620045e6565b62003e9d919062004616565b670de0b6b3a76400008062003eb38580620045e6565b62003ebf919062004616565b62003ecc866003620045e6565b62003ed89190620045e6565b62003ee4919062004616565b6200123c919062004685565b60608247101562003f535760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162001ac7565b600080866001600160a01b0316858760405162003f71919062004bfa565b60006040518083038185875af1925050503d806000811462003fb0576040519150601f19603f3d011682016040523d82523d6000602084013e62003fb5565b606091505b509150915062001a4f8783838760608315620040365782516000036200402e576001600160a01b0385163b6200402e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162001ac7565b508162001196565b6200119683838151156200404d5781518083602001fd5b8060405162461bcd60e51b815260040162001ac791906200419d565b6105818062004c1983390190565b6001600160a01b038116811462001d0457600080fd5b60008083601f840112620040a057600080fd5b50813567ffffffffffffffff811115620040b957600080fd5b602083019150836020828501011115620040d257600080fd5b9250929050565b600080600080600060808688031215620040f257600080fd5b853594506020860135935060408601356200410d8162004077565b9250606086013567ffffffffffffffff8111156200412a57600080fd5b62004138888289016200408d565b969995985093965092949392505050565b60005b83811015620041665781810151838201526020016200414c565b50506000910152565b600081518084526200418981602086016020860162004149565b601f01601f19169290920160200192915050565b6020815260006200123c60208301846200416f565b60008060408385031215620041c657600080fd5b8235620041d38162004077565b946020939093013593505050565b60008060008060808587031215620041f857600080fd5b8435620042058162004077565b966020860135965060408601359560600135945092505050565b600081518084526020808501945080840160005b83811015620042515781518752958201959082019060010162004233565b509495945050505050565b6020815260006200123c60208301846200421f565b6000602082840312156200428457600080fd5b81356200123c8162004077565b600080600060608486031215620042a757600080fd5b8335620042b48162004077565b92506020840135620042c68162004077565b929592945050506040919091013590565b600060208284031215620042ea57600080fd5b5035919050565b6000806000606084860312156200430757600080fd5b8335620043148162004077565b95602085013595506040909401359392505050565b60ff60f81b8816815260e0602082015260006200434a60e08301896200416f565b82810360408401526200435e81896200416f565b606084018890526001600160a01b038716608085015260a0840186905283810360c085015290506200439181856200421f565b9a9950505050505050505050565b60008060208385031215620043b357600080fd5b823567ffffffffffffffff811115620043cb57600080fd5b620043d9858286016200408d565b90969095509350505050565b60ff8116811462001d0457600080fd5b600080600080600080600060e0888a0312156200441157600080fd5b87356200441e8162004077565b96506020880135620044308162004077565b9550604088013594506060880135935060808801356200445081620043e5565b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156200448157600080fd5b82356200448e8162004077565b91506020830135620044a08162004077565b809150509250929050565b801515811462001d0457600080fd5b600080600060608486031215620044d057600080fd5b8335620044dd8162004077565b92506020840135620044ef8162004077565b915060408401356200450181620044ab565b809150509250925092565b600080604083850312156200452057600080fd5b823591506020830135620044a08162004077565b6000602082840312156200454757600080fd5b81516200123c81620044ab565b60018060a01b038616815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b600060208284031215620045b357600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8181038181111562000f6b5762000f6b620045ba565b808202811582820484141762000f6b5762000f6b620045ba565b634e487b7160e01b600052601260045260246000fd5b6000826200463457634e487b7160e01b600052601260045260246000fd5b500490565b600181811c908216806200464e57607f821691505b602082108103620037c857634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b8082018082111562000f6b5762000f6b620045ba565b634e487b7160e01b600052603260045260246000fd5b600060018201620046c657620046c6620045ba565b5060010190565b600060208284031215620046e057600080fd5b81516200123c8162004077565b601f82111562001bb557600081815260208120601f850160051c81016020861015620047165750805b601f850160051c820191505b81811015620047375782815560010162004722565b505050505050565b67ffffffffffffffff8311156200475a576200475a6200466f565b62004772836200476b835462004639565b83620046ed565b6000601f841160018114620047a95760008515620047905750838201355b600019600387901b1c1916600186901b17835562000eb4565b600083815260209020601f19861690835b82811015620047dc5786850135825560209485019460019092019101620047ba565b5086821015620047fa5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b6000602082840312156200481f57600080fd5b815167ffffffffffffffff808211156200483857600080fd5b818401915084601f8301126200484d57600080fd5b8151818111156200486257620048626200466f565b604051601f8201601f19908116603f011681019083821181831017156200488d576200488d6200466f565b81604052828152876020848701011115620048a757600080fd5b62001a4f83602083016020880162004149565b6e029ba30b13632ab191020a6a690169608d1b815260008351620048e681600f85016020880162004149565b602f60f81b600f9184019182015283516200490981601084016020880162004149565b01601001949350505050565b815167ffffffffffffffff8111156200493257620049326200466f565b6200494a8162004943845462004639565b84620046ed565b602080601f831160018114620049825760008415620049695750858301515b600019600386901b1c1916600185901b17855562004737565b600085815260208120601f198616915b82811015620049b35788860151825594840194600190910190840162004992565b5085821015620049d25787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6673414d4d56322d60c81b81526000835162004a0681600785016020880162004149565b602f60f81b600791840191820152835162004a2981600884016020880162004149565b01600801949350505050565b7002b37b630ba34b632ab191020a6a690169607d1b81526000835162004a6381601185016020880162004149565b602f60f81b601191840191820152835162004a8681601284016020880162004149565b01601201949350505050565b6676414d4d56322d60c81b81526000835162004a0681600785016020880162004149565b60006020828403121562004ac957600080fd5b81516200123c81620043e5565b600181815b8085111562004b1757816000190482111562004afb5762004afb620045ba565b8085161562004b0957918102915b93841c939080029062004adb565b509250929050565b60008262004b305750600162000f6b565b8162004b3f5750600062000f6b565b816001811462004b58576002811462004b635762004b83565b600191505062000f6b565b60ff84111562004b775762004b77620045ba565b50506001821b62000f6b565b5060208310610133831016604e8410600b841016171562004ba8575081810a62000f6b565b62004bb4838362004ad6565b806000190482111562004bcb5762004bcb620045ba565b029392505050565b60006200123c60ff84168362004b1f565b634e487b7160e01b600052602160045260246000fd5b6000825162004c0e81846020870162004149565b919091019291505056fe60e060405234801561001057600080fd5b5060405161058138038061058183398101604081905261002f91610066565b336080526001600160a01b0391821660a0521660c052610099565b80516001600160a01b038116811461006157600080fd5b919050565b6000806040838503121561007957600080fd5b6100828361004a565b91506100906020840161004a565b90509250929050565b60805160a05160c0516104bc6100c5600039600060db0152600060a101526000605001526104bc6000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063533cf5ce14610030575b600080fd5b61004361003e3660046103a9565b610045565b005b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461008e57604051636f61f64160e01b815260040160405180910390fd5b81156100c8576100c86001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168484610107565b8015610102576101026001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168483610107565b505050565b604080516001600160a01b03848116602483015260448083018590528351808403909101815260649092018352602080830180516001600160e01b031663a9059cbb60e01b17905283518085019094528084527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649084015261010292869291600091610197918516908490610219565b80519091501561010257808060200190518101906101b591906103ea565b6101025760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084015b60405180910390fd5b60606102288484600085610230565b949350505050565b6060824710156102915760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610210565b600080866001600160a01b031685876040516102ad9190610437565b60006040518083038185875af1925050503d80600081146102ea576040519150601f19603f3d011682016040523d82523d6000602084013e6102ef565b606091505b50915091506103008783838761030b565b979650505050505050565b6060831561037a578251600003610373576001600160a01b0385163b6103735760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610210565b5081610228565b610228838381511561038f5781518083602001fd5b8060405162461bcd60e51b81526004016102109190610453565b6000806000606084860312156103be57600080fd5b83356001600160a01b03811681146103d557600080fd5b95602085013595506040909401359392505050565b6000602082840312156103fc57600080fd5b8151801515811461040c57600080fd5b9392505050565b60005b8381101561042e578181015183820152602001610416565b50506000910152565b60008251610449818460208701610413565b9190910192915050565b6020815260008251806020840152610472816040850160208701610413565b601f01601f1916919091016040019291505056fea26469706673582212205e5499e3f9c7a0a696d53c6d17a2dd592efb80bae3e5401fbc29f58ac6d664ec64736f6c63430008130033a26469706673582212202b2b184adb2e50f82565b7eb0000c83c47c4b055a844d7c7c95c40853f0651ae64736f6c63430008130033
Deployed Bytecode
0x60806040523480156200001157600080fd5b5060043610620003305760003560e01c806384b0196e11620001bf578063bf944dbc11620000fc578063d294f09311620000af578063e4bbb5a81162000086578063e4bbb5a814620007f0578063ebeb31db1462000807578063f140a35a1462000810578063fff6cae9146200082757600080fd5b8063d294f09314620007b8578063d505accf14620007c2578063dd62ed3e14620007d957600080fd5b8063bf944dbc146200075b578063c245febc1462000765578063c45a0155146200076f578063c47f00271462000783578063c5700a02146200079a578063d21220a714620007a457600080fd5b80639f767c881162000172578063a9059cbb1162000149578063a9059cbb146200070c578063b84c82461462000723578063bc25cf77146200073a578063bda39cad146200075157600080fd5b80639f767c8814620006af578063a1ac4d1314620006d2578063a457c2d714620006f557600080fd5b806384b0196e14620005ee57806389afcb44146200060d5780638a7b8cf2146200063a57806395d89b4114620006675780639d63848a14620006715780639e8cc04b146200069857600080fd5b8063313ce567116200028e578063443cb4bc11620002415780635a76f25e11620002185780635a76f25e146200058a5780636a627842146200059457806370a0823114620005ab5780637ecebe0014620005d757600080fd5b8063443cb4bc14620005465780634d5a9f8a14620005505780635881c475146200057357600080fd5b8063313ce567146200049457806332c0defd14620004a45780633358095914620004ae5780633644e51514620004c2578063392f37e914620004cc57806339509351146200052f57600080fd5b806318160ddd11620002e757806318160ddd14620004115780631df8c7171462000424578063205aabf1146200042e57806322be3de1146200045157806323b872dd1462000466578063252c09d7146200047d57600080fd5b8063022c0d9f146200033557806306fdde03146200034e5780630902f1ac1462000370578063095ea7b314620003965780630dfe168114620003be57806313345fe114620003eb575b600080fd5b6200034c62000346366004620040d9565b62000831565b005b6200035862000ebb565b6040516200036791906200419d565b60405180910390f35b6014546015546016545b6040805193845260208401929092529082015260600162000367565b620003ad620003a7366004620041b2565b62000f55565b604051901515815260200162000367565b600d54620003d2906001600160a01b031681565b6040516001600160a01b03909116815260200162000367565b62000402620003fc366004620041e1565b62000f71565b6040516200036791906200425c565b6002545b60405190815260200162000367565b6200037a6200119e565b620004156200043f36600462004271565b601c6020526000908152604090205481565b600c54620003ad90600160a01b900460ff1681565b620003ad6200047736600462004291565b62001219565b6200037a6200048e366004620042d7565b62001243565b6040516012815260200162000367565b6200041560195481565b600f54620003d2906001600160a01b031681565b6200041562001277565b601254601354601454601554600c54600d54600e54604080519788526020880196909652948601939093526060850191909152600160a01b900460ff16151560808401526001600160a01b0390811660a08401521660c082015260e00162000367565b620003ad62000540366004620041b2565b62001288565b6200041560145481565b620004156200056136600462004271565b601d6020526000908152604090205481565b6200040262000584366004620042f1565b620012b0565b6200041560155481565b62000415620005a536600462004271565b620012c1565b62000415620005bc36600462004271565b6001600160a01b031660009081526020819052604090205490565b62000415620005e836600462004271565b620015a3565b620005f8620015c2565b60405162000367979695949392919062004329565b620006246200061e36600462004271565b6200164f565b6040805192835260208301919091520162000367565b6200064462001945565b604080518251815260208084015190820152918101519082015260600162000367565b62000358620019cb565b600d54600e54604080516001600160a01b0393841681529290911660208301520162000367565b62000415620006a9366004620042f1565b620019dc565b62000415620006c036600462004271565b601b6020526000908152604090205481565b62000415620006e336600462004271565b601e6020526000908152604090205481565b620003ad62000706366004620041b2565b62001a5a565b620003ad6200071d366004620041b2565b62001aea565b6200034c620007343660046200439f565b62001afa565b6200034c6200074b36600462004271565b62001bba565b62000415601a5481565b6200041560175481565b6200041560185481565b601054620003d2906001600160a01b031681565b6200034c620007943660046200439f565b62001d07565b6200041560165481565b600e54620003d2906001600160a01b031681565b6200062462001dc2565b6200034c620007d3366004620043f5565b62001eed565b62000415620007ea3660046200446d565b6200205d565b6200034c62000801366004620044ba565b62002088565b60115462000415565b62000415620008213660046200450c565b62002536565b6200034c62002606565b6200083b6200270a565b601060009054906101000a90046001600160a01b03166001600160a01b031663b187bd266040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200088f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620008b5919062004534565b15620008d457604051631309a56360e01b815260040160405180910390fd5b84158015620008e1575083155b1562000900576040516342301c2360e01b815260040160405180910390fd5b6014546015548187101580620009165750808610155b15620009355760405163bb55fd2760e01b815260040160405180910390fd5b600d54600e5460009182916001600160a01b0391821691908116908916821480620009715750806001600160a01b0316896001600160a01b0316145b156200099057604051630521f43160e31b815260040160405180910390fd5b8a15620009ad57620009ad6001600160a01b0383168a8d62002765565b8915620009ca57620009ca6001600160a01b0382168a8c62002765565b861562000a3c57604051639a7bff7960e01b81526001600160a01b038a1690639a7bff799062000a079033908f908f908e908e9060040162004554565b600060405180830381600087803b15801562000a2257600080fd5b505af115801562000a37573d6000803e3d6000fd5b505050505b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa15801562000a81573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000aa79190620045a0565b6040516370a0823160e01b81523060048201529094506001600160a01b038216906370a0823190602401602060405180830381865afa15801562000aef573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b159190620045a0565b925050506000898562000b299190620045d0565b831162000b3857600062000b50565b62000b448a86620045d0565b62000b509084620045d0565b9050600062000b608a86620045d0565b831162000b6f57600062000b87565b62000b7b8a86620045d0565b62000b879084620045d0565b90508115801562000b96575080155b1562000bb55760405163098fb56160e01b815260040160405180910390fd5b600d54600e546001600160a01b039182169116831562000c7a57601054600c5460405163cc56b2c560e01b8152306004820152600160a01b90910460ff161515602482015262000c7a91612710916001600160a01b039091169063cc56b2c590604401602060405180830381865afa15801562000c36573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000c5c9190620045a0565b62000c689087620045e6565b62000c74919062004616565b620027b9565b821562000d2c57601054600c5460405163cc56b2c560e01b8152306004820152600160a01b90910460ff161515602482015262000d2c91612710916001600160a01b039091169063cc56b2c590604401602060405180830381865afa15801562000ce8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d0e9190620045a0565b62000d1a9086620045e6565b62000d26919062004616565b62002873565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa15801562000d71573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d979190620045a0565b6040516370a0823160e01b81523060048201529096506001600160a01b038216906370a0823190602401602060405180830381865afa15801562000ddf573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e059190620045a0565b945062000e13888862002927565b62000e1f878762002927565b101562000e3f5760405163a932492f60e01b815260040160405180910390fd5b505062000e4f8484888862002a46565b60408051838152602081018390528082018d9052606081018c905290516001600160a01b038b169133917fb3e2773606abfd36b5bd91394b3a54d1398336c65005baf7bf7a05efeffaf75b9181900360800190a350505050505062000eb46001600955565b5050505050565b6060600a805462000ecc9062004639565b80601f016020809104026020016040519081016040528092919081815260200182805462000efa9062004639565b801562000f4b5780601f1062000f1f5761010080835404028352916020019162000f4b565b820191906000526020600020905b81548152906001019060200180831162000f2d57829003601f168201915b5050505050905090565b60003362000f6581858562002bec565b60019150505b92915050565b606060008367ffffffffffffffff81111562000f915762000f916200466f565b60405190808252806020026020018201604052801562000fbb578160200160208202803683370190505b5060115490915060009062000fd390600190620045d0565b9050600062000fe38587620045e6565b62000fef9083620045d0565b90506000805b838310156200118e576200100a878462004685565b91506000601184815481106200102457620010246200469b565b906000526020600020906003020160000154601184815481106200104c576200104c6200469b565b9060005260206000209060030201600001546200106a9190620045d0565b9050600081601186815481106200108557620010856200469b565b90600052602060002090600302016001015460118681548110620010ad57620010ad6200469b565b906000526020600020906003020160010154620010cb9190620045d0565b620010d7919062004616565b905060008260118781548110620010f257620010f26200469b565b906000526020600020906003020160020154601187815481106200111a576200111a6200469b565b906000526020600020906003020160020154620011389190620045d0565b62001144919062004616565b9050620011548c8e848462002d14565b8885815181106200116957620011696200469b565b602090810291909101015250505060010162001186878462004685565b925062000ff5565b509293505050505b949350505050565b6017546018544260008080620011bd6014546015546016549192909190565b92509250925083811462001211576000620011d98286620045d0565b9050620011e78185620045e6565b620011f3908862004685565b9650620012018184620045e6565b6200120d908762004685565b9550505b505050909192565b6000336200122985828562002ee9565b6200123685858562002f6a565b60019150505b9392505050565b601181815481106200125457600080fd5b600091825260209091206003909102018054600182015460029092015490925083565b60006200128362003122565b905090565b60003362000f658185856200129e83836200205d565b620012aa919062004685565b62002bec565b606062001196848484600162000f71565b6000620012cd6200270a565b601454601554600d546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156200131d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620013439190620045a0565b600e546040516370a0823160e01b81523060048201529192506000916001600160a01b03909116906370a0823190602401602060405180830381865afa15801562001392573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620013b89190620045a0565b90506000620013c88584620045d0565b90506000620013d88584620045d0565b90506000620013e660025490565b905080600003620014d6576103e86200140a620014048486620045e6565b62003250565b620014169190620045d0565b97506200142760016103e862003355565b600c54600160a01b900460ff1615620014d0576013546200145183670de0b6b3a7640000620045e6565b6200145d919062004616565b6012546200147485670de0b6b3a7640000620045e6565b62001480919062004616565b146200149f576040516305026bfd60e11b815260040160405180910390fd5b6402540be400620014b1848462002927565b11620014d0576040516321c69d6f60e11b815260040160405180910390fd5b62001515565b6200151287620014e78386620045e6565b620014f3919062004616565b87620015008486620045e6565b6200150c919062004616565b62003426565b97505b876000036200153757604051633489be7560e21b815260040160405180910390fd5b62001543898962003355565b620015518585898962002a46565b604080518481526020810184905233917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a2505050505050506200159e6001600955565b919050565b6001600160a01b03811660009081526007602052604081205462000f6b565b600060608082808083620015f87f000000000000000000000000000000000000000000000000000000000000000060056200343e565b620016257f310000000000000000000000000000000000000000000000000000000000000160066200343e565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b6000806200165c6200270a565b601454601554600d54600e546040516370a0823160e01b81523060048201526001600160a01b03928316929091169060009083906370a0823190602401602060405180830381865afa158015620016b7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620016dd9190620045a0565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a0823190602401602060405180830381865afa15801562001728573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200174e9190620045a0565b306000908152602081905260409020546002549192509080620017728584620045e6565b6200177e919062004616565b9950806200178d8484620045e6565b62001799919062004616565b9850891580620017a7575088155b15620017c65760405163749383ad60e01b815260040160405180910390fd5b620017d23083620034ef565b620017e86001600160a01b0387168c8c62002765565b620017fe6001600160a01b0386168c8b62002765565b6040516370a0823160e01b81523060048201526001600160a01b038716906370a0823190602401602060405180830381865afa15801562001843573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018699190620045a0565b6040516370a0823160e01b81523060048201529094506001600160a01b038616906370a0823190602401602060405180830381865afa158015620018b1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018d79190620045a0565b9250620018e784848a8a62002a46565b604080518b8152602081018b90526001600160a01b038d169133917f5d624aa9c148153ab3446c1b154f660ee7701e549fe9b62dab7171b1c80e6fa2910160405180910390a35050505050505050620019406001600955565b915091565b6200196a60405180606001604052806000815260200160008152602001600081525090565b601180546200197c90600190620045d0565b815481106200198f576200198f6200469b565b90600052602060002090600302016040518060600160405290816000820154815260200160018201548152602001600282015481525050905090565b6060600b805462000ecc9062004639565b600080620019ee858585600162000f71565b8051909150600090815b8181101562001a425783818151811062001a165762001a166200469b565b60200260200101518362001a2b919062004685565b92508062001a3981620046b1565b915050620019f8565b5062001a4f858362004616565b979650505050505050565b6000338162001a6a82866200205d565b90508381101562001ad05760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084015b60405180910390fd5b62001adf828686840362002bec565b506001949350505050565b60003362000f6581858562002f6a565b600c60009054906101000a90046001600160a01b03166001600160a01b0316637778960e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001b4e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001b749190620046cd565b6001600160a01b0316336001600160a01b03161462001ba65760405163c560129360e01b815260040160405180910390fd5b600b62001bb58284836200473f565b505050565b62001bc46200270a565b600d54600e546014546040516370a0823160e01b81523060048201526001600160a01b03938416939092169162001c6491859185906370a0823190602401602060405180830381865afa15801562001c20573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001c469190620045a0565b62001c529190620045d0565b6001600160a01b038516919062002765565b6015546040516370a0823160e01b815230600482015262001cf79185916001600160a01b038516906370a0823190602401602060405180830381865afa15801562001cb3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001cd99190620045a0565b62001ce59190620045d0565b6001600160a01b038416919062002765565b505062001d046001600955565b50565b600c60009054906101000a90046001600160a01b03166001600160a01b0316637778960e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001d5b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001d819190620046cd565b6001600160a01b0316336001600160a01b03161462001db35760405163c560129360e01b815260040160405180910390fd5b600a62001bb58284836200473f565b6000803362001dd18162003633565b6001600160a01b0381166000908152601d6020908152604080832054601e9092529091205490935091508215158062001e0a5750600082115b1562001ee8576001600160a01b038181166000818152601d60209081526040808320839055601e90915280822091909155600f54905163299e7ae760e11b8152600481019290925260248201869052604482018590529091169063533cf5ce90606401600060405180830381600087803b15801562001e8857600080fd5b505af115801562001e9d573d6000803e3d6000fd5b505060408051868152602081018690526001600160a01b03851693508392507f865ca08d59f5cb456e85cd2f7ef63664ea4f73327414e9d8152c4158b0e94645910160405180910390a35b509091565b8342111562001f3f5760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e65000000604482015260640162001ac7565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c988888862001f708c620037a6565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600062001fcd82620037ce565b9050600062001fdf82878787620037fe565b9050896001600160a01b0316816001600160a01b031614620020445760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e61747572650000604482015260640162001ac7565b620020518a8a8a62002bec565b50505050505050505050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6010546001600160a01b031615620020b3576040516302a98a3760e31b815260040160405180910390fd5b601080546001600160a01b03191633908117909155604080516311b25aab60e21b815290516346c96aac916004808201926020929091908290030181865afa15801562002104573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200212a9190620046cd565b600c80546001600160a01b039283166001600160a81b031990911617600160a01b84151502179055600e80546001600160a01b031990811685841617909155600d8054909116918516919091179055604051839083906200218b9062004069565b6001600160a01b03928316815291166020820152604001604051809103906000f080158015620021bf573d6000803e3d6000fd5b50600f60006101000a8154816001600160a01b0302191690836001600160a01b031602179055506000836001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562002227573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200225191908101906200480c565b90506000836001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562002294573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620022be91908101906200480c565b9050821562002337578181604051602001620022dc929190620048ba565b604051602081830303815290604052600a9081620022fb919062004915565b50818160405160200162002311929190620049e2565b604051602081830303815290604052600b908162002330919062004915565b50620023a2565b81816040516020016200234c92919062004a35565b604051602081830303815290604052600a90816200236b919062004915565b5081816040516020016200238192919062004a92565b604051602081830303815290604052600b9081620023a0919062004915565b505b846001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620023e1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002407919062004ab6565b6200241490600a62004bd3565b601281905550836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562002459573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200247f919062004ab6565b6200248c90600a62004bd3565b60135550506040805160608101825242815260006020820181815292820181815260118054600181018255925291517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6860039092029182015591517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c69830155517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6a90910155505050565b601454601554601054600c5460405163cc56b2c560e01b8152306004820152600160a01b90910460ff16151560248201526000939291612710916001600160a01b039091169063cc56b2c590604401602060405180830381865afa158015620025a3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620025c99190620045a0565b620025d59087620045e6565b620025e1919062004616565b620025ed9086620045d0565b9450620025fd8585848462002d14565b95945050505050565b620026106200270a565b600d546040516370a0823160e01b8152306004820152620026fd916001600160a01b0316906370a0823190602401602060405180830381865afa1580156200265c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620026829190620045a0565b600e546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015620026cb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620026f19190620045a0565b60145460155462002a46565b620027086001600955565b565b6002600954036200275e5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640162001ac7565b6002600955565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905262001bb59084906200382a565b80600003620027c55750565b600f54600d54620027e4916001600160a01b0391821691168362002765565b6000620027f060025490565b6200280483670de0b6b3a7640000620045e6565b62002810919062004616565b90508015620028335780601960008282546200282d919062004685565b90915550505b604080518381526000602082015233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a860291015b60405180910390a25050565b806000036200287f5750565b600f54600e546200289e916001600160a01b0391821691168362002765565b6000620028aa60025490565b620028be83670de0b6b3a7640000620045e6565b620028ca919062004616565b90508015620028ed5780601a6000828254620028e7919062004685565b90915550505b60408051600081526020810184905233917f112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a8602910162002867565b600c54600090600160a01b900460ff161562002a32576012546000906200295785670de0b6b3a7640000620045e6565b62002963919062004616565b9050600060135484670de0b6b3a7640000620029809190620045e6565b6200298c919062004616565b90506000670de0b6b3a7640000620029a58385620045e6565b620029b1919062004616565b90506000670de0b6b3a7640000620029ca8480620045e6565b620029d6919062004616565b670de0b6b3a7640000620029eb8680620045e6565b620029f7919062004616565b62002a03919062004685565b9050670de0b6b3a764000062002a1a8284620045e6565b62002a26919062004616565b94505050505062000f6b565b62002a3e8284620045e6565b905062000f6b565b601654429060009062002a5a9083620045d0565b905060008111801562002a6c57508315155b801562002a7857508215155b1562002ac85762002a8a8185620045e6565b6017600082825462002a9d919062004685565b9091555062002aaf90508184620045e6565b6018600082825462002ac2919062004685565b90915550505b600062002ad462001945565b805190915062002ae59084620045d0565b915061070882111562002b9b5760408051606081018252848152601754602082019081526018549282019283526011805460018101825560009190915291517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c68600390930292830155517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6982015590517f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6a909101555b60148790556015869055601683905560408051888152602081018890527fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a150505050505050565b6001600160a01b03831662002c505760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840162001ac7565b6001600160a01b03821662002cb35760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840162001ac7565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b600c54600090600160a01b900460ff161562002e9057600062002d38848462002927565b60125490915062002d5285670de0b6b3a7640000620045e6565b62002d5e919062004616565b60135490945062002d7884670de0b6b3a7640000620045e6565b62002d84919062004616565b600d5490935060009081906001600160a01b0388811691161462002daa57848662002dad565b85855b600d5491935091506001600160a01b0388811691161462002df15760135462002ddf89670de0b6b3a7640000620045e6565b62002deb919062004616565b62002e14565b60125462002e0889670de0b6b3a7640000620045e6565b62002e14919062004616565b9750600062002e3062002e28848b62004685565b858462003903565b62002e3c9083620045d0565b600d54909150670de0b6b3a7640000906001600160a01b038a811691161462002e685760125462002e6c565b6013545b62002e789083620045e6565b62002e84919062004616565b94505050505062001196565b600d5460009081906001600160a01b0387811691161462002eb357838562002eb6565b84845b909250905062002ec7878362004685565b62002ed38289620045e6565b62002edf919062004616565b9250505062001196565b600062002ef784846200205d565b9050600019811462002f64578181101562002f555760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640162001ac7565b62002f64848484840362002bec565b50505050565b6001600160a01b03831662002fd05760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840162001ac7565b6001600160a01b038216620030345760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840162001ac7565b6200304183838362003aa9565b6001600160a01b03831660009081526020819052604090205481811015620030bb5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840162001ac7565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a362002f64565b6000306001600160a01b037f000000000000000000000000b7fabdcab63e048bb09ff35a2b09f9a6506f4edd161480156200317c57507f0000000000000000000000000000000000000000000000000000000000aa37dc46145b15620031a757507ff2c07de0a39b85226b24de252ca93be099567d46248181e37fd565e86dbc3e5a90565b62001283604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b6000816000036200326357506000919050565b60006001620032728462003abf565b901c6001901b905060018184816200328e576200328e62004600565b048201901c90506001818481620032a957620032a962004600565b048201901c90506001818481620032c457620032c462004600565b048201901c90506001818481620032df57620032df62004600565b048201901c90506001818481620032fa57620032fa62004600565b048201901c9050600181848162003315576200331562004600565b048201901c9050600181848162003330576200333062004600565b048201901c90506200123c818285816200334e576200334e62004600565b0462003426565b6001600160a01b038216620033ad5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640162001ac7565b620033bb6000838362003aa9565b8060026000828254620033cf919062004685565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b60008183106200343757816200123c565b5090919050565b606060ff831615620034555762002a3e8362003b5b565b818054620034639062004639565b80601f0160208091040260200160405190810160405280929190818152602001828054620034919062004639565b8015620034e25780601f10620034b657610100808354040283529160200191620034e2565b820191906000526020600020905b815481529060010190602001808311620034c457829003601f168201915b5050505050905062000f6b565b6001600160a01b038216620035515760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840162001ac7565b6200355f8260008362003aa9565b6001600160a01b03821660009081526020819052604090205481811015620035d55760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840162001ac7565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6001600160a01b038116600090815260208190526040902054801562003774576001600160a01b0382166000908152601b602090815260408083208054601c8085529285208054601954601a54948190559490955282905593620036988584620045d0565b90506000620036a88584620045d0565b905081156200370a576000670de0b6b3a7640000620036c8848a620045e6565b620036d4919062004616565b6001600160a01b038a166000908152601d60205260408120805492935083929091906200370390849062004685565b9091555050505b80156200376a576000670de0b6b3a764000062003728838a620045e6565b62003734919062004616565b6001600160a01b038a166000908152601e60205260408120805492935083929091906200376390849062004685565b9091555050505b5050505050505050565b6019546001600160a01b0383166000908152601b6020908152604080832093909355601a54601c909152919020555050565b6001600160a01b03811660009081526007602052604090208054600181018255905b50919050565b600062000f6b620037de62003122565b8360405161190160f01b8152600281019290925260228201526042902090565b6000806000620038118787878762003b90565b91509150620038208162003c59565b5095945050505050565b600062003881826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031662003db69092919063ffffffff16565b80519091501562001bb55780806020019051810190620038a2919062004534565b62001bb55760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162001ac7565b6000805b60ff81101562003a7a5760006200391f868562003dc7565b905084811015620039d457600062003938878662003e60565b620039448388620045d0565b6200395890670de0b6b3a7640000620045e6565b62003964919062004616565b905080600003620039bf5785820362003983578493505050506200123c565b856200399c886200399688600162004685565b62002927565b1115620039bb57620039b085600162004685565b93505050506200123c565b5060015b620039cb818662004685565b94505062003a64565b6000620039e2878662003e60565b620039ee8784620045d0565b62003a0290670de0b6b3a7640000620045e6565b62003a0e919062004616565b90508060000362003a54578582148062003a3e57508562003a3c8862003a36600189620045d0565b62003dc7565b105b1562003a50578493505050506200123c565b5060015b62003a608186620045d0565b9450505b508062003a7181620046b1565b91505062003907565b5060405162461bcd60e51b8152602060048201526002602482015261217960f01b604482015260640162001ac7565b62003ab48362003633565b62001bb58262003633565b600080608083901c1562003ad557608092831c92015b604083901c1562003ae857604092831c92015b602083901c1562003afb57602092831c92015b601083901c1562003b0e57601092831c92015b600883901c1562003b2157600892831c92015b600483901c1562003b3457600492831c92015b600283901c1562003b4757600292831c92015b600183901c1562000f6b5760010192915050565b60408051602080825281830190925260609160ff84169160009180820181803683375050509182525060208101929092525090565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111562003bc9575060009050600362003c50565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801562003c1e573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811662003c495760006001925092505062003c50565b9150600090505b94509492505050565b600081600481111562003c705762003c7062004be4565b0362003c795750565b600181600481111562003c905762003c9062004be4565b0362003cdf5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640162001ac7565b600281600481111562003cf65762003cf662004be4565b0362003d455760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640162001ac7565b600381600481111562003d5c5762003d5c62004be4565b0362001d045760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840162001ac7565b606062001196848460008562003ef0565b600080670de0b6b3a764000062003ddf8486620045e6565b62003deb919062004616565b90506000670de0b6b3a764000062003e048580620045e6565b62003e10919062004616565b670de0b6b3a764000062003e258780620045e6565b62003e31919062004616565b62003e3d919062004685565b9050670de0b6b3a764000062003e548284620045e6565b620025fd919062004616565b6000670de0b6b3a7640000838162003e798280620045e6565b62003e85919062004616565b62003e919190620045e6565b62003e9d919062004616565b670de0b6b3a76400008062003eb38580620045e6565b62003ebf919062004616565b62003ecc866003620045e6565b62003ed89190620045e6565b62003ee4919062004616565b6200123c919062004685565b60608247101562003f535760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162001ac7565b600080866001600160a01b0316858760405162003f71919062004bfa565b60006040518083038185875af1925050503d806000811462003fb0576040519150601f19603f3d011682016040523d82523d6000602084013e62003fb5565b606091505b509150915062001a4f8783838760608315620040365782516000036200402e576001600160a01b0385163b6200402e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162001ac7565b508162001196565b6200119683838151156200404d5781518083602001fd5b8060405162461bcd60e51b815260040162001ac791906200419d565b6105818062004c1983390190565b6001600160a01b038116811462001d0457600080fd5b60008083601f840112620040a057600080fd5b50813567ffffffffffffffff811115620040b957600080fd5b602083019150836020828501011115620040d257600080fd5b9250929050565b600080600080600060808688031215620040f257600080fd5b853594506020860135935060408601356200410d8162004077565b9250606086013567ffffffffffffffff8111156200412a57600080fd5b62004138888289016200408d565b969995985093965092949392505050565b60005b83811015620041665781810151838201526020016200414c565b50506000910152565b600081518084526200418981602086016020860162004149565b601f01601f19169290920160200192915050565b6020815260006200123c60208301846200416f565b60008060408385031215620041c657600080fd5b8235620041d38162004077565b946020939093013593505050565b60008060008060808587031215620041f857600080fd5b8435620042058162004077565b966020860135965060408601359560600135945092505050565b600081518084526020808501945080840160005b83811015620042515781518752958201959082019060010162004233565b509495945050505050565b6020815260006200123c60208301846200421f565b6000602082840312156200428457600080fd5b81356200123c8162004077565b600080600060608486031215620042a757600080fd5b8335620042b48162004077565b92506020840135620042c68162004077565b929592945050506040919091013590565b600060208284031215620042ea57600080fd5b5035919050565b6000806000606084860312156200430757600080fd5b8335620043148162004077565b95602085013595506040909401359392505050565b60ff60f81b8816815260e0602082015260006200434a60e08301896200416f565b82810360408401526200435e81896200416f565b606084018890526001600160a01b038716608085015260a0840186905283810360c085015290506200439181856200421f565b9a9950505050505050505050565b60008060208385031215620043b357600080fd5b823567ffffffffffffffff811115620043cb57600080fd5b620043d9858286016200408d565b90969095509350505050565b60ff8116811462001d0457600080fd5b600080600080600080600060e0888a0312156200441157600080fd5b87356200441e8162004077565b96506020880135620044308162004077565b9550604088013594506060880135935060808801356200445081620043e5565b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156200448157600080fd5b82356200448e8162004077565b91506020830135620044a08162004077565b809150509250929050565b801515811462001d0457600080fd5b600080600060608486031215620044d057600080fd5b8335620044dd8162004077565b92506020840135620044ef8162004077565b915060408401356200450181620044ab565b809150509250925092565b600080604083850312156200452057600080fd5b823591506020830135620044a08162004077565b6000602082840312156200454757600080fd5b81516200123c81620044ab565b60018060a01b038616815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b600060208284031215620045b357600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8181038181111562000f6b5762000f6b620045ba565b808202811582820484141762000f6b5762000f6b620045ba565b634e487b7160e01b600052601260045260246000fd5b6000826200463457634e487b7160e01b600052601260045260246000fd5b500490565b600181811c908216806200464e57607f821691505b602082108103620037c857634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b8082018082111562000f6b5762000f6b620045ba565b634e487b7160e01b600052603260045260246000fd5b600060018201620046c657620046c6620045ba565b5060010190565b600060208284031215620046e057600080fd5b81516200123c8162004077565b601f82111562001bb557600081815260208120601f850160051c81016020861015620047165750805b601f850160051c820191505b81811015620047375782815560010162004722565b505050505050565b67ffffffffffffffff8311156200475a576200475a6200466f565b62004772836200476b835462004639565b83620046ed565b6000601f841160018114620047a95760008515620047905750838201355b600019600387901b1c1916600186901b17835562000eb4565b600083815260209020601f19861690835b82811015620047dc5786850135825560209485019460019092019101620047ba565b5086821015620047fa5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b6000602082840312156200481f57600080fd5b815167ffffffffffffffff808211156200483857600080fd5b818401915084601f8301126200484d57600080fd5b8151818111156200486257620048626200466f565b604051601f8201601f19908116603f011681019083821181831017156200488d576200488d6200466f565b81604052828152876020848701011115620048a757600080fd5b62001a4f83602083016020880162004149565b6e029ba30b13632ab191020a6a690169608d1b815260008351620048e681600f85016020880162004149565b602f60f81b600f9184019182015283516200490981601084016020880162004149565b01601001949350505050565b815167ffffffffffffffff8111156200493257620049326200466f565b6200494a8162004943845462004639565b84620046ed565b602080601f831160018114620049825760008415620049695750858301515b600019600386901b1c1916600185901b17855562004737565b600085815260208120601f198616915b82811015620049b35788860151825594840194600190910190840162004992565b5085821015620049d25787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6673414d4d56322d60c81b81526000835162004a0681600785016020880162004149565b602f60f81b600791840191820152835162004a2981600884016020880162004149565b01600801949350505050565b7002b37b630ba34b632ab191020a6a690169607d1b81526000835162004a6381601185016020880162004149565b602f60f81b601191840191820152835162004a8681601284016020880162004149565b01601201949350505050565b6676414d4d56322d60c81b81526000835162004a0681600785016020880162004149565b60006020828403121562004ac957600080fd5b81516200123c81620043e5565b600181815b8085111562004b1757816000190482111562004afb5762004afb620045ba565b8085161562004b0957918102915b93841c939080029062004adb565b509250929050565b60008262004b305750600162000f6b565b8162004b3f5750600062000f6b565b816001811462004b58576002811462004b635762004b83565b600191505062000f6b565b60ff84111562004b775762004b77620045ba565b50506001821b62000f6b565b5060208310610133831016604e8410600b841016171562004ba8575081810a62000f6b565b62004bb4838362004ad6565b806000190482111562004bcb5762004bcb620045ba565b029392505050565b60006200123c60ff84168362004b1f565b634e487b7160e01b600052602160045260246000fd5b6000825162004c0e81846020870162004149565b919091019291505056fe60e060405234801561001057600080fd5b5060405161058138038061058183398101604081905261002f91610066565b336080526001600160a01b0391821660a0521660c052610099565b80516001600160a01b038116811461006157600080fd5b919050565b6000806040838503121561007957600080fd5b6100828361004a565b91506100906020840161004a565b90509250929050565b60805160a05160c0516104bc6100c5600039600060db0152600060a101526000605001526104bc6000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063533cf5ce14610030575b600080fd5b61004361003e3660046103a9565b610045565b005b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461008e57604051636f61f64160e01b815260040160405180910390fd5b81156100c8576100c86001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168484610107565b8015610102576101026001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168483610107565b505050565b604080516001600160a01b03848116602483015260448083018590528351808403909101815260649092018352602080830180516001600160e01b031663a9059cbb60e01b17905283518085019094528084527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649084015261010292869291600091610197918516908490610219565b80519091501561010257808060200190518101906101b591906103ea565b6101025760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084015b60405180910390fd5b60606102288484600085610230565b949350505050565b6060824710156102915760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610210565b600080866001600160a01b031685876040516102ad9190610437565b60006040518083038185875af1925050503d80600081146102ea576040519150601f19603f3d011682016040523d82523d6000602084013e6102ef565b606091505b50915091506103008783838761030b565b979650505050505050565b6060831561037a578251600003610373576001600160a01b0385163b6103735760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610210565b5081610228565b610228838381511561038f5781518083602001fd5b8060405162461bcd60e51b81526004016102109190610453565b6000806000606084860312156103be57600080fd5b83356001600160a01b03811681146103d557600080fd5b95602085013595506040909401359392505050565b6000602082840312156103fc57600080fd5b8151801515811461040c57600080fd5b9392505050565b60005b8381101561042e578181015183820152602001610416565b50506000910152565b60008251610449818460208701610413565b9190910192915050565b6020815260008251806020840152610472816040850160208701610413565b601f01601f1916919091016040019291505056fea26469706673582212205e5499e3f9c7a0a696d53c6d17a2dd592efb80bae3e5401fbc29f58ac6d664ec64736f6c63430008130033a26469706673582212202b2b184adb2e50f82565b7eb0000c83c47c4b055a844d7c7c95c40853f0651ae64736f6c63430008130033
Deployed Bytecode Sourcemap
98896:21931:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;112972:2624;;;;;;:::i;:::-;;:::i;:::-;;120477:92;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;105806:232;105940:8;;105971;;106012:18;;105806:232;;;;2146:25:1;;;2202:2;2187:18;;2180:34;;;;2230:18;;;2223:34;2134:2;2119:18;105806:232:0;1944:319:1;52155:201:0;;;;;;:::i;:::-;;:::i;:::-;;;2753:14:1;;2746:22;2728:41;;2716:2;2701:18;52155:201:0;2588:187:1;99267:21:0;;;;;-1:-1:-1;;;;;99267:21:0;;;;;;-1:-1:-1;;;;;2944:32:1;;;2926:51;;2914:2;2899:18;99267:21:0;2780:203:1;108795:1121:0;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;50924:108::-;51012:12;;50924:108;;;4297:25:1;;;4285:2;4270:18;50924:108:0;4151:177:1;107189:830:0;;;:::i;100432:47::-;;;;;;:::i;:::-;;;;;;;;;;;;;;99125:18;;;;;-1:-1:-1;;;99125:18:0;;;;;;52936:261;;;;;;:::i;:::-;;:::i;99706:33::-;;;;;;:::i;:::-;;:::i;50766:93::-;;;50849:2;5373:36:1;;5361:2;5346:18;50766:93:0;5231:184:1;100213:25:0;;;;;;99323:23;;;;;-1:-1:-1;;;;;99323:23:0;;;63420:115;;;:::i;102426:252::-;102605:9;;102616;;102627:8;;102637;;102647:6;;102655;;102663;;102426:252;;;5911:25:1;;;5967:2;5952:18;;5945:34;;;;5995:18;;;5988:34;;;;6053:2;6038:18;;6031:34;;;;-1:-1:-1;;;102647:6:0;;;;6109:14:1;6102:22;6096:3;6081:19;;6074:51;-1:-1:-1;;;;;102655:6:0;;;6152:3:1;6179:19;;6172:44;102663:6:0;6247:3:1;6232:19;;6225:44;5898:3;5883:19;102426:252:0;5602:673:1;53606:238:0;;;;;;:::i;:::-;;:::i;99816:23::-;;;;;;100583:45;;;;;;:::i;:::-;;;;;;;;;;;;;;108617:170;;;;;;:::i;:::-;;:::i;99846:23::-;;;;;;110096:1359;;;;;;:::i;:::-;;:::i;51095:127::-;;;;;;:::i;:::-;-1:-1:-1;;;;;51196:18:0;51169:7;51196:18;;;;;;;;;;;;51095:127;63162:128;;;;;;:::i;:::-;;:::i;18350:657::-;;;:::i;:::-;;;;;;;;;;;;;:::i;111610:1250::-;;;;;;:::i;:::-;;:::i;:::-;;;;7767:25:1;;;7823:2;7808:18;;7801:34;;;;7740:18;111610:1250:0;7593:248:1;102287:131:0;;;:::i;:::-;;;;8068:13:1;;8050:32;;8138:4;8126:17;;;8120:24;8098:20;;;8091:54;8189:17;;;8183:24;8161:20;;;8154:54;8038:2;8023:18;102287:131:0;7846:368:1;120577:96:0;;;:::i;102686:101::-;102764:6;;102772;;102686:101;;;-1:-1:-1;;;;;102764:6:0;;;8431:34:1;;102772:6:0;;;;8496:2:1;8481:18;;8474:43;8366:18;102686:101:0;8219:304:1;108116:449:0;;;;;;:::i;:::-;;:::i;100378:47::-;;;;;;:::i;:::-;;;;;;;;;;;;;;100635:45;;;;;;:::i;:::-;;;;;;;;;;;;;;54347:436;;;;;;:::i;:::-;;:::i;51428:193::-;;;;;;:::i;:::-;;:::i;101982:183::-;;;;;;:::i;:::-;;:::i;115645:316::-;;;;;;:::i;:::-;;:::i;100245:25::-;;;;;;99918:37;;;;;;99962;;;;;;99353:22;;;;;-1:-1:-1;;;;;99353:22:0;;;101799:175;;;;;;:::i;:::-;;:::i;99876:33::-;;;;;;99295:21;;;;;-1:-1:-1;;;;;99295:21:0;;;102881:505;;;:::i;62451:645::-;;;;;;:::i;:::-;;:::i;51684:151::-;;;;;;:::i;:::-;;:::i;100743:1048::-;;;;;;:::i;:::-;;:::i;102173:106::-;102252:12;:19;102173:106;;118494:371;;;;;;:::i;:::-;;:::i;116010:166::-;;;:::i;112972:2624::-;44445:21;:19;:21::i;:::-;113109:7:::1;;;;;;;;;-1:-1:-1::0;;;;;113109:7:0::1;-1:-1:-1::0;;;;;113096:30:0::1;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;113092:55;;;113137:10;;-1:-1:-1::0;;;113137:10:0::1;;;;;;;;;;;113092:55;113162:15:::0;;:34;::::1;;;-1:-1:-1::0;113181:15:0;;113162:34:::1;113158:73;;;113205:26;;-1:-1:-1::0;;;113205:26:0::1;;;;;;;;;;;113158:73;113284:8;::::0;113294::::1;::::0;113318:23;;::::1;;::::0;:50:::1;;;113359:9;113345:10;:23;;113318:50;113314:86;;;113377:23;;-1:-1:-1::0;;;113377:23:0::1;;;;;;;;;;;113314:86;113590:6;::::0;113598::::1;::::0;113413:17:::1;::::0;;;-1:-1:-1;;;;;113590:6:0;;::::1;::::0;113598;;::::1;::::0;113624:13;::::1;::::0;::::1;::::0;:30:::1;;;113647:7;-1:-1:-1::0;;;;;113641:13:0::1;:2;-1:-1:-1::0;;;;;113641:13:0::1;;113624:30;113620:54;;;113663:11;;-1:-1:-1::0;;;113663:11:0::1;;;;;;;;;;;113620:54;113693:14:::0;;113689:64:::1;;113709:44;-1:-1:-1::0;;;;;113709:28:0;::::1;113738:2:::0;113742:10;113709:28:::1;:44::i;:::-;113806:14:::0;;113802:64:::1;;113822:44;-1:-1:-1::0;;;;;113822:28:0;::::1;113851:2:::0;113855:10;113822:28:::1;:44::i;:::-;113919:15:::0;;113915:85:::1;;113936:64;::::0;-1:-1:-1;;;113936:64:0;;-1:-1:-1;;;;;113936:20:0;::::1;::::0;::::1;::::0;:64:::1;::::0;29012:10;;113971;;113983;;113995:4;;;;113936:64:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;113915:85;114061:40;::::0;-1:-1:-1;;;114061:40:0;;114095:4:::1;114061:40;::::0;::::1;2926:51:1::0;-1:-1:-1;;;;;114061:25:0;::::1;::::0;::::1;::::0;2899:18:1;;114061:40:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;114128;::::0;-1:-1:-1;;;114128:40:0;;114162:4:::1;114128:40;::::0;::::1;2926:51:1::0;114049:52:0;;-1:-1:-1;;;;;;114128:25:0;::::1;::::0;::::1;::::0;2899:18:1;;114128:40:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;114116:52;;113469:711;;114190:17;114234:10;114222:9;:22;;;;:::i;:::-;114210:9;:34;:77;;114286:1;114210:77;;;114260:22;114272:10:::0;114260:9;:22:::1;:::i;:::-;114247:36;::::0;:9;:36:::1;:::i;:::-;114190:97:::0;-1:-1:-1;114298:17:0::1;114330:22;114342:10:::0;114330:9;:22:::1;:::i;:::-;114318:9;:34;:77;;114394:1;114318:77;;;114368:22;114380:10:::0;114368:9;:22:::1;:::i;:::-;114355:36;::::0;:9;:36:::1;:::i;:::-;114298:97:::0;-1:-1:-1;114410:14:0;;:32;::::1;;;-1:-1:-1::0;114428:14:0;;114410:32:::1;114406:70;;;114451:25;;-1:-1:-1::0;;;114451:25:0::1;;;;;;;;;;;114406:70;114617:6;::::0;114625::::1;::::0;-1:-1:-1;;;;;114617:6:0;;::::1;::::0;114625::::1;114651:13:::0;;114647:102:::1;;114701:7;::::0;114732:6:::1;::::0;114688:51:::1;::::0;-1:-1:-1;;;114688:51:0;;114725:4:::1;114688:51;::::0;::::1;12741::1::0;-1:-1:-1;;;114732:6:0;;::::1;;;12835:14:1::0;12828:22;12808:18;;;12801:50;114666:83:0::1;::::0;114743:5:::1;::::0;-1:-1:-1;;;;;114701:7:0;;::::1;::::0;114688:28:::1;::::0;12714:18:1;;114688:51:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;114676:63;::::0;:9;:63:::1;:::i;:::-;114675:73;;;;:::i;:::-;114666:8;:83::i;:::-;114820:13:::0;;114816:102:::1;;114870:7;::::0;114901:6:::1;::::0;114857:51:::1;::::0;-1:-1:-1;;;114857:51:0;;114894:4:::1;114857:51;::::0;::::1;12741::1::0;-1:-1:-1;;;114901:6:0;;::::1;;;12835:14:1::0;12828:22;12808:18;;;12801:50;114835:83:0::1;::::0;114912:5:::1;::::0;-1:-1:-1;;;;;114870:7:0;;::::1;::::0;114857:28:::1;::::0;12714:18:1;;114857:51:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;114845:63;::::0;:9;:63:::1;:::i;:::-;114844:73;;;;:::i;:::-;114835:8;:83::i;:::-;114997:40;::::0;-1:-1:-1;;;114997:40:0;;115031:4:::1;114997:40;::::0;::::1;2926:51:1::0;-1:-1:-1;;;;;114997:25:0;::::1;::::0;::::1;::::0;2899:18:1;;114997:40:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;115221;::::0;-1:-1:-1;;;115221:40:0;;115255:4:::1;115221:40;::::0;::::1;2926:51:1::0;114985:52:0;;-1:-1:-1;;;;;;115221:25:0;::::1;::::0;::::1;::::0;2899:18:1;;115221:40:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;115209:52;;115393:24;115396:9;115407;115393:2;:24::i;:::-;115366;115369:9;115380;115366:2;:24::i;:::-;:51;115362:67;;;115426:3;;-1:-1:-1::0;;;115426:3:0::1;;;;;;;;;;;115362:67;114487:954;;115453:51;115461:9;115472;115483;115494;115453:7;:51::i;:::-;115520:68;::::0;;13620:25:1;;;13676:2;13661:18;;13654:34;;;13704:18;;;13697:34;;;13762:2;13747:18;;13740:34;;;115520:68:0;;-1:-1:-1;;;;;115520:68:0;::::1;::::0;29012:10;;115520:68:::1;::::0;;;;13607:3:1;115520:68:0;;::::1;113081:2515;;;;;;44489:20:::0;43883:1;45009:7;:22;44826:213;44489:20;112972:2624;;;;;:::o;120477:92::-;120523:13;120556:5;120549:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;120477:92;:::o;52155:201::-;52238:4;29012:10;52294:32;29012:10;52310:7;52319:6;52294:8;:32::i;:::-;52344:4;52337:11;;;52155:201;;;;;:::o;108795:1121::-;108942:16;108971:24;109012:6;108998:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;108998:21:0;-1:-1:-1;109049:12:0;:19;108971:48;;-1:-1:-1;109032:14:0;;109049:23;;109071:1;;109049:23;:::i;:::-;109032:40;-1:-1:-1;109083:9:0;109105:15;109114:6;109105;:15;:::i;:::-;109095:26;;:6;:26;:::i;:::-;109083:38;;109132:17;109164:13;109194:690;109205:6;109201:1;:10;109194:690;;;109253:10;109257:6;109253:1;:10;:::i;:::-;109241:22;;109278:19;109336:12;109349:1;109336:15;;;;;;;;:::i;:::-;;;;;;;;;;;:25;;;109300:12;109313:9;109300:23;;;;;;;;:::i;:::-;;;;;;;;;;;:33;;;:61;;;;:::i;:::-;109278:83;;109376:17;109497:11;109442:12;109455:1;109442:15;;;;;;;;:::i;:::-;;;;;;;;;;;:34;;;109397:12;109410:9;109397:23;;;;;;;;:::i;:::-;;;;;;;;;;;:42;;;:79;;;;:::i;:::-;109396:112;;;;:::i;:::-;109376:132;;109523:17;109644:11;109589:12;109602:1;109589:15;;;;;;;;:::i;:::-;;;;;;;;;;;:34;;;109544:12;109557:9;109544:23;;;;;;;;:::i;:::-;;;;;;;;;;;:42;;;:79;;;;:::i;:::-;109543:112;;;;:::i;:::-;109523:132;;109687:54;109701:8;109711:7;109720:9;109731;109687:13;:54::i;:::-;109670:7;109678:5;109670:14;;;;;;;;:::i;:::-;;;;;;;;;;:71;-1:-1:-1;;;109856:1:0;109848:9;109213:11;109218:6;109213:11;;:::i;:::-;;;109194:690;;;-1:-1:-1;109901:7:0;;-1:-1:-1;;;;108795:1121:0;;;;;;;:::o;107189:830::-;107432:22;;107486;;107385:15;107272:26;;;107692:13;105940:8;;105971;;106012:18;;105940:8;;105971;;106012:18;105806:232;107692:13;107622:83;;;;;;107743:14;107720:19;:37;107716:296;;107822:19;107844:36;107861:19;107844:14;:36;:::i;:::-;107822:58;-1:-1:-1;107917:23:0;107822:58;107917:9;:23;:::i;:::-;107895:45;;;;:::i;:::-;;-1:-1:-1;107977:23:0;107989:11;107977:9;:23;:::i;:::-;107955:45;;;;:::i;:::-;;;107759:253;107716:296;107357:662;;;107189:830;;;:::o;52936:261::-;53033:4;29012:10;53091:38;53107:4;29012:10;53122:6;53091:15;:38::i;:::-;53140:27;53150:4;53156:2;53160:6;53140:9;:27::i;:::-;53185:4;53178:11;;;52936:261;;;;;;:::o;99706:33::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;99706:33:0;:::o;63420:115::-;63480:7;63507:20;:18;:20::i;:::-;63500:27;;63420:115;:::o;53606:238::-;53694:4;29012:10;53750:64;29012:10;53766:7;53803:10;53775:25;29012:10;53766:7;53775:9;:25::i;:::-;:38;;;;:::i;:::-;53750:8;:64::i;108617:170::-;108707:16;108743:36;108750:7;108759:8;108769:6;108777:1;108743:6;:36::i;110096:1359::-;110153:17;44445:21;:19;:21::i;:::-;110225:8:::1;::::0;110235::::1;::::0;110282:6:::1;::::0;110275:39:::1;::::0;-1:-1:-1;;;110275:39:0;;110308:4:::1;110275:39;::::0;::::1;2926:51:1::0;110184:17:0::1;::::0;-1:-1:-1;;;;;110282:6:0::1;::::0;110275:24:::1;::::0;2899:18:1;;110275:39:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;110352:6;::::0;110345:39:::1;::::0;-1:-1:-1;;;110345:39:0;;110378:4:::1;110345:39;::::0;::::1;2926:51:1::0;110255:59:0;;-1:-1:-1;110325:17:0::1;::::0;-1:-1:-1;;;;;110352:6:0;;::::1;::::0;110345:24:::1;::::0;2899:18:1;;110345:39:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;110325:59:::0;-1:-1:-1;110395:16:0::1;110414:21;110426:9:::0;110414;:21:::1;:::i;:::-;110395:40:::0;-1:-1:-1;110446:16:0::1;110465:21;110477:9:::0;110465;:21:::1;:::i;:::-;110446:40;;110499:20;110522:13;51012:12:::0;;;50924:108;110522:13:::1;110499:36;;110628:12;110644:1;110628:17:::0;110624:608:::1;;99198:7;110674:30;110684:19;110695:8:::0;110684;:19:::1;:::i;:::-;110674:9;:30::i;:::-;:50;;;;:::i;:::-;110662:62;;110739:36;110753:1;99198:7;110739:5;:36::i;:::-;110872:6;::::0;-1:-1:-1;;;110872:6:0;::::1;;;110868:222;;;110956:9;::::0;110937:15:::1;:8:::0;110948:4:::1;110937:15;:::i;:::-;110936:29;;;;:::i;:::-;110923:9;::::0;110904:15:::1;:8:::0;110915:4:::1;110904:15;:::i;:::-;110903:29;;;;:::i;:::-;:62;110899:93;;110974:18;;-1:-1:-1::0;;;110974:18:0::1;;;;;;;;;;;110899:93;99250:8;111015:22;111018:8;111028;111015:2;:22::i;:::-;:35;111011:63;;111059:15;;-1:-1:-1::0;;;111059:15:0::1;;;;;;;;;;;111011:63;110624:608;;;111134:86;111171:9:::0;111144:23:::1;111155:12:::0;111144:8;:23:::1;:::i;:::-;111143:37;;;;:::i;:::-;111210:9:::0;111183:23:::1;111194:12:::0;111183:8;:23:::1;:::i;:::-;111182:37;;;;:::i;:::-;111134:8;:86::i;:::-;111122:98;;110624:608;111246:9;111259:1;111246:14:::0;111242:56:::1;;111269:29;;-1:-1:-1::0;;;111269:29:0::1;;;;;;;;;;;111242:56;111309:20;111315:2;111319:9;111309:5;:20::i;:::-;111342:51;111350:9;111361;111372;111383;111342:7;:51::i;:::-;111409:38;::::0;;7767:25:1;;;7823:2;7808:18;;7801:34;;;29012:10:0;;111409:38:::1;::::0;7740:18:1;111409:38:0::1;;;;;;;110172:1283;;;;;;;44489:20:::0;43883:1;45009:7;:22;44826:213;44489:20;110096:1359;;;:::o;63162:128::-;-1:-1:-1;;;;;63258:14:0;;63231:7;63258:14;;;:7;:14;;;;;12092;63258:24;12000:114;18350:657;18471:13;18499:18;;18471:13;;;18499:18;18773:41;:5;18800:13;18773:26;:41::i;:::-;18829:47;:8;18859:16;18829:29;:47::i;:::-;18972:16;;;18955:1;18972:16;;;;;;;;;-1:-1:-1;;;18720:279:0;;;-1:-1:-1;18720:279:0;;-1:-1:-1;18891:13:0;;-1:-1:-1;18927:4:0;;-1:-1:-1;18955:1:0;-1:-1:-1;18972:16:0;-1:-1:-1;18720:279:0;-1:-1:-1;18350:657:0:o;111610:1250::-;111667:15;111684;44445:21;:19;:21::i;:::-;111754:8:::1;::::0;111764::::1;::::0;111822:6:::1;::::0;111830::::1;::::0;111868:40:::1;::::0;-1:-1:-1;;;111868:40:0;;111902:4:::1;111868:40;::::0;::::1;2926:51:1::0;-1:-1:-1;;;;;111822:6:0;;::::1;::::0;111830;;::::1;::::0;111713:17:::1;::::0;111822:6;;111868:25:::1;::::0;2899:18:1;;111868:40:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;111939;::::0;-1:-1:-1;;;111939:40:0;;111973:4:::1;111939:40;::::0;::::1;2926:51:1::0;111848:60:0;;-1:-1:-1;111919:17:0::1;::::0;-1:-1:-1;;;;;111939:25:0;::::1;::::0;::::1;::::0;2899:18:1;;111939:40:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;112029:4;111990:18;51196::::0;;;;;;;;;;;51012:12;;111919:60;;-1:-1:-1;51196:18:0;51012:12;112184:22:::1;112197:9:::0;51196:18;112184:22:::1;:::i;:::-;112183:39;;;;:::i;:::-;112173:49:::0;-1:-1:-1;112318:12:0;112292:22:::1;112305:9:::0;112292:10;:22:::1;:::i;:::-;112291:39;;;;:::i;:::-;112281:49:::0;-1:-1:-1;112393:12:0;;;:28:::1;;-1:-1:-1::0;112409:12:0;;112393:28:::1;112389:70;;;112430:29;;-1:-1:-1::0;;;112430:29:0::1;;;;;;;;;;;112389:70;112470:32;112484:4;112491:10;112470:5;:32::i;:::-;112513:41;-1:-1:-1::0;;;;;112513:28:0;::::1;112542:2:::0;112546:7;112513:28:::1;:41::i;:::-;112565;-1:-1:-1::0;;;;;112565:28:0;::::1;112594:2:::0;112598:7;112565:28:::1;:41::i;:::-;112629:40;::::0;-1:-1:-1;;;112629:40:0;;112663:4:::1;112629:40;::::0;::::1;2926:51:1::0;-1:-1:-1;;;;;112629:25:0;::::1;::::0;::::1;::::0;2899:18:1;;112629:40:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;112692;::::0;-1:-1:-1;;;112692:40:0;;112726:4:::1;112692:40;::::0;::::1;2926:51:1::0;112617:52:0;;-1:-1:-1;;;;;;112692:25:0;::::1;::::0;::::1;::::0;2899:18:1;;112692:40:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;112680:52;;112745:51;112753:9;112764;112775;112786;112745:7;:51::i;:::-;112812:40;::::0;;7767:25:1;;;7823:2;7808:18;;7801:34;;;-1:-1:-1;;;;;112812:40:0;::::1;::::0;29012:10;;112812:40:::1;::::0;7740:18:1;112812:40:0::1;;;;;;;111701:1159;;;;;;;;44489:20:::0;43883:1;45009:7;:22;44826:213;44489:20;111610:1250;;;:::o;102287:131::-;102335:18;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;102335:18:0;102373:12;102386:19;;:23;;102408:1;;102386:23;:::i;:::-;102373:37;;;;;;;;:::i;:::-;;;;;;;;;;;102366:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102287:131;:::o;120577:96::-;120625:13;120658:7;120651:14;;;;;:::i;108116:449::-;108210:17;108240:24;108267:41;108274:7;108283:8;108293:11;108306:1;108267:6;:41::i;:::-;108378:14;;108240:68;;-1:-1:-1;108319:30:0;;;108403:101;108427:7;108423:1;:11;108403:101;;;108482:7;108490:1;108482:10;;;;;;;;:::i;:::-;;;;;;;108456:36;;;;;:::i;:::-;;-1:-1:-1;108436:3:0;;;;:::i;:::-;;;;108403:101;;;-1:-1:-1;108521:36:0;108546:11;108521:22;:36;:::i;:::-;108514:43;108116:449;-1:-1:-1;;;;;;;108116:449:0:o;54347:436::-;54440:4;29012:10;54440:4;54523:25;29012:10;54540:7;54523:9;:25::i;:::-;54496:52;;54587:15;54567:16;:35;;54559:85;;;;-1:-1:-1;;;54559:85:0;;14906:2:1;54559:85:0;;;14888:21:1;14945:2;14925:18;;;14918:30;14984:34;14964:18;;;14957:62;-1:-1:-1;;;15035:18:1;;;15028:35;15080:19;;54559:85:0;;;;;;;;;54680:60;54689:5;54696:7;54724:15;54705:16;:34;54680:8;:60::i;:::-;-1:-1:-1;54771:4:0;;54347:436;-1:-1:-1;;;;54347:436:0:o;51428:193::-;51507:4;29012:10;51563:28;29012:10;51580:2;51584:6;51563:9;:28::i;101982:183::-;102072:6;;;;;;;;;-1:-1:-1;;;;;102072:6:0;-1:-1:-1;;;;;102065:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;102051:47:0;:10;-1:-1:-1;;;;;102051:47:0;;102047:81;;102107:21;;-1:-1:-1;;;102107:21:0;;;;;;;;;;;102047:81;102139:7;:18;102149:8;;102139:7;:18;:::i;:::-;;101982:183;;:::o;115645:316::-;44445:21;:19;:21::i;:::-;115742:6:::1;::::0;115750::::1;::::0;115845:8:::1;::::0;115801:40:::1;::::0;-1:-1:-1;;;115801:40:0;;115835:4:::1;115801:40;::::0;::::1;2926:51:1::0;-1:-1:-1;;;;;115742:6:0;;::::1;::::0;115750;;::::1;::::0;115768:87:::1;::::0;115797:2;;115742:6;;115801:25:::1;::::0;2899:18:1;;115801:40:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:53;;;;:::i;:::-;-1:-1:-1::0;;;;;115768:28:0;::::1;::::0;:87;:28:::1;:87::i;:::-;115943:8;::::0;115899:40:::1;::::0;-1:-1:-1;;;115899:40:0;;115933:4:::1;115899:40;::::0;::::1;2926:51:1::0;115866:87:0::1;::::0;115895:2;;-1:-1:-1;;;;;115899:25:0;::::1;::::0;::::1;::::0;2899:18:1;;115899:40:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:53;;;;:::i;:::-;-1:-1:-1::0;;;;;115866:28:0;::::1;::::0;:87;:28:::1;:87::i;:::-;115693:268;;44489:20:::0;43883:1;45009:7;:22;44826:213;44489:20;115645:316;:::o;101799:175::-;101885:6;;;;;;;;;-1:-1:-1;;;;;101885:6:0;-1:-1:-1;;;;;101878:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;101864:47:0;:10;-1:-1:-1;;;;;101864:47:0;;101860:81;;101920:21;;-1:-1:-1;;;101920:21:0;;;;;;;;;;;101860:81;101952:5;:14;101960:6;;101952:5;:14;:::i;102881:505::-;102920:16;;29012:10;103007:18;29012:10;103007;:18::i;:::-;-1:-1:-1;;;;;103049:18:0;;;;;;:10;:18;;;;;;;;;103089:10;:18;;;;;;;103049;;-1:-1:-1;103089:18:0;-1:-1:-1;103124:12:0;;;;:28;;;103151:1;103140:8;:12;103124:28;103120:259;;;-1:-1:-1;;;;;103169:18:0;;;103190:1;103169:18;;;:10;:18;;;;;;;;:22;;;103206:10;:18;;;;;;:22;;;;103254:8;;103245:59;;-1:-1:-1;;;103245:59:0;;;;;17626:51:1;;;;17693:18;;;17686:34;;;17736:18;;;17729:34;;;103254:8:0;;;;103245:31;;17599:18:1;;103245:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;103326:41:0;;;7767:25:1;;;7823:2;7808:18;;7801:34;;;-1:-1:-1;;;;;103326:41:0;;;-1:-1:-1;103326:41:0;;-1:-1:-1;103326:41:0;;7740:18:1;103326:41:0;;;;;;;103120:259;102956:430;102881:505;;:::o;62451:645::-;62695:8;62676:15;:27;;62668:69;;;;-1:-1:-1;;;62668:69:0;;17976:2:1;62668:69:0;;;17958:21:1;18015:2;17995:18;;;17988:30;18054:31;18034:18;;;18027:59;18103:18;;62668:69:0;17774:353:1;62668:69:0;62750:18;61626:95;62810:5;62817:7;62826:5;62833:16;62843:5;62833:9;:16::i;:::-;62781:79;;;;;;18419:25:1;;;;-1:-1:-1;;;;;18518:15:1;;;18498:18;;;18491:43;18570:15;;;;18550:18;;;18543:43;18602:18;;;18595:34;18645:19;;;18638:35;18689:19;;;18682:35;;;18391:19;;62781:79:0;;;;;;;;;;;;62771:90;;;;;;62750:111;;62874:12;62889:28;62906:10;62889:16;:28::i;:::-;62874:43;;62930:14;62947:28;62961:4;62967:1;62970;62973;62947:13;:28::i;:::-;62930:45;;63004:5;-1:-1:-1;;;;;62994:15:0;:6;-1:-1:-1;;;;;62994:15:0;;62986:58;;;;-1:-1:-1;;;62986:58:0;;18930:2:1;62986:58:0;;;18912:21:1;18969:2;18949:18;;;18942:30;19008:32;18988:18;;;18981:60;19058:18;;62986:58:0;18728:354:1;62986:58:0;63057:31;63066:5;63073:7;63082:5;63057:8;:31::i;:::-;62657:439;;;62451:645;;;;;;;:::o;51684:151::-;-1:-1:-1;;;;;51800:18:0;;;51773:7;51800:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;51684:151::o;100743:1048::-;100835:7;;-1:-1:-1;;;;;100835:7:0;:21;100831:53;;100865:19;;-1:-1:-1;;;100865:19:0;;;;;;;;;;;100831:53;100895:7;:22;;-1:-1:-1;;;;;;100895:22:0;29012:10;100895:22;;;;;;100937:29;;;-1:-1:-1;;;100937:29:0;;;;:27;;:29;;;;;;;;;;;;;;;29012:10;100937:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;100928:6;:38;;-1:-1:-1;;;;;100928:38:0;;;-1:-1:-1;;;;;;100977:54:0;;;;-1:-1:-1;;;100977:54:0;;;;;;;100986:6;100977:54;;-1:-1:-1;;;;;;100977:54:0;;;;;;;;;;100978:6;100977:54;;;;;;;;;;;;;;101061:30;;100977:54;;;;101061:30;;;:::i;:::-;-1:-1:-1;;;;;8449:15:1;;;8431:34;;8501:15;;8496:2;8481:18;;8474:43;8381:2;8366:18;101061:30:0;;;;;;;;;;;;;;;;;;;;;;;101042:8;;:50;;;;;-1:-1:-1;;;;;101042:50:0;;;;;-1:-1:-1;;;;;101042:50:0;;;;;;101103:21;101133:7;-1:-1:-1;;;;;101127:21:0;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;101127:23:0;;;;;;;;;;;;:::i;:::-;101103:47;;101161:21;101191:7;-1:-1:-1;;;;;101185:21:0;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;101185:23:0;;;;;;;;;;;;:::i;:::-;101161:47;;101223:7;101219:389;;;101298:7;101312;101262:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;101247:5;:74;;;;;;:::i;:::-;;101381:7;101395;101353:50;;;;;;;;;:::i;:::-;;;;;;;;;;;;;101336:7;:68;;;;;;:::i;:::-;;101219:389;;;101490:7;101504;101452:60;;;;;;;;;:::i;:::-;;;;;;;;;;;;;101437:5;:76;;;;;;:::i;:::-;;101573:7;101587;101545:50;;;;;;;;;:::i;:::-;;;;;;;;;;;;;101528:7;:68;;;;;;:::i;:::-;;101219:389;101644:7;-1:-1:-1;;;;;101638:23:0;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;101632:31;;:2;:31;:::i;:::-;101620:9;:43;;;;101698:7;-1:-1:-1;;;;;101692:23:0;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;101686:31;;:2;:31;:::i;:::-;101674:9;:43;-1:-1:-1;;101748:34:0;;;;;;;;101760:15;101748:34;;-1:-1:-1;101748:34:0;;;;;;;;;;;;101730:12;:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;100743:1048:0:o;118494:371::-;118636:8;;118646;;118703:7;;118734:6;;118690:51;;-1:-1:-1;;;118690:51:0;;118727:4;118690:51;;;12741::1;-1:-1:-1;;;118734:6:0;;;;;12835:14:1;12828:22;12808:18;;;12801:50;118574:7:0;;118636:8;118646;118745:5;;-1:-1:-1;;;;;118703:7:0;;;;118690:28;;12714:18:1;;118690:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;118679:62;;:8;:62;:::i;:::-;118678:72;;;;:::i;:::-;118666:84;;;;:::i;:::-;;;118803:54;118817:8;118827:7;118836:9;118847;118803:13;:54::i;:::-;118796:61;118494:371;-1:-1:-1;;;;;118494:371:0:o;116010:166::-;44445:21;:19;:21::i;:::-;116074:6:::1;::::0;116067:39:::1;::::0;-1:-1:-1;;;116067:39:0;;116100:4:::1;116067:39;::::0;::::1;2926:51:1::0;116059:109:0::1;::::0;-1:-1:-1;;;;;116074:6:0::1;::::0;116067:24:::1;::::0;2899:18:1;;116067:39:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;116115:6;::::0;116108:39:::1;::::0;-1:-1:-1;;;116108:39:0;;116141:4:::1;116108:39;::::0;::::1;2926:51:1::0;-1:-1:-1;;;;;116115:6:0;;::::1;::::0;116108:24:::1;::::0;2899:18:1;;116108:39:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;116149:8;;116159;;116059:7;:109::i;:::-;44489:20:::0;43883:1;45009:7;:22;44826:213;44489:20;116010:166::o;44525:293::-;43927:1;44659:7;;:19;44651:63;;;;-1:-1:-1;;;44651:63:0;;26333:2:1;44651:63:0;;;26315:21:1;26372:2;26352:18;;;26345:30;26411:33;26391:18;;;26384:61;26462:18;;44651:63:0;26131:355:1;44651:63:0;43927:1;44792:7;:18;44525:293::o;64527:177::-;64637:58;;;-1:-1:-1;;;;;26683:32:1;;64637:58:0;;;26665:51:1;26732:18;;;;26725:34;;;64637:58:0;;;;;;;;;;26638:18:1;;;;64637:58:0;;;;;;;;-1:-1:-1;;;;;64637:58:0;-1:-1:-1;;;64637:58:0;;;64610:86;;64630:5;;64610:19;:86::i;103424:449::-;103537:6;103547:1;103537:11;103533:24;;103424:449;:::o;103533:24::-;103595:8;;103574:6;;103567:45;;-1:-1:-1;;;;;103574:6:0;;;;103595:8;103605:6;103567:27;:45::i;:::-;103660:14;103695:13;51012:12;;;50924:108;103695:13;103678;:6;103687:4;103678:13;:::i;:::-;103677:31;;;;:::i;:::-;103660:48;-1:-1:-1;103766:10:0;;103762:59;;103803:6;103793;;:16;;;;;;;:::i;:::-;;;;-1:-1:-1;;103762:59:0;103836:29;;;7767:25:1;;;103863:1:0;7823:2:1;7808:18;;7801:34;29012:10:0;;103836:29;;7740:18:1;103836:29:0;;;;;;;;103467:406;103424:449;:::o;103911:369::-;104024:6;104034:1;104024:11;104020:24;;103911:369;:::o;104020:24::-;104082:8;;104061:6;;104054:45;;-1:-1:-1;;;;;104061:6:0;;;;104082:8;104092:6;104054:27;:45::i;:::-;104110:14;104145:13;51012:12;;;50924:108;104145:13;104128;:6;104137:4;104128:13;:::i;:::-;104127:31;;;;:::i;:::-;104110:48;-1:-1:-1;104173:10:0;;104169:59;;104210:6;104200;;:16;;;;;;;:::i;:::-;;;;-1:-1:-1;;104169:59:0;104243:29;;;104262:1;7767:25:1;;7823:2;7808:18;;7801:34;;;29012:10:0;;104243:29;;7740:18:1;104243:29:0;7593:248:1;119851:427:0;119932:6;;119908:7;;-1:-1:-1;;;119932:6:0;;;;119928:343;;;119981:9;;119955:10;;119969:8;:1;119973:4;119969:8;:::i;:::-;119968:22;;;;:::i;:::-;119955:35;;120005:10;120031:9;;120019:1;120023:4;120019:8;;;;:::i;:::-;120018:22;;;;:::i;:::-;120005:35;-1:-1:-1;120055:10:0;120080:4;120069:7;120005:35;120069:2;:7;:::i;:::-;120068:16;;;;:::i;:::-;120055:29;-1:-1:-1;120099:10:0;120144:4;120133:7;120138:2;;120133:7;:::i;:::-;120132:16;;;;:::i;:::-;120125:4;120114:7;120119:2;;120114:7;:::i;:::-;120113:16;;;;:::i;:::-;:35;;;;:::i;:::-;120099:50;-1:-1:-1;120183:4:0;120172:7;120099:50;120172:2;:7;:::i;:::-;120171:16;;;;:::i;:::-;120164:23;;;;;;;;119928:343;120243:5;120247:1;120243;:5;:::i;:::-;120236:12;;;;106123:960;106324:18;;106259:15;;106234:22;;106307:35;;106259:15;106307:35;:::i;:::-;106285:57;;106371:1;106357:11;:15;:33;;;;-1:-1:-1;106376:14:0;;;106357:33;:51;;;;-1:-1:-1;106394:14:0;;;106357:51;106353:197;;;106451:23;106463:11;106451:9;:23;:::i;:::-;106425:22;;:49;;;;;;;:::i;:::-;;;;-1:-1:-1;106515:23:0;;-1:-1:-1;106527:11:0;106515:9;:23;:::i;:::-;106489:22;;:49;;;;;;;:::i;:::-;;;;-1:-1:-1;;106353:197:0;106562:25;106590:17;:15;:17::i;:::-;106649:16;;106562:45;;-1:-1:-1;106632:33:0;;:14;:33;:::i;:::-;106618:47;;99693:4;106783:11;:24;106779:151;;;106842:75;;;;;;;;;;;106870:22;;106842:75;;;;;;106894:22;;106842:75;;;;;;106824:12;:94;;;;;;;-1:-1:-1;106824:94:0;;;;;;;;;;;;;;;;;;;;;;;;;;;106779:151;106940:8;:19;;;106970:8;:19;;;107000:18;:35;;;107051:24;;;7767:25:1;;;7823:2;7808:18;;7801:34;;;107051:24:0;;7740:18:1;107051:24:0;;;;;;;106223:860;;;106123:960;;;;:::o;58340:346::-;-1:-1:-1;;;;;58442:19:0;;58434:68;;;;-1:-1:-1;;;58434:68:0;;27494:2:1;58434:68:0;;;27476:21:1;27533:2;27513:18;;;27506:30;27572:34;27552:18;;;27545:62;-1:-1:-1;;;27623:18:1;;;27616:34;27667:19;;58434:68:0;27292:400:1;58434:68:0;-1:-1:-1;;;;;58521:21:0;;58513:68;;;;-1:-1:-1;;;58513:68:0;;27899:2:1;58513:68:0;;;27881:21:1;27938:2;27918:18;;;27911:30;27977:34;27957:18;;;27950:62;-1:-1:-1;;;28028:18:1;;;28021:32;28070:19;;58513:68:0;27697:398:1;58513:68:0;-1:-1:-1;;;;;58594:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;58646:32;;4297:25:1;;;58646:32:0;;4270:18:1;58646:32:0;;;;;;;58340:346;;;:::o;118873:970::-;119059:6;;119035:7;;-1:-1:-1;;;119059:6:0;;;;119055:781;;;119082:10;119095:24;119098:9;119109;119095:2;:24::i;:::-;119167:9;;119082:37;;-1:-1:-1;119147:16:0;:9;119159:4;119147:16;:::i;:::-;119146:30;;;;:::i;:::-;119224:9;;119134:42;;-1:-1:-1;119204:16:0;:9;119216:4;119204:16;:::i;:::-;119203:30;;;;:::i;:::-;119298:6;;119191:42;;-1:-1:-1;119249:16:0;;;;-1:-1:-1;;;;;119287:17:0;;;119298:6;;119287:17;:67;;119333:9;119344;119287:67;;;119308:9;119319;119287:67;119391:6;;119248:106;;-1:-1:-1;119248:106:0;-1:-1:-1;;;;;;119380:17:0;;;119391:6;;119380:17;:81;;119452:9;;119433:15;:8;119444:4;119433:15;:::i;:::-;119432:29;;;;:::i;:::-;119380:81;;;119420:9;;119401:15;:8;119412:4;119401:15;:::i;:::-;119400:29;;;;:::i;:::-;119369:92;-1:-1:-1;119476:9:0;119499:41;119506:19;119517:8;119369:92;119506:19;:::i;:::-;119527:2;119531:8;119499:6;:41::i;:::-;119488:52;;:8;:52;:::i;:::-;119579:6;;119476:64;;-1:-1:-1;119614:4:0;;-1:-1:-1;;;;;119568:17:0;;;119579:6;;119568:17;:41;;119600:9;;119568:41;;;119588:9;;119568:41;119563:47;;:1;:47;:::i;:::-;119562:56;;;;:::i;:::-;119555:63;;;;;;;;119055:781;119701:6;;119652:16;;;;-1:-1:-1;;;;;119690:17:0;;;119701:6;;119690:17;:67;;119736:9;119747;119690:67;;;119711:9;119722;119690:67;119651:106;;-1:-1:-1;119651:106:0;-1:-1:-1;119804:19:0;119815:8;119651:106;119804:19;:::i;:::-;119780;119791:8;119780;:19;:::i;:::-;119779:45;;;;:::i;:::-;119772:52;;;;;;58977:419;59078:24;59105:25;59115:5;59122:7;59105:9;:25::i;:::-;59078:52;;-1:-1:-1;;59145:16:0;:37;59141:248;;59227:6;59207:16;:26;;59199:68;;;;-1:-1:-1;;;59199:68:0;;28302:2:1;59199:68:0;;;28284:21:1;28341:2;28321:18;;;28314:30;28380:31;28360:18;;;28353:59;28429:18;;59199:68:0;28100:353:1;59199:68:0;59311:51;59320:5;59327:7;59355:6;59336:16;:25;59311:8;:51::i;:::-;59067:329;58977:419;;;:::o;55253:806::-;-1:-1:-1;;;;;55350:18:0;;55342:68;;;;-1:-1:-1;;;55342:68:0;;28660:2:1;55342:68:0;;;28642:21:1;28699:2;28679:18;;;28672:30;28738:34;28718:18;;;28711:62;-1:-1:-1;;;28789:18:1;;;28782:35;28834:19;;55342:68:0;28458:401:1;55342:68:0;-1:-1:-1;;;;;55429:16:0;;55421:64;;;;-1:-1:-1;;;55421:64:0;;29066:2:1;55421:64:0;;;29048:21:1;29105:2;29085:18;;;29078:30;29144:34;29124:18;;;29117:62;-1:-1:-1;;;29195:18:1;;;29188:33;29238:19;;55421:64:0;28864:399:1;55421:64:0;55498:38;55519:4;55525:2;55529:6;55498:20;:38::i;:::-;-1:-1:-1;;;;;55571:15:0;;55549:19;55571:15;;;;;;;;;;;55605:21;;;;55597:72;;;;-1:-1:-1;;;55597:72:0;;29470:2:1;55597:72:0;;;29452:21:1;29509:2;29489:18;;;29482:30;29548:34;29528:18;;;29521:62;-1:-1:-1;;;29599:18:1;;;29592:36;29645:19;;55597:72:0;29268:402:1;55597:72:0;-1:-1:-1;;;;;55705:15:0;;;:9;:15;;;;;;;;;;;55723:20;;;55705:38;;55923:13;;;;;;;;;;:23;;;;;;55975:26;;4297:25:1;;;55923:13:0;;55975:26;;4270:18:1;55975:26:0;;;;;;;56014:37;101982:183;17028:268;17081:7;17113:4;-1:-1:-1;;;;;17122:11:0;17105:28;;:63;;;;;17154:14;17137:13;:31;17105:63;17101:188;;;-1:-1:-1;17192:22:0;;17028:268::o;17101:188::-;17254:23;17396:81;;;15127:95;17396:81;;;31840:25:1;17419:11:0;31881:18:1;;;31874:34;;;;17432:14:0;31924:18:1;;;31917:34;17448:13:0;31967:18:1;;;31960:34;17471:4:0;32010:19:1;;;32003:61;17359:7:0;;31812:19:1;;17396:81:0;;;;;;;;;;;;17386:92;;;;;;17379:99;;17304:182;;90188:1673;90236:7;90260:1;90265;90260:6;90256:47;;-1:-1:-1;90290:1:0;;90188:1673;-1:-1:-1;90188:1673:0:o;90256:47::-;90994:14;91028:1;91017:7;91022:1;91017:4;:7::i;:::-;:12;;91011:1;:19;;90994:36;;91496:1;91485:6;91481:1;:10;;;;;:::i;:::-;;91472:6;:19;91471:26;;91462:35;;91546:1;91535:6;91531:1;:10;;;;;:::i;:::-;;91522:6;:19;91521:26;;91512:35;;91596:1;91585:6;91581:1;:10;;;;;:::i;:::-;;91572:6;:19;91571:26;;91562:35;;91646:1;91635:6;91631:1;:10;;;;;:::i;:::-;;91622:6;:19;91621:26;;91612:35;;91696:1;91685:6;91681:1;:10;;;;;:::i;:::-;;91672:6;:19;91671:26;;91662:35;;91746:1;91735:6;91731:1;:10;;;;;:::i;:::-;;91722:6;:19;91721:26;;91712:35;;91796:1;91785:6;91781:1;:10;;;;;:::i;:::-;;91772:6;:19;91771:26;;91762:35;;91819:23;91823:6;91835;91831:1;:10;;;;;:::i;:::-;;91819:3;:23::i;56346:548::-;-1:-1:-1;;;;;56430:21:0;;56422:65;;;;-1:-1:-1;;;56422:65:0;;29877:2:1;56422:65:0;;;29859:21:1;29916:2;29896:18;;;29889:30;29955:33;29935:18;;;29928:61;30006:18;;56422:65:0;29675:355:1;56422:65:0;56500:49;56529:1;56533:7;56542:6;56500:20;:49::i;:::-;56578:6;56562:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;56733:18:0;;:9;:18;;;;;;;;;;;:28;;;;;;56788:37;4297:25:1;;;56788:37:0;;4270:18:1;56788:37:0;;;;;;;56346:548;;:::o;84416:106::-;84474:7;84505:1;84501;:5;:13;;84513:1;84501:13;;;-1:-1:-1;84509:1:0;;84494:20;-1:-1:-1;84416:106:0:o;8156:244::-;8250:13;7558:4;7522:40;;8280:17;8276:117;;8321:15;8330:5;8321:8;:15::i;8276:117::-;8376:5;8369:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57227:675;-1:-1:-1;;;;;57311:21:0;;57303:67;;;;-1:-1:-1;;;57303:67:0;;30237:2:1;57303:67:0;;;30219:21:1;30276:2;30256:18;;;30249:30;30315:34;30295:18;;;30288:62;-1:-1:-1;;;30366:18:1;;;30359:31;30407:19;;57303:67:0;30035:397:1;57303:67:0;57383:49;57404:7;57421:1;57425:6;57383:20;:49::i;:::-;-1:-1:-1;;;;;57470:18:0;;57445:22;57470:18;;;;;;;;;;;57507:24;;;;57499:71;;;;-1:-1:-1;;;57499:71:0;;30639:2:1;57499:71:0;;;30621:21:1;30678:2;30658:18;;;30651:30;30717:34;30697:18;;;30690:62;-1:-1:-1;;;30768:18:1;;;30761:32;30810:19;;57499:71:0;30437:398:1;57499:71:0;-1:-1:-1;;;;;57606:18:0;;:9;:18;;;;;;;;;;;57627:23;;;57606:44;;57745:12;:22;;;;;;;57796:37;4297:25:1;;;57606:9:0;;:18;57796:37;;4270:18:1;57796:37:0;;;;;;;102139:18;101982:183;;:::o;104481:1317::-;-1:-1:-1;;;;;51196:18:0;;104540:17;51196:18;;;;;;;;;;;104628:13;;104624:1167;;-1:-1:-1;;;;;104682:23:0;;104658:21;104682:23;;;:12;:23;;;;;;;;;;104786:12;:23;;;;;;;;104842:6;;104923;;104944:33;;;;105043:23;;;;:33;;;104682:23;105109;104682;104842:6;105109:23;:::i;:::-;105091:41;-1:-1:-1;105205:15:0;105223:23;105233:13;105223:7;:23;:::i;:::-;105205:41;-1:-1:-1;105265:11:0;;105261:197;;105297:14;105338:4;105315:19;105327:7;105315:9;:19;:::i;:::-;105314:28;;;;:::i;:::-;-1:-1:-1;;;;;105411:21:0;;;;;;:10;:21;;;;;:31;;105297:45;;-1:-1:-1;105297:45:0;;105411:21;;;:31;;105297:45;;105411:31;:::i;:::-;;;;-1:-1:-1;;;105261:197:0;105476:11;;105472:147;;105508:14;105549:4;105526:19;105538:7;105526:9;:19;:::i;:::-;105525:28;;;;:::i;:::-;-1:-1:-1;;;;;105572:21:0;;;;;;:10;:21;;;;;:31;;105508:45;;-1:-1:-1;105508:45:0;;105572:21;;;:31;;105508:45;;105572:31;:::i;:::-;;;;-1:-1:-1;;;105472:147:0;104643:987;;;;;;56346:548;;:::o;104624:1167::-;105677:6;;-1:-1:-1;;;;;105651:23:0;;;;;;:12;:23;;;;;;;;:32;;;;105773:6;;105747:12;:23;;;;;;:32;104529:1269;104481:1317;:::o;63673:207::-;-1:-1:-1;;;;;63794:14:0;;63733:15;63794:14;;;:7;:14;;;;;12092;;12229:1;12211:19;;;;12092:14;63855:17;63750:130;63673:207;;;:::o;18128:167::-;18205:7;18232:55;18254:20;:18;:20::i;:::-;18276:10;27692:4;27686:11;-1:-1:-1;;;27711:23:0;;27764:4;27755:14;;27748:39;;;;27817:4;27808:14;;27801:34;27872:4;27857:20;;;27489:406;25705:236;25790:7;25811:17;25830:18;25852:25;25863:4;25869:1;25872;25875;25852:10;:25::i;:::-;25810:67;;;;25888:18;25900:5;25888:11;:18::i;:::-;-1:-1:-1;25924:9:0;25705:236;-1:-1:-1;;;;;25705:236:0:o;67415:716::-;67839:23;67865:69;67893:4;67865:69;;;;;;;;;;;;;;;;;67873:5;-1:-1:-1;;;;;67865:27:0;;;:69;;;;;:::i;:::-;67949:17;;67839:95;;-1:-1:-1;67949:21:0;67945:179;;68046:10;68035:30;;;;;;;;;;;;:::i;:::-;68027:85;;;;-1:-1:-1;;;68027:85:0;;31042:2:1;68027:85:0;;;31024:21:1;31081:2;31061:18;;;31054:30;31120:34;31100:18;;;31093:62;-1:-1:-1;;;31171:18:1;;;31164:40;31221:19;;68027:85:0;30840:406:1;116571:1915:0;116645:7;;116665:1791;116689:3;116685:1;:7;116665:1791;;;116714:9;116726;116729:2;116733:1;116726:2;:9::i;:::-;116714:21;;116758:2;116754:1;:6;116750:1695;;;117116:10;117149:9;117152:2;117156:1;117149:2;:9::i;:::-;117131:6;117136:1;117131:2;:6;:::i;:::-;117130:15;;117141:4;117130:15;:::i;:::-;117129:29;;;;:::i;:::-;117116:42;;117181:2;117187:1;117181:7;117177:487;;117222:2;117217:1;:7;117213:138;;117326:1;117319:8;;;;;;;117213:138;117393:2;117377:13;117380:2;117384:5;:1;117388;117384:5;:::i;:::-;117377:2;:13::i;:::-;:18;117373:243;;;117587:5;:1;117591;117587:5;:::i;:::-;117580:12;;;;;;;117373:243;-1:-1:-1;117643:1:0;117177:487;117686:6;117690:2;117686:1;:6;:::i;:::-;117682:10;;116762:946;116750:1695;;;117733:10;117766:9;117769:2;117773:1;117766:2;:9::i;:::-;117748:6;117752:2;117748:1;:6;:::i;:::-;117747:15;;117758:4;117747:15;:::i;:::-;117746:29;;;;:::i;:::-;117733:42;;117798:2;117804:1;117798:7;117794:607;;117839:2;117834:1;:7;:29;;;-1:-1:-1;117861:2:0;117845:13;117848:2;117852:5;117856:1;117852;:5;:::i;:::-;117845:2;:13::i;:::-;:18;117834:29;117830:523;;;118328:1;118321:8;;;;;;;117830:523;-1:-1:-1;118380:1:0;117794:607;118423:6;118427:2;118423:1;:6;:::i;:::-;118419:10;;117714:731;116750:1695;-1:-1:-1;116694:3:0;;;;:::i;:::-;;;;116665:1791;;;-1:-1:-1;118466:12:0;;-1:-1:-1;;;118466:12:0;;31453:2:1;118466:12:0;;;31435:21:1;31492:1;31472:18;;;31465:29;-1:-1:-1;;;31510:18:1;;;31503:32;31552:18;;118466:12:0;31251:325:1;120681:143:0;120775:16;120786:4;120775:10;:16::i;:::-;120802:14;120813:2;120802:10;:14::i;92338:1019::-;92390:7;;92477:3;92468:12;;;:16;92464:102;;92515:3;92505:13;;;;92537;92464:102;92593:2;92584:11;;;:15;92580:99;;92630:2;92620:12;;;;92651;92580:99;92706:2;92697:11;;;:15;92693:99;;92743:2;92733:12;;;;92764;92693:99;92819:2;92810:11;;;:15;92806:99;;92856:2;92846:12;;;;92877;92806:99;92932:1;92923:10;;;:14;92919:96;;92968:1;92958:11;;;;92988;92919:96;93042:1;93033:10;;;:14;93029:96;;93078:1;93068:11;;;;93098;93029:96;93152:1;93143:10;;;:14;93139:96;;93188:1;93178:11;;;;93208;93139:96;93262:1;93253:10;;;:14;93249:66;;93298:1;93288:11;93343:6;92338:1019;-1:-1:-1;;92338:1019:0:o;6950:411::-;7171:14;;;7182:2;7171:14;;;;;;;;;7009:13;;7558:4;7522:40;;;7035:11;;7171:14;;;7182:2;;7171:14;;;-1:-1:-1;;;7264:16:0;;;-1:-1:-1;7310:4:0;7301:14;;7294:28;;;;-1:-1:-1;7264:16:0;6950:411::o;24089:1477::-;24177:7;;25111:66;25098:79;;25094:163;;;-1:-1:-1;25210:1:0;;-1:-1:-1;25214:30:0;25194:51;;25094:163;25371:24;;;25354:14;25371:24;;;;;;;;;32302:25:1;;;32375:4;32363:17;;32343:18;;;32336:45;;;;32397:18;;;32390:34;;;32440:18;;;32433:34;;;25371:24:0;;32274:19:1;;25371:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;25371:24:0;;-1:-1:-1;;25371:24:0;;;-1:-1:-1;;;;;;;25410:20:0;;25406:103;;25463:1;25467:29;25447:50;;;;;;;25406:103;25529:6;-1:-1:-1;25537:20:0;;-1:-1:-1;24089:1477:0;;;;;;;;:::o;19549:521::-;19627:20;19618:5;:29;;;;;;;;:::i;:::-;;19614:449;;19549:521;:::o;19614:449::-;19725:29;19716:5;:38;;;;;;;;:::i;:::-;;19712:351;;19771:34;;-1:-1:-1;;;19771:34:0;;32812:2:1;19771:34:0;;;32794:21:1;32851:2;32831:18;;;32824:30;32890:26;32870:18;;;32863:54;32934:18;;19771:34:0;32610:348:1;19712:351:0;19836:35;19827:5;:44;;;;;;;;:::i;:::-;;19823:240;;19888:41;;-1:-1:-1;;;19888:41:0;;33165:2:1;19888:41:0;;;33147:21:1;33204:2;33184:18;;;33177:30;33243:33;33223:18;;;33216:61;33294:18;;19888:41:0;32963:355:1;19823:240:0;19960:30;19951:5;:39;;;;;;;;:::i;:::-;;19947:116;;20007:44;;-1:-1:-1;;;20007:44:0;;33525:2:1;20007:44:0;;;33507:21:1;33564:2;33544:18;;;33537:30;33603:34;33583:18;;;33576:62;-1:-1:-1;;;33654:18:1;;;33647:32;33696:19;;20007:44:0;33323:398:1;36763:229:0;36900:12;36932:52;36954:6;36962:4;36968:1;36971:12;36932:21;:52::i;116184:207::-;116242:7;;116286:4;116276:6;116281:1;116276:2;:6;:::i;:::-;116275:15;;;;:::i;:::-;116262:28;-1:-1:-1;116301:10:0;116344:4;116335:5;116339:1;;116335:5;:::i;:::-;116334:14;;;;:::i;:::-;116327:4;116316:7;116321:2;;116316:7;:::i;:::-;116315:16;;;;:::i;:::-;:33;;;;:::i;:::-;116301:48;-1:-1:-1;116379:4:0;116368:7;116301:48;116368:2;:7;:::i;:::-;116367:16;;;;:::i;116399:164::-;116457:7;116550:4;116544:2;116550:4;116525:7;116544:2;;116525:7;:::i;:::-;116524:16;;;;:::i;:::-;116523:23;;;;:::i;:::-;116522:32;;;;:::i;:::-;116514:4;;116496:5;116500:1;;116496:5;:::i;:::-;116495:14;;;;:::i;:::-;116485:6;116489:2;116485:1;:6;:::i;:::-;:25;;;;:::i;:::-;116484:34;;;;:::i;:::-;:71;;;;:::i;37849:455::-;38019:12;38077:5;38052:21;:30;;38044:81;;;;-1:-1:-1;;;38044:81:0;;33928:2:1;38044:81:0;;;33910:21:1;33967:2;33947:18;;;33940:30;34006:34;33986:18;;;33979:62;-1:-1:-1;;;34057:18:1;;;34050:36;34103:19;;38044:81:0;33726:402:1;38044:81:0;38137:12;38151:23;38178:6;-1:-1:-1;;;;;38178:11:0;38197:5;38204:4;38178:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38136:73;;;;38227:69;38254:6;38262:7;38271:10;38283:12;40607;40636:7;40632:427;;;40664:10;:17;40685:1;40664:22;40660:290;;-1:-1:-1;;;;;34302:19:0;;;40874:60;;;;-1:-1:-1;;;40874:60:0;;34627:2:1;40874:60:0;;;34609:21:1;34666:2;34646:18;;;34639:30;34705:31;34685:18;;;34678:59;34754:18;;40874:60:0;34425:353:1;40874:60:0;-1:-1:-1;40971:10:0;40964:17;;40632:427;41014:33;41022:10;41034:12;41769:17;;:21;41765:388;;42001:10;41995:17;42058:15;42045:10;42041:2;42037:19;42030:44;41765:388;42128:12;42121:20;;-1:-1:-1;;;42121:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;:::o;14:131:1:-;-1:-1:-1;;;;;89:31:1;;79:42;;69:70;;135:1;132;125:12;150:347;201:8;211:6;265:3;258:4;250:6;246:17;242:27;232:55;;283:1;280;273:12;232:55;-1:-1:-1;306:20:1;;349:18;338:30;;335:50;;;381:1;378;371:12;335:50;418:4;410:6;406:17;394:29;;470:3;463:4;454:6;446;442:19;438:30;435:39;432:59;;;487:1;484;477:12;432:59;150:347;;;;;:::o;502:681::-;599:6;607;615;623;631;684:3;672:9;663:7;659:23;655:33;652:53;;;701:1;698;691:12;652:53;737:9;724:23;714:33;;794:2;783:9;779:18;766:32;756:42;;848:2;837:9;833:18;820:32;861:31;886:5;861:31;:::i;:::-;911:5;-1:-1:-1;967:2:1;952:18;;939:32;994:18;983:30;;980:50;;;1026:1;1023;1016:12;980:50;1065:58;1115:7;1106:6;1095:9;1091:22;1065:58;:::i;:::-;502:681;;;;-1:-1:-1;502:681:1;;-1:-1:-1;1142:8:1;;1039:84;502:681;-1:-1:-1;;;502:681:1:o;1188:250::-;1273:1;1283:113;1297:6;1294:1;1291:13;1283:113;;;1373:11;;;1367:18;1354:11;;;1347:39;1319:2;1312:10;1283:113;;;-1:-1:-1;;1430:1:1;1412:16;;1405:27;1188:250::o;1443:271::-;1485:3;1523:5;1517:12;1550:6;1545:3;1538:19;1566:76;1635:6;1628:4;1623:3;1619:14;1612:4;1605:5;1601:16;1566:76;:::i;:::-;1696:2;1675:15;-1:-1:-1;;1671:29:1;1662:39;;;;1703:4;1658:50;;1443:271;-1:-1:-1;;1443:271:1:o;1719:220::-;1868:2;1857:9;1850:21;1831:4;1888:45;1929:2;1918:9;1914:18;1906:6;1888:45;:::i;2268:315::-;2336:6;2344;2397:2;2385:9;2376:7;2372:23;2368:32;2365:52;;;2413:1;2410;2403:12;2365:52;2452:9;2439:23;2471:31;2496:5;2471:31;:::i;:::-;2521:5;2573:2;2558:18;;;;2545:32;;-1:-1:-1;;;2268:315:1:o;2988:452::-;3074:6;3082;3090;3098;3151:3;3139:9;3130:7;3126:23;3122:33;3119:53;;;3168:1;3165;3158:12;3119:53;3207:9;3194:23;3226:31;3251:5;3226:31;:::i;:::-;3276:5;3328:2;3313:18;;3300:32;;-1:-1:-1;3379:2:1;3364:18;;3351:32;;3430:2;3415:18;3402:32;;-1:-1:-1;2988:452:1;-1:-1:-1;;;2988:452:1:o;3445:435::-;3498:3;3536:5;3530:12;3563:6;3558:3;3551:19;3589:4;3618:2;3613:3;3609:12;3602:19;;3655:2;3648:5;3644:14;3676:1;3686:169;3700:6;3697:1;3694:13;3686:169;;;3761:13;;3749:26;;3795:12;;;;3830:15;;;;3722:1;3715:9;3686:169;;;-1:-1:-1;3871:3:1;;3445:435;-1:-1:-1;;;;;3445:435:1:o;3885:261::-;4064:2;4053:9;4046:21;4027:4;4084:56;4136:2;4125:9;4121:18;4113:6;4084:56;:::i;4333:247::-;4392:6;4445:2;4433:9;4424:7;4420:23;4416:32;4413:52;;;4461:1;4458;4451:12;4413:52;4500:9;4487:23;4519:31;4544:5;4519:31;:::i;4585:456::-;4662:6;4670;4678;4731:2;4719:9;4710:7;4706:23;4702:32;4699:52;;;4747:1;4744;4737:12;4699:52;4786:9;4773:23;4805:31;4830:5;4805:31;:::i;:::-;4855:5;-1:-1:-1;4912:2:1;4897:18;;4884:32;4925:33;4884:32;4925:33;:::i;:::-;4585:456;;4977:7;;-1:-1:-1;;;5031:2:1;5016:18;;;;5003:32;;4585:456::o;5046:180::-;5105:6;5158:2;5146:9;5137:7;5133:23;5129:32;5126:52;;;5174:1;5171;5164:12;5126:52;-1:-1:-1;5197:23:1;;5046:180;-1:-1:-1;5046:180:1:o;6280:383::-;6357:6;6365;6373;6426:2;6414:9;6405:7;6401:23;6397:32;6394:52;;;6442:1;6439;6432:12;6394:52;6481:9;6468:23;6500:31;6525:5;6500:31;:::i;:::-;6550:5;6602:2;6587:18;;6574:32;;-1:-1:-1;6653:2:1;6638:18;;;6625:32;;6280:383;-1:-1:-1;;;6280:383:1:o;6668:920::-;7074:3;7069;7065:13;7057:6;7053:26;7042:9;7035:45;7116:3;7111:2;7100:9;7096:18;7089:31;7016:4;7143:46;7184:3;7173:9;7169:19;7161:6;7143:46;:::i;:::-;7237:9;7229:6;7225:22;7220:2;7209:9;7205:18;7198:50;7271:33;7297:6;7289;7271:33;:::i;:::-;7335:2;7320:18;;7313:34;;;-1:-1:-1;;;;;7384:32:1;;7378:3;7363:19;;7356:61;7404:3;7433:19;;7426:35;;;7498:22;;;7492:3;7477:19;;7470:51;7257:47;-1:-1:-1;7538:44:1;7257:47;7567:6;7538:44;:::i;:::-;7530:52;6668:920;-1:-1:-1;;;;;;;;;;6668:920:1:o;8528:410::-;8599:6;8607;8660:2;8648:9;8639:7;8635:23;8631:32;8628:52;;;8676:1;8673;8666:12;8628:52;8716:9;8703:23;8749:18;8741:6;8738:30;8735:50;;;8781:1;8778;8771:12;8735:50;8820:58;8870:7;8861:6;8850:9;8846:22;8820:58;:::i;:::-;8897:8;;8794:84;;-1:-1:-1;8528:410:1;-1:-1:-1;;;;8528:410:1:o;8943:114::-;9027:4;9020:5;9016:16;9009:5;9006:27;8996:55;;9047:1;9044;9037:12;9062:801;9173:6;9181;9189;9197;9205;9213;9221;9274:3;9262:9;9253:7;9249:23;9245:33;9242:53;;;9291:1;9288;9281:12;9242:53;9330:9;9317:23;9349:31;9374:5;9349:31;:::i;:::-;9399:5;-1:-1:-1;9456:2:1;9441:18;;9428:32;9469:33;9428:32;9469:33;:::i;:::-;9521:7;-1:-1:-1;9575:2:1;9560:18;;9547:32;;-1:-1:-1;9626:2:1;9611:18;;9598:32;;-1:-1:-1;9682:3:1;9667:19;;9654:33;9696:31;9654:33;9696:31;:::i;:::-;9062:801;;;;-1:-1:-1;9062:801:1;;;;9746:7;9800:3;9785:19;;9772:33;;-1:-1:-1;9852:3:1;9837:19;;;9824:33;;9062:801;-1:-1:-1;;9062:801:1:o;9868:388::-;9936:6;9944;9997:2;9985:9;9976:7;9972:23;9968:32;9965:52;;;10013:1;10010;10003:12;9965:52;10052:9;10039:23;10071:31;10096:5;10071:31;:::i;:::-;10121:5;-1:-1:-1;10178:2:1;10163:18;;10150:32;10191:33;10150:32;10191:33;:::i;:::-;10243:7;10233:17;;;9868:388;;;;;:::o;10261:118::-;10347:5;10340:13;10333:21;10326:5;10323:32;10313:60;;10369:1;10366;10359:12;10384:523;10458:6;10466;10474;10527:2;10515:9;10506:7;10502:23;10498:32;10495:52;;;10543:1;10540;10533:12;10495:52;10582:9;10569:23;10601:31;10626:5;10601:31;:::i;:::-;10651:5;-1:-1:-1;10708:2:1;10693:18;;10680:32;10721:33;10680:32;10721:33;:::i;:::-;10773:7;-1:-1:-1;10832:2:1;10817:18;;10804:32;10845:30;10804:32;10845:30;:::i;:::-;10894:7;10884:17;;;10384:523;;;;;:::o;10912:315::-;10980:6;10988;11041:2;11029:9;11020:7;11016:23;11012:32;11009:52;;;11057:1;11054;11047:12;11009:52;11093:9;11080:23;11070:33;;11153:2;11142:9;11138:18;11125:32;11166:31;11191:5;11166:31;:::i;11232:245::-;11299:6;11352:2;11340:9;11331:7;11327:23;11323:32;11320:52;;;11368:1;11365;11358:12;11320:52;11400:9;11394:16;11419:28;11441:5;11419:28;:::i;11482:632::-;11752:1;11748;11743:3;11739:11;11735:19;11727:6;11723:32;11712:9;11705:51;11792:6;11787:2;11776:9;11772:18;11765:34;11835:6;11830:2;11819:9;11815:18;11808:34;11878:3;11873:2;11862:9;11858:18;11851:31;11919:6;11913:3;11902:9;11898:19;11891:35;11977:6;11969;11963:3;11952:9;11948:19;11935:49;12034:1;12004:22;;;12028:3;12000:32;;;11993:43;;;;12097:2;12076:15;;;-1:-1:-1;;12072:29:1;12057:45;12053:55;;11482:632;-1:-1:-1;;;;11482:632:1:o;12119:184::-;12189:6;12242:2;12230:9;12221:7;12217:23;12213:32;12210:52;;;12258:1;12255;12248:12;12210:52;-1:-1:-1;12281:16:1;;12119:184;-1:-1:-1;12119:184:1:o;12308:127::-;12369:10;12364:3;12360:20;12357:1;12350:31;12400:4;12397:1;12390:15;12424:4;12421:1;12414:15;12440:128;12507:9;;;12528:11;;;12525:37;;;12542:18;;:::i;12862:168::-;12935:9;;;12966;;12983:15;;;12977:22;;12963:37;12953:71;;13004:18;;:::i;13035:127::-;13096:10;13091:3;13087:20;13084:1;13077:31;13127:4;13124:1;13117:15;13151:4;13148:1;13141:15;13167:217;13207:1;13233;13223:132;;13277:10;13272:3;13268:20;13265:1;13258:31;13312:4;13309:1;13302:15;13340:4;13337:1;13330:15;13223:132;-1:-1:-1;13369:9:1;;13167:217::o;13785:380::-;13864:1;13860:12;;;;13907;;;13928:61;;13982:4;13974:6;13970:17;13960:27;;13928:61;14035:2;14027:6;14024:14;14004:18;14001:38;13998:161;;14081:10;14076:3;14072:20;14069:1;14062:31;14116:4;14113:1;14106:15;14144:4;14141:1;14134:15;14170:127;14231:10;14226:3;14222:20;14219:1;14212:31;14262:4;14259:1;14252:15;14286:4;14283:1;14276:15;14302:125;14367:9;;;14388:10;;;14385:36;;;14401:18;;:::i;14432:127::-;14493:10;14488:3;14484:20;14481:1;14474:31;14524:4;14521:1;14514:15;14548:4;14545:1;14538:15;14564:135;14603:3;14624:17;;;14621:43;;14644:18;;:::i;:::-;-1:-1:-1;14691:1:1;14680:13;;14564:135::o;15110:251::-;15180:6;15233:2;15221:9;15212:7;15208:23;15204:32;15201:52;;;15249:1;15246;15239:12;15201:52;15281:9;15275:16;15300:31;15325:5;15300:31;:::i;15492:545::-;15594:2;15589:3;15586:11;15583:448;;;15630:1;15655:5;15651:2;15644:17;15700:4;15696:2;15686:19;15770:2;15758:10;15754:19;15751:1;15747:27;15741:4;15737:38;15806:4;15794:10;15791:20;15788:47;;;-1:-1:-1;15829:4:1;15788:47;15884:2;15879:3;15875:12;15872:1;15868:20;15862:4;15858:31;15848:41;;15939:82;15957:2;15950:5;15947:13;15939:82;;;16002:17;;;15983:1;15972:13;15939:82;;;15943:3;;;15492:545;;;:::o;16213:1206::-;16337:18;16332:3;16329:27;16326:53;;;16359:18;;:::i;:::-;16388:94;16478:3;16438:38;16470:4;16464:11;16438:38;:::i;:::-;16432:4;16388:94;:::i;:::-;16508:1;16533:2;16528:3;16525:11;16550:1;16545:616;;;;17205:1;17222:3;17219:93;;;-1:-1:-1;17278:19:1;;;17265:33;17219:93;-1:-1:-1;;16170:1:1;16166:11;;;16162:24;16158:29;16148:40;16194:1;16190:11;;;16145:57;17325:78;;16518:895;;16545:616;15439:1;15432:14;;;15476:4;15463:18;;-1:-1:-1;;16581:17:1;;;16682:9;16704:229;16718:7;16715:1;16712:14;16704:229;;;16807:19;;;16794:33;16779:49;;16914:4;16899:20;;;;16867:1;16855:14;;;;16734:12;16704:229;;;16708:3;16961;16952:7;16949:16;16946:159;;;17085:1;17081:6;17075:3;17069;17066:1;17062:11;17058:21;17054:34;17050:39;17037:9;17032:3;17028:19;17015:33;17011:79;17003:6;16996:95;16946:159;;;17148:1;17142:3;17139:1;17135:11;17131:19;17125:4;17118:33;16518:895;;16213:1206;;;:::o;19087:897::-;19167:6;19220:2;19208:9;19199:7;19195:23;19191:32;19188:52;;;19236:1;19233;19226:12;19188:52;19269:9;19263:16;19298:18;19339:2;19331:6;19328:14;19325:34;;;19355:1;19352;19345:12;19325:34;19393:6;19382:9;19378:22;19368:32;;19438:7;19431:4;19427:2;19423:13;19419:27;19409:55;;19460:1;19457;19450:12;19409:55;19489:2;19483:9;19511:2;19507;19504:10;19501:36;;;19517:18;;:::i;:::-;19592:2;19586:9;19560:2;19646:13;;-1:-1:-1;;19642:22:1;;;19666:2;19638:31;19634:40;19622:53;;;19690:18;;;19710:22;;;19687:46;19684:72;;;19736:18;;:::i;:::-;19776:10;19772:2;19765:22;19811:2;19803:6;19796:18;19851:7;19846:2;19841;19837;19833:11;19829:20;19826:33;19823:53;;;19872:1;19869;19862:12;19823:53;19885:68;19950:2;19945;19937:6;19933:15;19928:2;19924;19920:11;19885:68;:::i;19989:788::-;-1:-1:-1;;;20395:3:1;20388:30;20370:3;20447:6;20441:13;20463:75;20531:6;20526:2;20521:3;20517:12;20510:4;20502:6;20498:17;20463:75;:::i;:::-;-1:-1:-1;;;20597:2:1;20557:16;;;20589:11;;;20582:24;20631:13;;20653:76;20631:13;20715:2;20707:11;;20700:4;20688:17;;20653:76;:::i;:::-;20749:17;20768:2;20745:26;;19989:788;-1:-1:-1;;;;19989:788:1:o;20782:1352::-;20908:3;20902:10;20935:18;20927:6;20924:30;20921:56;;;20957:18;;:::i;:::-;20986:97;21076:6;21036:38;21068:4;21062:11;21036:38;:::i;:::-;21030:4;20986:97;:::i;:::-;21138:4;;21202:2;21191:14;;21219:1;21214:663;;;;21921:1;21938:6;21935:89;;;-1:-1:-1;21990:19:1;;;21984:26;21935:89;-1:-1:-1;;16170:1:1;16166:11;;;16162:24;16158:29;16148:40;16194:1;16190:11;;;16145:57;22037:81;;21184:944;;21214:663;15439:1;15432:14;;;15476:4;15463:18;;-1:-1:-1;;21250:20:1;;;21368:236;21382:7;21379:1;21376:14;21368:236;;;21471:19;;;21465:26;21450:42;;21563:27;;;;21531:1;21519:14;;;;21398:19;;21368:236;;;21372:3;21632:6;21623:7;21620:19;21617:201;;;21693:19;;;21687:26;-1:-1:-1;;21776:1:1;21772:14;;;21788:3;21768:24;21764:37;21760:42;21745:58;21730:74;;21617:201;-1:-1:-1;;;;;21864:1:1;21848:14;;;21844:22;21831:36;;-1:-1:-1;20782:1352:1:o;22139:776::-;-1:-1:-1;;;22545:3:1;22538:22;22520:3;22589:6;22583:13;22605:74;22672:6;22668:1;22663:3;22659:11;22652:4;22644:6;22640:17;22605:74;:::i;:::-;-1:-1:-1;;;22738:1:1;22698:16;;;22730:10;;;22723:23;22771:13;;22793:75;22771:13;22855:1;22847:10;;22840:4;22828:17;;22793:75;:::i;:::-;22888:17;22907:1;22884:25;;22139:776;-1:-1:-1;;;;22139:776:1:o;22920:790::-;-1:-1:-1;;;23326:3:1;23319:32;23301:3;23380:6;23374:13;23396:75;23464:6;23459:2;23454:3;23450:12;23443:4;23435:6;23431:17;23396:75;:::i;:::-;-1:-1:-1;;;23530:2:1;23490:16;;;23522:11;;;23515:24;23564:13;;23586:76;23564:13;23648:2;23640:11;;23633:4;23621:17;;23586:76;:::i;:::-;23682:17;23701:2;23678:26;;22920:790;-1:-1:-1;;;;22920:790:1:o;23715:776::-;-1:-1:-1;;;24121:3:1;24114:22;24096:3;24165:6;24159:13;24181:74;24248:6;24244:1;24239:3;24235:11;24228:4;24220:6;24216:17;24181:74;:::i;24496:247::-;24564:6;24617:2;24605:9;24596:7;24592:23;24588:32;24585:52;;;24633:1;24630;24623:12;24585:52;24665:9;24659:16;24684:29;24707:5;24684:29;:::i;24748:422::-;24837:1;24880:5;24837:1;24894:270;24915:7;24905:8;24902:21;24894:270;;;24974:4;24970:1;24966:6;24962:17;24956:4;24953:27;24950:53;;;24983:18;;:::i;:::-;25033:7;25023:8;25019:22;25016:55;;;25053:16;;;;25016:55;25132:22;;;;25092:15;;;;24894:270;;;24898:3;24748:422;;;;;:::o;25175:806::-;25224:5;25254:8;25244:80;;-1:-1:-1;25295:1:1;25309:5;;25244:80;25343:4;25333:76;;-1:-1:-1;25380:1:1;25394:5;;25333:76;25425:4;25443:1;25438:59;;;;25511:1;25506:130;;;;25418:218;;25438:59;25468:1;25459:10;;25482:5;;;25506:130;25543:3;25533:8;25530:17;25527:43;;;25550:18;;:::i;:::-;-1:-1:-1;;25606:1:1;25592:16;;25621:5;;25418:218;;25720:2;25710:8;25707:16;25701:3;25695:4;25692:13;25688:36;25682:2;25672:8;25669:16;25664:2;25658:4;25655:12;25651:35;25648:77;25645:159;;;-1:-1:-1;25757:19:1;;;25789:5;;25645:159;25836:34;25861:8;25855:4;25836:34;:::i;:::-;25906:6;25902:1;25898:6;25894:19;25885:7;25882:32;25879:58;;;25917:18;;:::i;:::-;25955:20;;25175:806;-1:-1:-1;;;25175:806:1:o;25986:140::-;26044:5;26073:47;26114:4;26104:8;26100:19;26094:4;26073:47;:::i;32478:127::-;32539:10;32534:3;32530:20;32527:1;32520:31;32570:4;32567:1;32560:15;32594:4;32591:1;32584:15;34133:287;34262:3;34300:6;34294:13;34316:66;34375:6;34370:3;34363:4;34355:6;34351:17;34316:66;:::i;:::-;34398:16;;;;;34133:287;-1:-1:-1;;34133:287:1:o
Swarm Source
ipfs://2b2b184adb2e50f82565b7eb0000c83c47c4b055a844d7c7c95c40853f0651ae
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.