ERC-20
Overview
Max Total Supply
5,511,061.599082291429387936 sASNT
Holders
176
Total Transfers
-
Market
Price
$0.00 @ 0.000000 FTM
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Loading...
Loading
Loading...
Loading
Loading...
Loading
Contract Name:
sASNTToken
Compiler Version
v0.8.11+commit.d7f03943
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: MIT // ___ __ // / | _____________ ____ / /_ // / /| | / ___/ ___/ _ \/ __ \/ __/ // / ___ |(__ |__ ) __/ / / / /_ // /_/ |_/____/____/\___/_/ /_/\__/ // // 2022 - Assent Protocol pragma solidity 0.8.11; import "./ERC20Permit.sol"; import "./ERC20Burnable.sol"; import "./AccessControl.sol"; import "./Pausable.sol"; import "./SafeERC20.sol"; contract sASNTToken is ERC20Burnable, ERC20Permit, AccessControl, Pausable { using SafeERC20 for IERC20; bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant RESCUER_ROLE = keccak256("RESCUER_ROLE"); bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); constructor() ERC20("Assent Protocol sASNT Token", "sASNT") ERC20Permit("Assent Protocol") { _setupRole(DEFAULT_ADMIN_ROLE, msg.sender); _setupRole(PAUSER_ROLE, msg.sender); _setupRole(MINTER_ROLE, msg.sender); _setupRole(RESCUER_ROLE, msg.sender); } function mint(address to, uint256 amount) external onlyRole(MINTER_ROLE) { _mint(to, amount); } function rescueTokens(IERC20 token, uint256 value) external onlyRole(RESCUER_ROLE) { token.transfer(msg.sender, value); } function pause() external onlyRole(PAUSER_ROLE) { _pause(); } function unpause() external onlyRole(PAUSER_ROLE) { _unpause(); } function _beforeTokenTransfer( address from, address to, uint256 amount ) internal override whenNotPaused { super._beforeTokenTransfer(from, to, amount); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IAccessControl.sol"; import "./ERC165.sol"; import "./Context.sol"; import "./Strings.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role, _msgSender()); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(uint160(account), 20), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @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 * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(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) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(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) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason 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 { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT 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; } }
// SPDX-License-Identifier: MIT 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; import "./Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } 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"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' 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) { // Check the signature length // - case 65: r,s,v signature (standard) // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._ 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. 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 if (signature.length == 64) { bytes32 r; bytes32 vs; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) vs := mload(add(signature, 0x40)) } return tryRecover(hash, r, vs); } 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; uint8 v; assembly { s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) v := add(shr(255, vs), 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 (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // 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) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @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) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./ECDSA.sol"; /** * @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]. * * _Available since v3.4._ */ abstract contract EIP712 { /* 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 _CACHED_DOMAIN_SEPARATOR; uint256 private immutable _CACHED_CHAIN_ID; address private immutable _CACHED_THIS; bytes32 private immutable _HASHED_NAME; bytes32 private immutable _HASHED_VERSION; bytes32 private immutable _TYPE_HASH; /* 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) { bytes32 hashedName = keccak256(bytes(name)); bytes32 hashedVersion = keccak256(bytes(version)); bytes32 typeHash = keccak256( "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" ); _HASHED_NAME = hashedName; _HASHED_VERSION = hashedVersion; _CACHED_CHAIN_ID = block.chainid; _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion); _CACHED_THIS = address(this); _TYPE_HASH = typeHash; } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) { return _CACHED_DOMAIN_SEPARATOR; } else { return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION); } } function _buildDomainSeparator( bytes32 typeHash, bytes32 nameHash, bytes32 versionHash ) private view returns (bytes32) { return keccak256(abi.encode(typeHash, nameHash, versionHash, 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); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT import "./IERC20.sol"; import "./IERC20Metadata.sol"; import "./Context.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * 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}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * 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(IERC20,IERC20Metadata) 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(IERC20,IERC20Metadata) 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 value {ERC20} uses, unless this function is * 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(IERC20,IERC20Metadata) 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: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, 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}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), 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}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, _msgSender(), currentAllowance - 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) { _approve(_msgSender(), spender, _allowances[_msgSender()][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) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(_msgSender(), spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * 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: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[sender] = senderBalance - amount; } _balances[recipient] += amount; emit Transfer(sender, recipient, amount); _afterTokenTransfer(sender, recipient, 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; _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; } _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 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 {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./ERC20.sol"; pragma solidity ^0.8.0; /** * @dev Extension of {ERC20} that allows token holders to destroy both their own * tokens and those that they have an allowance for, in a way that can be * recognized off-chain (via event analysis). */ abstract contract ERC20Burnable is Context, ERC20 { /** * @dev Destroys `amount` tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 amount) public virtual { _burn(_msgSender(), amount); } /** * @dev Destroys `amount` tokens from `account`, deducting from the caller's * allowance. * * See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for ``accounts``'s tokens of at least * `amount`. */ function burnFrom(address account, uint256 amount) public virtual { uint256 currentAllowance = allowance(account, _msgSender()); require(currentAllowance >= amount, "ERC20: burn amount exceeds allowance"); unchecked { _approve(account, _msgSender(), currentAllowance - amount); } _burn(account, amount); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IERC20Permit.sol"; import "./ERC20.sol"; import "./EIP712.sol"; import "./Counters.sol"; /** * @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 immutable _PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); /** * @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(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT import "./IERC20.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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IERC20.sol"; import "./Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; 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)); } } /** * @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"); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @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] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RESCUER_ROLE","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":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","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":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"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":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"rescueTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101606040527f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9610140523480156200003757600080fd5b506040518060400160405280600f81526020016e105cdcd95b9d08141c9bdd1bd8dbdb608a1b81525080604051806040016040528060018152602001603160f81b8152506040518060400160405280601b81526020017f417373656e742050726f746f636f6c207341534e5420546f6b656e0000000000815250604051806040016040528060058152602001641cd054d39560da1b8152508160039080519060200190620000e7929190620002e5565b508051620000fd906004906020840190620002e5565b5050825160209384012082519284019290922060e08390526101008190524660a0818152604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818901819052818301979097526060810194909452608080850193909352308483018190528151808603909301835260c0948501909152815191909601209052929092526101205250506007805460ff19169055620001a760003362000231565b620001d37f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a3362000231565b620001ff7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a63362000231565b6200022b7fcf6f9f892731e14b8859835f2ff35575f447fb501f46243c4eb8bac19e31a0503362000231565b620003c8565b6200023d828262000241565b5050565b60008281526006602090815260408083206001600160a01b038516845290915290205460ff166200023d5760008281526006602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620002a13390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b828054620002f3906200038b565b90600052602060002090601f01602090048101928262000317576000855562000362565b82601f106200033257805160ff191683800117855562000362565b8280016001018555821562000362579182015b828111156200036257825182559160200191906001019062000345565b506200037092915062000374565b5090565b5b8082111562000370576000815560010162000375565b600181811c90821680620003a057607f821691505b60208210811415620003c257634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05160e051610100516101205161014051611d35620004236000396000610a3301526000610fda015260006110290152600061100401526000610f5d01526000610f8701526000610fb10152611d356000f3fe608060405234801561001057600080fd5b50600436106101e55760003560e01c80635c975abb1161010f578063a217fddf116100a2578063d539139311610071578063d5391393146103fa578063d547741f14610421578063dd62ed3e14610434578063e63ab1e91461046d57600080fd5b8063a217fddf146103b9578063a457c2d7146103c1578063a9059cbb146103d4578063d505accf146103e757600080fd5b80637ecebe00116100de5780637ecebe00146103835780638456cb591461039657806391d148541461039e57806395d89b41146103b157600080fd5b80635c975abb1461031557806370a0823114610320578063713725441461034957806379cc67901461037057600080fd5b8063313ce567116101875780633f4ba83a116101565780633f4ba83a146102d457806340c10f19146102dc57806342966c68146102ef578063573761981461030257600080fd5b8063313ce567146102975780633644e515146102a657806336568abe146102ae57806339509351146102c157600080fd5b806318160ddd116101c357806318160ddd1461023a57806323b872dd1461024c578063248a9ca31461025f5780632f2ff15d1461028257600080fd5b806301ffc9a7146101ea57806306fdde0314610212578063095ea7b314610227575b600080fd5b6101fd6101f8366004611960565b610494565b60405190151581526020015b60405180910390f35b61021a6104cb565b60405161020991906119b6565b6101fd6102353660046119fe565b61055d565b6002545b604051908152602001610209565b6101fd61025a366004611a2a565b610573565b61023e61026d366004611a6b565b60009081526006602052604090206001015490565b610295610290366004611a84565b610622565b005b60405160128152602001610209565b61023e61064d565b6102956102bc366004611a84565b61065c565b6101fd6102cf3660046119fe565b6106da565b610295610716565b6102956102ea3660046119fe565b61074c565b6102956102fd366004611a6b565b610781565b6102956103103660046119fe565b61078b565b60075460ff166101fd565b61023e61032e366004611ab4565b6001600160a01b031660009081526020819052604090205490565b61023e7fcf6f9f892731e14b8859835f2ff35575f447fb501f46243c4eb8bac19e31a05081565b61029561037e3660046119fe565b61082d565b61023e610391366004611ab4565b6108ae565b6102956108cc565b6101fd6103ac366004611a84565b6108ff565b61021a61092a565b61023e600081565b6101fd6103cf3660046119fe565b610939565b6101fd6103e23660046119fe565b6109d2565b6102956103f5366004611ad1565b6109df565b61023e7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b61029561042f366004611a84565b610b43565b61023e610442366004611b48565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b61023e7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b60006001600160e01b03198216637965db0b60e01b14806104c557506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600380546104da90611b76565b80601f016020809104026020016040519081016040528092919081815260200182805461050690611b76565b80156105535780601f1061052857610100808354040283529160200191610553565b820191906000526020600020905b81548152906001019060200180831161053657829003601f168201915b5050505050905090565b600061056a338484610b69565b50600192915050565b6000610580848484610c8d565b6001600160a01b03841660009081526001602090815260408083203384529091529020548281101561060a5760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b60648201526084015b60405180910390fd5b6106178533858403610b69565b506001949350505050565b60008281526006602052604090206001015461063e8133610e66565b6106488383610eca565b505050565b6000610657610f50565b905090565b6001600160a01b03811633146106cc5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610601565b6106d68282611077565b5050565b3360008181526001602090815260408083206001600160a01b0387168452909152812054909161056a918590610711908690611bc1565b610b69565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a6107418133610e66565b6107496110de565b50565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a66107778133610e66565b6106488383611171565b610749338261125c565b7fcf6f9f892731e14b8859835f2ff35575f447fb501f46243c4eb8bac19e31a0506107b68133610e66565b60405163a9059cbb60e01b8152336004820152602481018390526001600160a01b0384169063a9059cbb906044016020604051808303816000875af1158015610803573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108279190611bd9565b50505050565b60006108398333610442565b9050818110156108975760405162461bcd60e51b8152602060048201526024808201527f45524332303a206275726e20616d6f756e74206578636565647320616c6c6f77604482015263616e636560e01b6064820152608401610601565b6108a48333848403610b69565b610648838361125c565b6001600160a01b0381166000908152600560205260408120546104c5565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a6108f78133610e66565b6107496113b6565b60009182526006602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6060600480546104da90611b76565b3360009081526001602090815260408083206001600160a01b0386168452909152812054828110156109bb5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610601565b6109c83385858403610b69565b5060019392505050565b600061056a338484610c8d565b83421115610a2f5760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610601565b60007f0000000000000000000000000000000000000000000000000000000000000000888888610a5e8c611431565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610ab982611459565b90506000610ac9828787876114a7565b9050896001600160a01b0316816001600160a01b031614610b2c5760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610601565b610b378a8a8a610b69565b50505050505050505050565b600082815260066020526040902060010154610b5f8133610e66565b6106488383611077565b6001600160a01b038316610bcb5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610601565b6001600160a01b038216610c2c5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610601565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b038316610cf15760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610601565b6001600160a01b038216610d535760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610601565b610d5e8383836114cf565b6001600160a01b03831660009081526020819052604090205481811015610dd65760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610601565b6001600160a01b03808516600090815260208190526040808220858503905591851681529081208054849290610e0d908490611bc1565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e5991815260200190565b60405180910390a3610827565b610e7082826108ff565b6106d657610e88816001600160a01b03166014611515565b610e93836020611515565b604051602001610ea4929190611bfb565b60408051601f198184030181529082905262461bcd60e51b8252610601916004016119b6565b610ed482826108ff565b6106d65760008281526006602090815260408083206001600160a01b03851684529091529020805460ff19166001179055610f0c3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148015610fa957507f000000000000000000000000000000000000000000000000000000000000000046145b15610fd357507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b61108182826108ff565b156106d65760008281526006602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60075460ff166111275760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610601565b6007805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6001600160a01b0382166111c75760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610601565b6111d3600083836114cf565b80600260008282546111e59190611bc1565b90915550506001600160a01b03821660009081526020819052604081208054839290611212908490611bc1565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b0382166112bc5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610601565b6112c8826000836114cf565b6001600160a01b0382166000908152602081905260409020548181101561133c5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610601565b6001600160a01b038316600090815260208190526040812083830390556002805484929061136b908490611c70565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60075460ff16156113fc5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610601565b6007805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586111543390565b6001600160a01b03811660009081526005602052604090208054600181018255905b50919050565b60006104c5611466610f50565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006114b8878787876116b8565b915091506114c5816117a5565b5095945050505050565b60075460ff16156106485760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610601565b60606000611524836002611c87565b61152f906002611bc1565b67ffffffffffffffff81111561154757611547611ca6565b6040519080825280601f01601f191660200182016040528015611571576020820181803683370190505b509050600360fc1b8160008151811061158c5761158c611cbc565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106115bb576115bb611cbc565b60200101906001600160f81b031916908160001a90535060006115df846002611c87565b6115ea906001611bc1565b90505b6001811115611662576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061161e5761161e611cbc565b1a60f81b82828151811061163457611634611cbc565b60200101906001600160f81b031916908160001a90535060049490941c9361165b81611cd2565b90506115ed565b5083156116b15760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610601565b9392505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156116ef575060009050600361179c565b8460ff16601b1415801561170757508460ff16601c14155b15611718575060009050600461179c565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561176c573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166117955760006001925092505061179c565b9150600090505b94509492505050565b60008160048111156117b9576117b9611ce9565b14156117c25750565b60018160048111156117d6576117d6611ce9565b14156118245760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610601565b600281600481111561183857611838611ce9565b14156118865760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610601565b600381600481111561189a5761189a611ce9565b14156118f35760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610601565b600481600481111561190757611907611ce9565b14156107495760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610601565b60006020828403121561197257600080fd5b81356001600160e01b0319811681146116b157600080fd5b60005b838110156119a557818101518382015260200161198d565b838111156108275750506000910152565b60208152600082518060208401526119d581604085016020870161198a565b601f01601f19169190910160400192915050565b6001600160a01b038116811461074957600080fd5b60008060408385031215611a1157600080fd5b8235611a1c816119e9565b946020939093013593505050565b600080600060608486031215611a3f57600080fd5b8335611a4a816119e9565b92506020840135611a5a816119e9565b929592945050506040919091013590565b600060208284031215611a7d57600080fd5b5035919050565b60008060408385031215611a9757600080fd5b823591506020830135611aa9816119e9565b809150509250929050565b600060208284031215611ac657600080fd5b81356116b1816119e9565b600080600080600080600060e0888a031215611aec57600080fd5b8735611af7816119e9565b96506020880135611b07816119e9565b95506040880135945060608801359350608088013560ff81168114611b2b57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215611b5b57600080fd5b8235611b66816119e9565b91506020830135611aa9816119e9565b600181811c90821680611b8a57607f821691505b6020821081141561145357634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60008219821115611bd457611bd4611bab565b500190565b600060208284031215611beb57600080fd5b815180151581146116b157600080fd5b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611c3381601785016020880161198a565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351611c6481602884016020880161198a565b01602801949350505050565b600082821015611c8257611c82611bab565b500390565b6000816000190483118215151615611ca157611ca1611bab565b500290565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600081611ce157611ce1611bab565b506000190190565b634e487b7160e01b600052602160045260246000fdfea26469706673582212201cd88dc81bcea0dba8aeb39b90469e6b357d3d17599a8eafad0c351c41f2eda764736f6c634300080b0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101e55760003560e01c80635c975abb1161010f578063a217fddf116100a2578063d539139311610071578063d5391393146103fa578063d547741f14610421578063dd62ed3e14610434578063e63ab1e91461046d57600080fd5b8063a217fddf146103b9578063a457c2d7146103c1578063a9059cbb146103d4578063d505accf146103e757600080fd5b80637ecebe00116100de5780637ecebe00146103835780638456cb591461039657806391d148541461039e57806395d89b41146103b157600080fd5b80635c975abb1461031557806370a0823114610320578063713725441461034957806379cc67901461037057600080fd5b8063313ce567116101875780633f4ba83a116101565780633f4ba83a146102d457806340c10f19146102dc57806342966c68146102ef578063573761981461030257600080fd5b8063313ce567146102975780633644e515146102a657806336568abe146102ae57806339509351146102c157600080fd5b806318160ddd116101c357806318160ddd1461023a57806323b872dd1461024c578063248a9ca31461025f5780632f2ff15d1461028257600080fd5b806301ffc9a7146101ea57806306fdde0314610212578063095ea7b314610227575b600080fd5b6101fd6101f8366004611960565b610494565b60405190151581526020015b60405180910390f35b61021a6104cb565b60405161020991906119b6565b6101fd6102353660046119fe565b61055d565b6002545b604051908152602001610209565b6101fd61025a366004611a2a565b610573565b61023e61026d366004611a6b565b60009081526006602052604090206001015490565b610295610290366004611a84565b610622565b005b60405160128152602001610209565b61023e61064d565b6102956102bc366004611a84565b61065c565b6101fd6102cf3660046119fe565b6106da565b610295610716565b6102956102ea3660046119fe565b61074c565b6102956102fd366004611a6b565b610781565b6102956103103660046119fe565b61078b565b60075460ff166101fd565b61023e61032e366004611ab4565b6001600160a01b031660009081526020819052604090205490565b61023e7fcf6f9f892731e14b8859835f2ff35575f447fb501f46243c4eb8bac19e31a05081565b61029561037e3660046119fe565b61082d565b61023e610391366004611ab4565b6108ae565b6102956108cc565b6101fd6103ac366004611a84565b6108ff565b61021a61092a565b61023e600081565b6101fd6103cf3660046119fe565b610939565b6101fd6103e23660046119fe565b6109d2565b6102956103f5366004611ad1565b6109df565b61023e7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b61029561042f366004611a84565b610b43565b61023e610442366004611b48565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b61023e7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b60006001600160e01b03198216637965db0b60e01b14806104c557506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600380546104da90611b76565b80601f016020809104026020016040519081016040528092919081815260200182805461050690611b76565b80156105535780601f1061052857610100808354040283529160200191610553565b820191906000526020600020905b81548152906001019060200180831161053657829003601f168201915b5050505050905090565b600061056a338484610b69565b50600192915050565b6000610580848484610c8d565b6001600160a01b03841660009081526001602090815260408083203384529091529020548281101561060a5760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b60648201526084015b60405180910390fd5b6106178533858403610b69565b506001949350505050565b60008281526006602052604090206001015461063e8133610e66565b6106488383610eca565b505050565b6000610657610f50565b905090565b6001600160a01b03811633146106cc5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610601565b6106d68282611077565b5050565b3360008181526001602090815260408083206001600160a01b0387168452909152812054909161056a918590610711908690611bc1565b610b69565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a6107418133610e66565b6107496110de565b50565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a66107778133610e66565b6106488383611171565b610749338261125c565b7fcf6f9f892731e14b8859835f2ff35575f447fb501f46243c4eb8bac19e31a0506107b68133610e66565b60405163a9059cbb60e01b8152336004820152602481018390526001600160a01b0384169063a9059cbb906044016020604051808303816000875af1158015610803573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108279190611bd9565b50505050565b60006108398333610442565b9050818110156108975760405162461bcd60e51b8152602060048201526024808201527f45524332303a206275726e20616d6f756e74206578636565647320616c6c6f77604482015263616e636560e01b6064820152608401610601565b6108a48333848403610b69565b610648838361125c565b6001600160a01b0381166000908152600560205260408120546104c5565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a6108f78133610e66565b6107496113b6565b60009182526006602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6060600480546104da90611b76565b3360009081526001602090815260408083206001600160a01b0386168452909152812054828110156109bb5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610601565b6109c83385858403610b69565b5060019392505050565b600061056a338484610c8d565b83421115610a2f5760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610601565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888610a5e8c611431565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610ab982611459565b90506000610ac9828787876114a7565b9050896001600160a01b0316816001600160a01b031614610b2c5760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610601565b610b378a8a8a610b69565b50505050505050505050565b600082815260066020526040902060010154610b5f8133610e66565b6106488383611077565b6001600160a01b038316610bcb5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610601565b6001600160a01b038216610c2c5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610601565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b038316610cf15760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610601565b6001600160a01b038216610d535760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610601565b610d5e8383836114cf565b6001600160a01b03831660009081526020819052604090205481811015610dd65760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610601565b6001600160a01b03808516600090815260208190526040808220858503905591851681529081208054849290610e0d908490611bc1565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e5991815260200190565b60405180910390a3610827565b610e7082826108ff565b6106d657610e88816001600160a01b03166014611515565b610e93836020611515565b604051602001610ea4929190611bfb565b60408051601f198184030181529082905262461bcd60e51b8252610601916004016119b6565b610ed482826108ff565b6106d65760008281526006602090815260408083206001600160a01b03851684529091529020805460ff19166001179055610f0c3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000306001600160a01b037f000000000000000000000000104b2aa5333966360c4f28c206634759c546b82716148015610fa957507f00000000000000000000000000000000000000000000000000000000000000fa46145b15610fd357507ffe259586219013e37c58f2c85090b5ffa35574f1a83e3a7fb424636e2dabc30790565b50604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6020808301919091527f2f6467a1cd0ffa5d3283f6025c0360f611a2ebed770c1e33cf678d34b0b96e71828401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b61108182826108ff565b156106d65760008281526006602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60075460ff166111275760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610601565b6007805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6001600160a01b0382166111c75760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610601565b6111d3600083836114cf565b80600260008282546111e59190611bc1565b90915550506001600160a01b03821660009081526020819052604081208054839290611212908490611bc1565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b0382166112bc5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610601565b6112c8826000836114cf565b6001600160a01b0382166000908152602081905260409020548181101561133c5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610601565b6001600160a01b038316600090815260208190526040812083830390556002805484929061136b908490611c70565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60075460ff16156113fc5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610601565b6007805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586111543390565b6001600160a01b03811660009081526005602052604090208054600181018255905b50919050565b60006104c5611466610f50565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006114b8878787876116b8565b915091506114c5816117a5565b5095945050505050565b60075460ff16156106485760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610601565b60606000611524836002611c87565b61152f906002611bc1565b67ffffffffffffffff81111561154757611547611ca6565b6040519080825280601f01601f191660200182016040528015611571576020820181803683370190505b509050600360fc1b8160008151811061158c5761158c611cbc565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106115bb576115bb611cbc565b60200101906001600160f81b031916908160001a90535060006115df846002611c87565b6115ea906001611bc1565b90505b6001811115611662576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061161e5761161e611cbc565b1a60f81b82828151811061163457611634611cbc565b60200101906001600160f81b031916908160001a90535060049490941c9361165b81611cd2565b90506115ed565b5083156116b15760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610601565b9392505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156116ef575060009050600361179c565b8460ff16601b1415801561170757508460ff16601c14155b15611718575060009050600461179c565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561176c573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166117955760006001925092505061179c565b9150600090505b94509492505050565b60008160048111156117b9576117b9611ce9565b14156117c25750565b60018160048111156117d6576117d6611ce9565b14156118245760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610601565b600281600481111561183857611838611ce9565b14156118865760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610601565b600381600481111561189a5761189a611ce9565b14156118f35760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610601565b600481600481111561190757611907611ce9565b14156107495760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610601565b60006020828403121561197257600080fd5b81356001600160e01b0319811681146116b157600080fd5b60005b838110156119a557818101518382015260200161198d565b838111156108275750506000910152565b60208152600082518060208401526119d581604085016020870161198a565b601f01601f19169190910160400192915050565b6001600160a01b038116811461074957600080fd5b60008060408385031215611a1157600080fd5b8235611a1c816119e9565b946020939093013593505050565b600080600060608486031215611a3f57600080fd5b8335611a4a816119e9565b92506020840135611a5a816119e9565b929592945050506040919091013590565b600060208284031215611a7d57600080fd5b5035919050565b60008060408385031215611a9757600080fd5b823591506020830135611aa9816119e9565b809150509250929050565b600060208284031215611ac657600080fd5b81356116b1816119e9565b600080600080600080600060e0888a031215611aec57600080fd5b8735611af7816119e9565b96506020880135611b07816119e9565b95506040880135945060608801359350608088013560ff81168114611b2b57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215611b5b57600080fd5b8235611b66816119e9565b91506020830135611aa9816119e9565b600181811c90821680611b8a57607f821691505b6020821081141561145357634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60008219821115611bd457611bd4611bab565b500190565b600060208284031215611beb57600080fd5b815180151581146116b157600080fd5b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611c3381601785016020880161198a565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351611c6481602884016020880161198a565b01602801949350505050565b600082821015611c8257611c82611bab565b500390565b6000816000190483118215151615611ca157611ca1611bab565b500290565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600081611ce157611ce1611bab565b506000190190565b634e487b7160e01b600052602160045260246000fdfea26469706673582212201cd88dc81bcea0dba8aeb39b90469e6b357d3d17599a8eafad0c351c41f2eda764736f6c634300080b0033
Deployed Bytecode Sourcemap
442:1303:18:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2585:204:0;;;;;;:::i;:::-;;:::i;:::-;;;470:14:19;;463:22;445:41;;433:2;418:18;2585:204:0;;;;;;;;2127:123:7;;;:::i;:::-;;;;;;;:::i;4363:169::-;;;;;;:::i;:::-;;:::i;3316:108::-;3404:12;;3316:108;;;1750:25:19;;;1738:2;1723:18;3316:108:7;1604:177:19;5014:492:7;;;;;;:::i;:::-;;:::i;3996:123:0:-;;;;;;:::i;:::-;4062:7;4089:12;;;:6;:12;;;;;:22;;;;3996:123;4381:147;;;;;;:::i;:::-;;:::i;:::-;;3135:116:7;;;3241:2;3076:36:19;;3064:2;3049:18;3135:116:7;2934:184:19;2396:115:9;;;:::i;5429:218:0:-;;;;;;:::i;:::-;;:::i;5915:215:7:-;;;;;;:::i;:::-;;:::i;1454:79:18:-;;;:::i;1088:109::-;;;;;;:::i;:::-;;:::i;493:91:8:-;;;;;;:::i;:::-;;:::i;1205:158:18:-;;;;;;:::i;:::-;;:::i;1070:86:15:-;1141:7;;;;1070:86;;3487:127:7;;;;;;:::i;:::-;-1:-1:-1;;;;;3588:18:7;3561:7;3588:18;;;;;;;;;;;;3487:127;647:64:18;;686:25;647:64;;903:368:8;;;;;;:::i;:::-;;:::i;2138:128:9:-;;;;;;:::i;:::-;;:::i;1371:75:18:-;;;:::i;2881:139:0:-;;;;;;:::i;:::-;;:::i;2369:127:7:-;;;:::i;1972:49:0:-;;2017:4;1972:49;;6633:413:7;;;;;;:::i;:::-;;:::i;3827:175::-;;;;;;:::i;:::-;;:::i;1427:645:9:-;;;;;;:::i;:::-;;:::i;578:62:18:-;;616:24;578:62;;4773:149:0;;;;;;:::i;:::-;;:::i;4065:151:7:-;;;;;;:::i;:::-;-1:-1:-1;;;;;4181:18:7;;;4154:7;4181:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;4065:151;718:62:18;;756:24;718:62;;2585:204:0;2670:4;-1:-1:-1;;;;;;2694:47:0;;-1:-1:-1;;;2694:47:0;;:87;;-1:-1:-1;;;;;;;;;;896:40:6;;;2745:36:0;2687:94;2585:204;-1:-1:-1;;2585:204:0:o;2127:123:7:-;2204:13;2237:5;2230:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2127:123;:::o;4363:169::-;4446:4;4463:39;682:10:2;4486:7:7;4495:6;4463:8;:39::i;:::-;-1:-1:-1;4520:4:7;4363:169;;;;:::o;5014:492::-;5154:4;5171:36;5181:6;5189:9;5200:6;5171:9;:36::i;:::-;-1:-1:-1;;;;;5247:19:7;;5220:24;5247:19;;;:11;:19;;;;;;;;682:10:2;5247:33:7;;;;;;;;5299:26;;;;5291:79;;;;-1:-1:-1;;;5291:79:7;;5709:2:19;5291:79:7;;;5691:21:19;5748:2;5728:18;;;5721:30;5787:34;5767:18;;;5760:62;-1:-1:-1;;;5838:18:19;;;5831:38;5886:19;;5291:79:7;;;;;;;;;5406:57;5415:6;682:10:2;5456:6:7;5437:16;:25;5406:8;:57::i;:::-;-1:-1:-1;5494:4:7;;5014:492;-1:-1:-1;;;;5014:492:7:o;4381:147:0:-;4062:7;4089:12;;;:6;:12;;;;;:22;;;2463:30;2474:4;682:10:2;2463::0;:30::i;:::-;4495:25:::1;4506:4;4512:7;4495:10;:25::i;:::-;4381:147:::0;;;:::o;2396:115:9:-;2456:7;2483:20;:18;:20::i;:::-;2476:27;;2396:115;:::o;5429:218:0:-;-1:-1:-1;;;;;5525:23:0;;682:10:2;5525:23:0;5517:83;;;;-1:-1:-1;;;5517:83:0;;6118:2:19;5517:83:0;;;6100:21:19;6157:2;6137:18;;;6130:30;6196:34;6176:18;;;6169:62;-1:-1:-1;;;6247:18:19;;;6240:45;6302:19;;5517:83:0;5916:411:19;5517:83:0;5613:26;5625:4;5631:7;5613:11;:26::i;:::-;5429:218;;:::o;5915:215:7:-;682:10:2;6003:4:7;6052:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;6052:34:7;;;;;;;;;;6003:4;;6020:80;;6043:7;;6052:47;;6089:10;;6052:47;:::i;:::-;6020:8;:80::i;1454:79:18:-;756:24;2463:30:0;756:24:18;682:10:2;2463::0;:30::i;:::-;1515:10:18::1;:8;:10::i;:::-;1454:79:::0;:::o;1088:109::-;616:24;2463:30:0;616:24:18;682:10:2;2463::0;:30::i;:::-;1172:17:18::1;1178:2;1182:6;1172:5;:17::i;493:91:8:-:0;549:27;682:10:2;569:6:8;549:5;:27::i;1205:158:18:-;686:25;2463:30:0;686:25:18;682:10:2;2463::0;:30::i;:::-;1322:33:18::1;::::0;-1:-1:-1;;;1322:33:18;;1337:10:::1;1322:33;::::0;::::1;6771:51:19::0;6838:18;;;6831:34;;;-1:-1:-1;;;;;1322:14:18;::::1;::::0;::::1;::::0;6744:18:19;;1322:33:18::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;1205:158:::0;;;:::o;903:368:8:-;980:24;1007:32;1017:7;682:10:2;4065:151:7;:::i;1007:32:8:-;980:59;;1078:6;1058:16;:26;;1050:75;;;;-1:-1:-1;;;1050:75:8;;7360:2:19;1050:75:8;;;7342:21:19;7399:2;7379:18;;;7372:30;7438:34;7418:18;;;7411:62;-1:-1:-1;;;7489:18:19;;;7482:34;7533:19;;1050:75:8;7158:400:19;1050:75:8;1161:58;1170:7;682:10:2;1212:6:8;1193:16;:25;1161:8;:58::i;:::-;1241:22;1247:7;1256:6;1241:5;:22::i;2138:128:9:-;-1:-1:-1;;;;;2234:14:9;;2207:7;2234:14;;;:7;:14;;;;;885::3;2234:24:9;793:114:3;1371:75:18;756:24;2463:30:0;756:24:18;682:10:2;2463::0;:30::i;:::-;1430:8:18::1;:6;:8::i;2881:139:0:-:0;2959:4;2983:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;2983:29:0;;;;;;;;;;;;;;;2881:139::o;2369:127:7:-;2448:13;2481:7;2474:14;;;;;:::i;6633:413::-;682:10:2;6726:4:7;6770:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;6770:34:7;;;;;;;;;;6823:35;;;;6815:85;;;;-1:-1:-1;;;6815:85:7;;7765:2:19;6815:85:7;;;7747:21:19;7804:2;7784:18;;;7777:30;7843:34;7823:18;;;7816:62;-1:-1:-1;;;7894:18:19;;;7887:35;7939:19;;6815:85:7;7563:401:19;6815:85:7;6936:67;682:10:2;6959:7:7;6987:15;6968:16;:34;6936:8;:67::i;:::-;-1:-1:-1;7034:4:7;;6633:413;-1:-1:-1;;;6633:413:7:o;3827:175::-;3913:4;3930:42;682:10:2;3954:9:7;3965:6;3930:9;:42::i;1427:645:9:-;1671:8;1652:15;:27;;1644:69;;;;-1:-1:-1;;;1644:69:9;;8171:2:19;1644:69:9;;;8153:21:19;8210:2;8190:18;;;8183:30;8249:31;8229:18;;;8222:59;8298:18;;1644:69:9;7969:353:19;1644:69:9;1726:18;1768:16;1786:5;1793:7;1802:5;1809:16;1819:5;1809:9;:16::i;:::-;1757:79;;;;;;8614:25:19;;;;-1:-1:-1;;;;;8713:15:19;;;8693:18;;;8686:43;8765:15;;;;8745:18;;;8738:43;8797:18;;;8790:34;8840:19;;;8833:35;8884:19;;;8877:35;;;8586:19;;1757:79:9;;;;;;;;;;;;1747:90;;;;;;1726:111;;1850:12;1865:28;1882:10;1865:16;:28::i;:::-;1850:43;;1906:14;1923:28;1937:4;1943:1;1946;1949;1923:13;:28::i;:::-;1906:45;;1980:5;-1:-1:-1;;;;;1970:15:9;:6;-1:-1:-1;;;;;1970:15:9;;1962:58;;;;-1:-1:-1;;;1962:58:9;;9125:2:19;1962:58:9;;;9107:21:19;9164:2;9144:18;;;9137:30;9203:32;9183:18;;;9176:60;9253:18;;1962:58:9;8923:354:19;1962:58:9;2033:31;2042:5;2049:7;2058:5;2033:8;:31::i;:::-;1633:439;;;1427:645;;;;;;;:::o;4773:149:0:-;4062:7;4089:12;;;:6;:12;;;;;:22;;;2463:30;2474:4;682:10:2;2463::0;:30::i;:::-;4888:26:::1;4900:4;4906:7;4888:11;:26::i;10317:380:7:-:0;-1:-1:-1;;;;;10453:19:7;;10445:68;;;;-1:-1:-1;;;10445:68:7;;9484:2:19;10445:68:7;;;9466:21:19;9523:2;9503:18;;;9496:30;9562:34;9542:18;;;9535:62;-1:-1:-1;;;9613:18:19;;;9606:34;9657:19;;10445:68:7;9282:400:19;10445:68:7;-1:-1:-1;;;;;10532:21:7;;10524:68;;;;-1:-1:-1;;;10524:68:7;;9889:2:19;10524:68:7;;;9871:21:19;9928:2;9908:18;;;9901:30;9967:34;9947:18;;;9940:62;-1:-1:-1;;;10018:18:19;;;10011:32;10060:19;;10524:68:7;9687:398:19;10524:68:7;-1:-1:-1;;;;;10605:18:7;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;10657:32;;1750:25:19;;;10657:32:7;;1723:18:19;10657:32:7;;;;;;;10317:380;;;:::o;7536:733::-;-1:-1:-1;;;;;7676:20:7;;7668:70;;;;-1:-1:-1;;;7668:70:7;;10292:2:19;7668:70:7;;;10274:21:19;10331:2;10311:18;;;10304:30;10370:34;10350:18;;;10343:62;-1:-1:-1;;;10421:18:19;;;10414:35;10466:19;;7668:70:7;10090:401:19;7668:70:7;-1:-1:-1;;;;;7757:23:7;;7749:71;;;;-1:-1:-1;;;7749:71:7;;10698:2:19;7749:71:7;;;10680:21:19;10737:2;10717:18;;;10710:30;10776:34;10756:18;;;10749:62;-1:-1:-1;;;10827:18:19;;;10820:33;10870:19;;7749:71:7;10496:399:19;7749:71:7;7833:47;7854:6;7862:9;7873:6;7833:20;:47::i;:::-;-1:-1:-1;;;;;7917:17:7;;7893:21;7917:17;;;;;;;;;;;7953:23;;;;7945:74;;;;-1:-1:-1;;;7945:74:7;;11102:2:19;7945:74:7;;;11084:21:19;11141:2;11121:18;;;11114:30;11180:34;11160:18;;;11153:62;-1:-1:-1;;;11231:18:19;;;11224:36;11277:19;;7945:74:7;10900:402:19;7945:74:7;-1:-1:-1;;;;;8055:17:7;;;:9;:17;;;;;;;;;;;8075:22;;;8055:42;;8119:20;;;;;;;;:30;;8091:6;;8055:9;8119:30;;8091:6;;8119:30;:::i;:::-;;;;;;;;8184:9;-1:-1:-1;;;;;8167:35:7;8176:6;-1:-1:-1;;;;;8167:35:7;;8195:6;8167:35;;;;1750:25:19;;1738:2;1723:18;;1604:177;8167:35:7;;;;;;;;8215:46;4381:147:0;3310:497;3391:22;3399:4;3405:7;3391;:22::i;:::-;3386:414;;3579:41;3607:7;-1:-1:-1;;;;;3579:41:0;3617:2;3579:19;:41::i;:::-;3693:38;3721:4;3728:2;3693:19;:38::i;:::-;3484:270;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;3484:270:0;;;;;;;;;;-1:-1:-1;;;3430:358:0;;;;;;;:::i;6930:238::-;7014:22;7022:4;7028:7;7014;:22::i;:::-;7009:152;;7053:12;;;;:6;:12;;;;;;;;-1:-1:-1;;;;;7053:29:0;;;;;;;;;:36;;-1:-1:-1;;7053:36:0;7085:4;7053:36;;;7136:12;682:10:2;;602:98;7136:12:0;-1:-1:-1;;;;;7109:40:0;7127:7;-1:-1:-1;;;;;7109:40:0;7121:4;7109:40;;;;;;;;;;6930:238;;:::o;3140:314:5:-;3193:7;3225:4;-1:-1:-1;;;;;3234:12:5;3217:29;;:66;;;;;3267:16;3250:13;:33;3217:66;3213:234;;;-1:-1:-1;3307:24:5;;3140:314::o;3213:234::-;-1:-1:-1;3643:73:5;;;3393:10;3643:73;;;;15493:25:19;;;;3405:12:5;15534:18:19;;;15527:34;3419:15:5;15577:18:19;;;15570:34;3687:13:5;15620:18:19;;;15613:34;3710:4:5;15663:19:19;;;;15656:61;;;;3643:73:5;;;;;;;;;;15465:19:19;;;;3643:73:5;;;3633:84;;;;;;2396:115:9:o;7300:239:0:-;7384:22;7392:4;7398:7;7384;:22::i;:::-;7380:152;;;7455:5;7423:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;7423:29:0;;;;;;;;;;:37;;-1:-1:-1;;7423:37:0;;;7480:40;682:10:2;;7423:12:0;;7480:40;;7455:5;7480:40;7300:239;;:::o;2129:120:15:-;1141:7;;;;1665:41;;;;-1:-1:-1;;;1665:41:15;;12300:2:19;1665:41:15;;;12282:21:19;12339:2;12319:18;;;12312:30;-1:-1:-1;;;12358:18:19;;;12351:50;12418:18;;1665:41:15;12098:344:19;1665:41:15;2188:7:::1;:15:::0;;-1:-1:-1;;2188:15:15::1;::::0;;2219:22:::1;682:10:2::0;2228:12:15::1;2219:22;::::0;-1:-1:-1;;;;;12611:32:19;;;12593:51;;12581:2;12566:18;2219:22:15::1;;;;;;;2129:120::o:0;8556:399:7:-;-1:-1:-1;;;;;8640:21:7;;8632:65;;;;-1:-1:-1;;;8632:65:7;;12857:2:19;8632:65:7;;;12839:21:19;12896:2;12876:18;;;12869:30;12935:33;12915:18;;;12908:61;12986:18;;8632:65:7;12655:355:19;8632:65:7;8710:49;8739:1;8743:7;8752:6;8710:20;:49::i;:::-;8788:6;8772:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;8805:18:7;;:9;:18;;;;;;;;;;:28;;8827:6;;8805:9;:28;;8827:6;;8805:28;:::i;:::-;;;;-1:-1:-1;;8849:37:7;;1750:25:19;;;-1:-1:-1;;;;;8849:37:7;;;8866:1;;8849:37;;1738:2:19;1723:18;8849:37:7;;;;;;;5429:218:0;;:::o;9288:591:7:-;-1:-1:-1;;;;;9372:21:7;;9364:67;;;;-1:-1:-1;;;9364:67:7;;13217:2:19;9364:67:7;;;13199:21:19;13256:2;13236:18;;;13229:30;13295:34;13275:18;;;13268:62;-1:-1:-1;;;13346:18:19;;;13339:31;13387:19;;9364:67:7;13015:397:19;9364:67:7;9444:49;9465:7;9482:1;9486:6;9444:20;:49::i;:::-;-1:-1:-1;;;;;9531:18:7;;9506:22;9531:18;;;;;;;;;;;9568:24;;;;9560:71;;;;-1:-1:-1;;;9560:71:7;;13619:2:19;9560:71:7;;;13601:21:19;13658:2;13638:18;;;13631:30;13697:34;13677:18;;;13670:62;-1:-1:-1;;;13748:18:19;;;13741:32;13790:19;;9560:71:7;13417:398:19;9560:71:7;-1:-1:-1;;;;;9667:18:7;;:9;:18;;;;;;;;;;9688:23;;;9667:44;;9733:12;:22;;9705:6;;9667:9;9733:22;;9705:6;;9733:22;:::i;:::-;;;;-1:-1:-1;;9773:37:7;;1750:25:19;;;9799:1:7;;-1:-1:-1;;;;;9773:37:7;;;;;1738:2:19;1723:18;9773:37:7;;;;;;;4381:147:0;;;:::o;1870:118:15:-;1141:7;;;;1395:9;1387:38;;;;-1:-1:-1;;;1387:38:15;;14152:2:19;1387:38:15;;;14134:21:19;14191:2;14171:18;;;14164:30;-1:-1:-1;;;14210:18:19;;;14203:46;14266:18;;1387:38:15;13950:340:19;1387:38:15;1930:7:::1;:14:::0;;-1:-1:-1;;1930:14:15::1;1940:4;1930:14;::::0;;1960:20:::1;1967:12;682:10:2::0;;602:98;2649:207:9;-1:-1:-1;;;;;2770:14:9;;2709:15;2770:14;;;:7;:14;;;;;885::3;;1022:1;1004:19;;;;885:14;2831:17:9;2726:130;2649:207;;;:::o;4367:167:5:-;4444:7;4471:55;4493:20;:18;:20::i;:::-;4515:10;9426:57:4;;-1:-1:-1;;;9426:57:4;;;15986:27:19;16029:11;;;16022:27;;;16065:12;;;16058:28;;;9389:7:4;;16102:12:19;;9426:57:4;;;;;;;;;;;;9416:68;;;;;;9409:75;;9296:196;;;;;7605:279;7733:7;7754:17;7773:18;7795:25;7806:4;7812:1;7815;7818;7795:10;:25::i;:::-;7753:67;;;;7831:18;7843:5;7831:11;:18::i;:::-;-1:-1:-1;7867:9:4;7605:279;-1:-1:-1;;;;;7605:279:4:o;1541:201:18:-;1141:7:15;;;;1395:9;1387:38;;;;-1:-1:-1;;;1387:38:15;;14152:2:19;1387:38:15;;;14134:21:19;14191:2;14171:18;;;14164:30;-1:-1:-1;;;14210:18:19;;;14203:46;14266:18;;1387:38:15;13950:340:19;1589:451:17;1664:13;1690:19;1722:10;1726:6;1722:1;:10;:::i;:::-;:14;;1735:1;1722:14;:::i;:::-;1712:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1712:25:17;;1690:47;;-1:-1:-1;;;1748:6:17;1755:1;1748:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;1748:15:17;;;;;;;;;-1:-1:-1;;;1774:6:17;1781:1;1774:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;1774:15:17;;;;;;;;-1:-1:-1;1805:9:17;1817:10;1821:6;1817:1;:10;:::i;:::-;:14;;1830:1;1817:14;:::i;:::-;1805:26;;1800:135;1837:1;1833;:5;1800:135;;;-1:-1:-1;;;1885:5:17;1893:3;1885:11;1872:25;;;;;;;:::i;:::-;;;;1860:6;1867:1;1860:9;;;;;;;;:::i;:::-;;;;:37;-1:-1:-1;;;;;1860:37:17;;;;;;;;-1:-1:-1;1922:1:17;1912:11;;;;;1840:3;;;:::i;:::-;;;1800:135;;;-1:-1:-1;1953:10:17;;1945:55;;;;-1:-1:-1;;;1945:55:17;;15075:2:19;1945:55:17;;;15057:21:19;;;15094:18;;;15087:30;15153:34;15133:18;;;15126:62;15205:18;;1945:55:17;14873:356:19;1945:55:17;2025:6;1589:451;-1:-1:-1;;;1589:451:17:o;5827:1639:4:-;5958:7;;6899:66;6886:79;;6882:163;;;-1:-1:-1;6998:1:4;;-1:-1:-1;7002:30:4;6982:51;;6882:163;7059:1;:7;;7064:2;7059:7;;:18;;;;;7070:1;:7;;7075:2;7070:7;;7059:18;7055:102;;;-1:-1:-1;7110:1:4;;-1:-1:-1;7114:30:4;7094:51;;7055:102;7271:24;;;7254:14;7271:24;;;;;;;;;16352:25:19;;;16425:4;16413:17;;16393:18;;;16386:45;;;;16447:18;;;16440:34;;;16490:18;;;16483:34;;;7271:24:4;;16324:19:19;;7271:24:4;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;7271:24:4;;-1:-1:-1;;7271:24:4;;;-1:-1:-1;;;;;;;7310:20:4;;7306:103;;7363:1;7367:29;7347:50;;;;;;;7306:103;7429:6;-1:-1:-1;7437:20:4;;-1:-1:-1;5827:1639:4;;;;;;;;:::o;489:643::-;567:20;558:5;:29;;;;;;;;:::i;:::-;;554:571;;;489:643;:::o;554:571::-;665:29;656:5;:38;;;;;;;;:::i;:::-;;652:473;;;711:34;;-1:-1:-1;;;711:34:4;;16862:2:19;711:34:4;;;16844:21:19;16901:2;16881:18;;;16874:30;16940:26;16920:18;;;16913:54;16984:18;;711:34:4;16660:348:19;652:473:4;776:35;767:5;:44;;;;;;;;:::i;:::-;;763:362;;;828:41;;-1:-1:-1;;;828:41:4;;17215:2:19;828:41:4;;;17197:21:19;17254:2;17234:18;;;17227:30;17293:33;17273:18;;;17266:61;17344:18;;828:41:4;17013:355:19;763:362:4;900:30;891:5;:39;;;;;;;;:::i;:::-;;887:238;;;947:44;;-1:-1:-1;;;947:44:4;;17575:2:19;947:44:4;;;17557:21:19;17614:2;17594:18;;;17587:30;17653:34;17633:18;;;17626:62;-1:-1:-1;;;17704:18:19;;;17697:32;17746:19;;947:44:4;17373:398:19;887:238:4;1022:30;1013:5;:39;;;;;;;;:::i;:::-;;1009:116;;;1069:44;;-1:-1:-1;;;1069:44:4;;17978:2:19;1069:44:4;;;17960:21:19;18017:2;17997:18;;;17990:30;18056:34;18036:18;;;18029:62;-1:-1:-1;;;18107:18:19;;;18100:32;18149:19;;1069:44:4;17776:398:19;14:286;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;167:23;;-1:-1:-1;;;;;;219:32:19;;209:43;;199:71;;266:1;263;256:12;497:258;569:1;579:113;593:6;590:1;587:13;579:113;;;669:11;;;663:18;650:11;;;643:39;615:2;608:10;579:113;;;710:6;707:1;704:13;701:48;;;-1:-1:-1;;745:1:19;727:16;;720:27;497:258::o;760:383::-;909:2;898:9;891:21;872:4;941:6;935:13;984:6;979:2;968:9;964:18;957:34;1000:66;1059:6;1054:2;1043:9;1039:18;1034:2;1026:6;1022:15;1000:66;:::i;:::-;1127:2;1106:15;-1:-1:-1;;1102:29:19;1087:45;;;;1134:2;1083:54;;760:383;-1:-1:-1;;760:383:19:o;1148:131::-;-1:-1:-1;;;;;1223:31:19;;1213:42;;1203:70;;1269:1;1266;1259:12;1284:315;1352:6;1360;1413:2;1401:9;1392:7;1388:23;1384:32;1381:52;;;1429:1;1426;1419:12;1381:52;1468:9;1455:23;1487:31;1512:5;1487:31;:::i;:::-;1537:5;1589:2;1574:18;;;;1561:32;;-1:-1:-1;;;1284:315:19:o;1786:456::-;1863:6;1871;1879;1932:2;1920:9;1911:7;1907:23;1903:32;1900:52;;;1948:1;1945;1938:12;1900:52;1987:9;1974:23;2006:31;2031:5;2006:31;:::i;:::-;2056:5;-1:-1:-1;2113:2:19;2098:18;;2085:32;2126:33;2085:32;2126:33;:::i;:::-;1786:456;;2178:7;;-1:-1:-1;;;2232:2:19;2217:18;;;;2204:32;;1786:456::o;2247:180::-;2306:6;2359:2;2347:9;2338:7;2334:23;2330:32;2327:52;;;2375:1;2372;2365:12;2327:52;-1:-1:-1;2398:23:19;;2247:180;-1:-1:-1;2247:180:19:o;2614:315::-;2682:6;2690;2743:2;2731:9;2722:7;2718:23;2714:32;2711:52;;;2759:1;2756;2749:12;2711:52;2795:9;2782:23;2772:33;;2855:2;2844:9;2840:18;2827:32;2868:31;2893:5;2868:31;:::i;:::-;2918:5;2908:15;;;2614:315;;;;;:::o;3643:247::-;3702:6;3755:2;3743:9;3734:7;3730:23;3726:32;3723:52;;;3771:1;3768;3761:12;3723:52;3810:9;3797:23;3829:31;3854:5;3829:31;:::i;3895:829::-;4006:6;4014;4022;4030;4038;4046;4054;4107:3;4095:9;4086:7;4082:23;4078:33;4075:53;;;4124:1;4121;4114:12;4075:53;4163:9;4150:23;4182:31;4207:5;4182:31;:::i;:::-;4232:5;-1:-1:-1;4289:2:19;4274:18;;4261:32;4302:33;4261:32;4302:33;:::i;:::-;4354:7;-1:-1:-1;4408:2:19;4393:18;;4380:32;;-1:-1:-1;4459:2:19;4444:18;;4431:32;;-1:-1:-1;4515:3:19;4500:19;;4487:33;4564:4;4551:18;;4539:31;;4529:59;;4584:1;4581;4574:12;4529:59;3895:829;;;;-1:-1:-1;3895:829:19;;;;4607:7;4661:3;4646:19;;4633:33;;-1:-1:-1;4713:3:19;4698:19;;;4685:33;;3895:829;-1:-1:-1;;3895:829:19:o;4729:388::-;4797:6;4805;4858:2;4846:9;4837:7;4833:23;4829:32;4826:52;;;4874:1;4871;4864:12;4826:52;4913:9;4900:23;4932:31;4957:5;4932:31;:::i;:::-;4982:5;-1:-1:-1;5039:2:19;5024:18;;5011:32;5052:33;5011:32;5052:33;:::i;5122:380::-;5201:1;5197:12;;;;5244;;;5265:61;;5319:4;5311:6;5307:17;5297:27;;5265:61;5372:2;5364:6;5361:14;5341:18;5338:38;5335:161;;;5418:10;5413:3;5409:20;5406:1;5399:31;5453:4;5450:1;5443:15;5481:4;5478:1;5471:15;6332:127;6393:10;6388:3;6384:20;6381:1;6374:31;6424:4;6421:1;6414:15;6448:4;6445:1;6438:15;6464:128;6504:3;6535:1;6531:6;6528:1;6525:13;6522:39;;;6541:18;;:::i;:::-;-1:-1:-1;6577:9:19;;6464:128::o;6876:277::-;6943:6;6996:2;6984:9;6975:7;6971:23;6967:32;6964:52;;;7012:1;7009;7002:12;6964:52;7044:9;7038:16;7097:5;7090:13;7083:21;7076:5;7073:32;7063:60;;7119:1;7116;7109:12;11307:786;11718:25;11713:3;11706:38;11688:3;11773:6;11767:13;11789:62;11844:6;11839:2;11834:3;11830:12;11823:4;11815:6;11811:17;11789:62;:::i;:::-;-1:-1:-1;;;11910:2:19;11870:16;;;11902:11;;;11895:40;11960:13;;11982:63;11960:13;12031:2;12023:11;;12016:4;12004:17;;11982:63;:::i;:::-;12065:17;12084:2;12061:26;;11307:786;-1:-1:-1;;;;11307:786:19:o;13820:125::-;13860:4;13888:1;13885;13882:8;13879:34;;;13893:18;;:::i;:::-;-1:-1:-1;13930:9:19;;13820:125::o;14295:168::-;14335:7;14401:1;14397;14393:6;14389:14;14386:1;14383:21;14378:1;14371:9;14364:17;14360:45;14357:71;;;14408:18;;:::i;:::-;-1:-1:-1;14448:9:19;;14295:168::o;14468:127::-;14529:10;14524:3;14520:20;14517:1;14510:31;14560:4;14557:1;14550:15;14584:4;14581:1;14574:15;14600:127;14661:10;14656:3;14652:20;14649:1;14642:31;14692:4;14689:1;14682:15;14716:4;14713:1;14706:15;14732:136;14771:3;14799:5;14789:39;;14808:18;;:::i;:::-;-1:-1:-1;;;14844:18:19;;14732:136::o;16528:127::-;16589:10;16584:3;16580:20;16577:1;16570:31;16620:4;16617:1;16610:15;16644:4;16641:1;16634:15
Swarm Source
ipfs://1cd88dc81bcea0dba8aeb39b90469e6b357d3d17599a8eafad0c351c41f2eda7
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.