Contract
0xf9430aD8da4af7fb4091C57FE523af1236FF5b2C
1
Contract Overview
Balance:
0 AVAX
AVAX Value:
$0.00
[ Download CSV Export ]
Contract Name:
XoXoToken
Compiler Version
v0.8.10+commit.fc410830
Contract Source Code (Solidity)
/** *Submitted for verification at snowtrace.io on 2022-06-07 */ // Dependency file: @openzeppelin/contracts/utils/Context.sol // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) // pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // Dependency file: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) // pragma solidity ^0.8.0; // import "@openzeppelin/contracts/utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // Dependency file: @openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) // pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // Dependency file: @openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) // pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // Dependency file: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) // pragma solidity ^0.8.0; // import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; /** * @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); } // Dependency file: @openzeppelin/contracts/token/ERC20/ERC20.sol // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/ERC20.sol) // pragma solidity ^0.8.0; // import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; // import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; // import "@openzeppelin/contracts/utils/Context.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.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 returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the 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 returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom( address from, address to, uint256 amount ) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, _allowances[owner][spender] + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = _allowances[owner][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, 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: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer( address from, address to, uint256 amount ) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; } _balances[to] += amount; emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _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 Spend `amount` form the allowance of `owner` toward `spender`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance( address owner, address spender, uint256 amount ) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} } // Dependency file: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol) // 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); } } // Dependency file: @openzeppelin/contracts/utils/cryptography/ECDSA.sol // OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol) // pragma solidity ^0.8.0; // import "@openzeppelin/contracts/utils/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 = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } if (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)); } } // Dependency file: @openzeppelin/contracts/utils/cryptography/draft-EIP712.sol // OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol) // pragma solidity ^0.8.0; // import "@openzeppelin/contracts/utils/cryptography/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); } } // Dependency file: @openzeppelin/contracts/utils/Counters.sol // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) // pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } } // Dependency file: @openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-ERC20Permit.sol) // pragma solidity ^0.8.0; // import "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol"; // import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; // import "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol"; // import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; // import "@openzeppelin/contracts/utils/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(); } } // Dependency file: @openzeppelin/contracts/utils/math/Math.sol // OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol) // pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a / b + (a % b == 0 ? 0 : 1); } } // Dependency file: @openzeppelin/contracts/governance/utils/IVotes.sol // OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol) // pragma solidity ^0.8.0; /** * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts. * * _Available since v4.5._ */ interface IVotes { /** * @dev Emitted when an account changes their delegate. */ event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); /** * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes. */ event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance); /** * @dev Returns the current amount of votes that `account` has. */ function getVotes(address account) external view returns (uint256); /** * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`). */ function getPastVotes(address account, uint256 blockNumber) external view returns (uint256); /** * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`). * * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. * Votes that have not been delegated are still part of total supply, even though they would not participate in a * vote. */ function getPastTotalSupply(uint256 blockNumber) external view returns (uint256); /** * @dev Returns the delegate that `account` has chosen. */ function delegates(address account) external view returns (address); /** * @dev Delegates votes from the sender to `delegatee`. */ function delegate(address delegatee) external; /** * @dev Delegates votes from signer to `delegatee`. */ function delegateBySig( address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) external; } // Dependency file: @openzeppelin/contracts/utils/math/SafeCast.sol // OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol) // pragma solidity ^0.8.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits. */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128) { require(value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits"); return int128(value); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64) { require(value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits"); return int64(value); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32) { require(value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits"); return int32(value); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16) { require(value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits"); return int16(value); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits. * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8) { require(value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits"); return int8(value); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } } // Dependency file: @openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol) // pragma solidity ^0.8.0; // import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol"; // import "@openzeppelin/contracts/utils/math/Math.sol"; // import "@openzeppelin/contracts/governance/utils/IVotes.sol"; // import "@openzeppelin/contracts/utils/math/SafeCast.sol"; // import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; /** * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's, * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1. * * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module. * * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting * power can be queried through the public accessors {getVotes} and {getPastVotes}. * * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked. * * _Available since v4.2._ */ abstract contract ERC20Votes is IVotes, ERC20Permit { struct Checkpoint { uint32 fromBlock; uint224 votes; } bytes32 private constant _DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); mapping(address => address) private _delegates; mapping(address => Checkpoint[]) private _checkpoints; Checkpoint[] private _totalSupplyCheckpoints; /** * @dev Get the `pos`-th checkpoint for `account`. */ function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) { return _checkpoints[account][pos]; } /** * @dev Get number of checkpoints for `account`. */ function numCheckpoints(address account) public view virtual returns (uint32) { return SafeCast.toUint32(_checkpoints[account].length); } /** * @dev Get the address `account` is currently delegating to. */ function delegates(address account) public view virtual override returns (address) { return _delegates[account]; } /** * @dev Gets the current votes balance for `account` */ function getVotes(address account) public view virtual override returns (uint256) { uint256 pos = _checkpoints[account].length; return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes; } /** * @dev Retrieve the number of votes for `account` at the end of `blockNumber`. * * Requirements: * * - `blockNumber` must have been already mined */ function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) { require(blockNumber < block.number, "ERC20Votes: block not yet mined"); return _checkpointsLookup(_checkpoints[account], blockNumber); } /** * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances. * It is but NOT the sum of all the delegated votes! * * Requirements: * * - `blockNumber` must have been already mined */ function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) { require(blockNumber < block.number, "ERC20Votes: block not yet mined"); return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber); } /** * @dev Lookup a value in a list of (sorted) checkpoints. */ function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) { // We run a binary search to look for the earliest checkpoint taken after `blockNumber`. // // During the loop, the index of the wanted checkpoint remains in the range [low-1, high). // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant. // - If the middle checkpoint is after `blockNumber`, we look in [low, mid) // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high) // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not // out of bounds (in which case we're looking too far in the past and the result is 0). // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out // the same. uint256 high = ckpts.length; uint256 low = 0; while (low < high) { uint256 mid = Math.average(low, high); if (ckpts[mid].fromBlock > blockNumber) { high = mid; } else { low = mid + 1; } } return high == 0 ? 0 : ckpts[high - 1].votes; } /** * @dev Delegate votes from the sender to `delegatee`. */ function delegate(address delegatee) public virtual override { _delegate(_msgSender(), delegatee); } /** * @dev Delegates votes from signer to `delegatee` */ function delegateBySig( address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) public virtual override { require(block.timestamp <= expiry, "ERC20Votes: signature expired"); address signer = ECDSA.recover( _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))), v, r, s ); require(nonce == _useNonce(signer), "ERC20Votes: invalid nonce"); _delegate(signer, delegatee); } /** * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1). */ function _maxSupply() internal view virtual returns (uint224) { return type(uint224).max; } /** * @dev Snapshots the totalSupply after it has been increased. */ function _mint(address account, uint256 amount) internal virtual override { super._mint(account, amount); require(totalSupply() <= _maxSupply(), "ERC20Votes: total supply risks overflowing votes"); _writeCheckpoint(_totalSupplyCheckpoints, _add, amount); } /** * @dev Snapshots the totalSupply after it has been decreased. */ function _burn(address account, uint256 amount) internal virtual override { super._burn(account, amount); _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount); } /** * @dev Move voting power when tokens are transferred. * * Emits a {DelegateVotesChanged} event. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual override { super._afterTokenTransfer(from, to, amount); _moveVotingPower(delegates(from), delegates(to), amount); } /** * @dev Change delegation for `delegator` to `delegatee`. * * Emits events {DelegateChanged} and {DelegateVotesChanged}. */ function _delegate(address delegator, address delegatee) internal virtual { address currentDelegate = delegates(delegator); uint256 delegatorBalance = balanceOf(delegator); _delegates[delegator] = delegatee; emit DelegateChanged(delegator, currentDelegate, delegatee); _moveVotingPower(currentDelegate, delegatee, delegatorBalance); } function _moveVotingPower( address src, address dst, uint256 amount ) private { if (src != dst && amount > 0) { if (src != address(0)) { (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount); emit DelegateVotesChanged(src, oldWeight, newWeight); } if (dst != address(0)) { (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount); emit DelegateVotesChanged(dst, oldWeight, newWeight); } } } function _writeCheckpoint( Checkpoint[] storage ckpts, function(uint256, uint256) view returns (uint256) op, uint256 delta ) private returns (uint256 oldWeight, uint256 newWeight) { uint256 pos = ckpts.length; oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes; newWeight = op(oldWeight, delta); if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) { ckpts[pos - 1].votes = SafeCast.toUint224(newWeight); } else { ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)})); } } function _add(uint256 a, uint256 b) private pure returns (uint256) { return a + b; } function _subtract(uint256 a, uint256 b) private pure returns (uint256) { return a - b; } } // Root file: contracts/XoXoToken.sol pragma solidity 0.8.10; // import "@openzeppelin/contracts/access/Ownable.sol"; // import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol"; contract XoXoToken is Ownable, ERC20Votes { uint256 private constant _maxTotalSupply = 30_000_000e18; // 30,000,000 max xoxos constructor() ERC20("Hunny XoXo Token", "XOXO") ERC20Permit("HunnyXoXoToken") {} // Returns maximum total supply of the token function getMaxTotalSupply() external pure returns (uint256) { return _maxTotalSupply; } /** * @dev Comp version of the {getVotes} accessor, with `uint96` return type. */ function getCurrentVotes(address account) external view virtual returns (uint256) { return getVotes(account); } /** * @dev Comp version of the {getPastVotes} accessor, with `uint96` return type. */ function getPriorVotes(address account, uint256 blockNumber) external view virtual returns (uint256) { return getPastVotes(account, blockNumber); } // No more tokens minted when max supply reached, mint action will not be reverted function mint(address _to, uint256 _amount) public onlyOwner { uint256 remain = _maxTotalSupply - totalSupply(); if (remain > _amount) { _mint(_to, _amount); } else { _mint(_to, remain); } } }
[{"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":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":true,"internalType":"address","name":"fromDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"toDelegate","type":"address"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"DelegateVotesChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint32","name":"pos","type":"uint32"}],"name":"checkpoints","outputs":[{"components":[{"internalType":"uint32","name":"fromBlock","type":"uint32"},{"internalType":"uint224","name":"votes","type":"uint224"}],"internalType":"struct ERC20Votes.Checkpoint","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegateBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"delegates","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getCurrentVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPastTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPastVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPriorVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"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":[{"internalType":"address","name":"account","type":"address"}],"name":"numCheckpoints","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","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":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101606040527f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9610140523480156200003757600080fd5b506040518060400160405280600e81526020016d243ab7373cac37ac37aa37b5b2b760911b81525080604051806040016040528060018152602001603160f81b8152506040518060400160405280601081526020016f243ab7373c902c37ac37902a37b5b2b760811b81525060405180604001604052806004815260200163584f584f60e01b815250620000da620000d4620001a160201b60201c565b620001a5565b8151620000ef906004906020850190620001f5565b50805162000105906005906020840190620001f5565b5050825160208085019190912083518483012060e08290526101008190524660a0818152604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81880181905281830187905260608201869052608082019490945230818401528151808203909301835260c0019052805194019390932091935091906080523060c0526101205250620002d89350505050565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b82805462000203906200029b565b90600052602060002090601f01602090048101928262000227576000855562000272565b82601f106200024257805160ff191683800117855562000272565b8280016001018555821562000272579182015b828111156200027257825182559160200191906001019062000255565b506200028092915062000284565b5090565b5b8082111562000280576000815560010162000285565b600181811c90821680620002b057607f821691505b60208210811415620002d257634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05160e051610100516101205161014051611eee620003336000396000610a5e0152600061109e015260006110ed015260006110c8015260006110210152600061104b015260006110750152611eee6000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c8063715018a611610104578063a457c2d7116100a2578063d505accf11610071578063d505accf146103fe578063dd62ed3e14610411578063f1127ed81461044a578063f2fde38b1461048757600080fd5b8063a457c2d7146103b2578063a9059cbb146103c5578063b4b5ea57146103d8578063c3cda520146103eb57600080fd5b80638da5cb5b116100de5780638da5cb5b146103735780638e539e8c1461038457806395d89b41146103975780639ab24eb01461039f57600080fd5b8063715018a614610345578063782d6fe11461034d5780637ecebe001461036057600080fd5b80633a46b1a8116101715780635c19a95c1161014b5780635c19a95c146102d05780635db30bb1146102e35780636fcfff45146102f457806370a082311461031c57600080fd5b80633a46b1a81461026457806340c10f1914610277578063587cde1e1461028c57600080fd5b806323b872dd116101ad57806323b872dd14610227578063313ce5671461023a5780633644e51514610249578063395093511461025157600080fd5b806306fdde03146101d4578063095ea7b3146101f257806318160ddd14610215575b600080fd5b6101dc61049a565b6040516101e99190611b6a565b60405180910390f35b610205610200366004611bdb565b61052c565b60405190151581526020016101e9565b6003545b6040519081526020016101e9565b610205610235366004611c05565b610544565b604051601281526020016101e9565b610219610568565b61020561025f366004611bdb565b610577565b610219610272366004611bdb565b6105b6565b61028a610285366004611bdb565b610635565b005b6102b861029a366004611c41565b6001600160a01b039081166000908152600760205260409020541690565b6040516001600160a01b0390911681526020016101e9565b61028a6102de366004611c41565b6106a2565b6a18d0bf423c03d8de000000610219565b610307610302366004611c41565b6106af565b60405163ffffffff90911681526020016101e9565b61021961032a366004611c41565b6001600160a01b031660009081526001602052604090205490565b61028a6106d7565b61021961035b366004611bdb565b61070d565b61021961036e366004611c41565b610719565b6000546001600160a01b03166102b8565b610219610392366004611c5c565b610737565b6101dc610793565b6102196103ad366004611c41565b6107a2565b6102056103c0366004611bdb565b610829565b6102056103d3366004611bdb565b6108bb565b6102196103e6366004611c41565b6108c9565b61028a6103f9366004611c86565b6108d4565b61028a61040c366004611cde565b610a0a565b61021961041f366004611d48565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b61045d610458366004611d7b565b610b6e565b60408051825163ffffffff1681526020928301516001600160e01b031692810192909252016101e9565b61028a610495366004611c41565b610bf2565b6060600480546104a990611dbb565b80601f01602080910402602001604051908101604052809291908181526020018280546104d590611dbb565b80156105225780601f106104f757610100808354040283529160200191610522565b820191906000526020600020905b81548152906001019060200180831161050557829003601f168201915b5050505050905090565b60003361053a818585610c8a565b5060019392505050565b600033610552858285610dae565b61055d858585610e40565b506001949350505050565b6000610572611014565b905090565b3360008181526002602090815260408083206001600160a01b038716845290915281205490919061053a90829086906105b1908790611e06565b610c8a565b600043821061060c5760405162461bcd60e51b815260206004820152601f60248201527f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e65640060448201526064015b60405180910390fd5b6001600160a01b038316600090815260086020526040902061062e908361113b565b9392505050565b6000546001600160a01b0316331461065f5760405162461bcd60e51b815260040161060390611e1e565b600061066a60035490565b61067f906a18d0bf423c03d8de000000611e53565b9050818111156106985761069383836111f8565b505050565b61069383826111f8565b6106ac3382611282565b50565b6001600160a01b0381166000908152600860205260408120546106d1906112fc565b92915050565b6000546001600160a01b031633146107015760405162461bcd60e51b815260040161060390611e1e565b61070b6000611365565b565b600061062e83836105b6565b6001600160a01b0381166000908152600660205260408120546106d1565b60004382106107885760405162461bcd60e51b815260206004820152601f60248201527f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e6564006044820152606401610603565b6106d160098361113b565b6060600580546104a990611dbb565b6001600160a01b0381166000908152600860205260408120548015610816576001600160a01b03831660009081526008602052604090206107e4600183611e53565b815481106107f4576107f4611e6a565b60009182526020909120015464010000000090046001600160e01b0316610819565b60005b6001600160e01b03169392505050565b3360008181526002602090815260408083206001600160a01b0387168452909152812054909190838110156108ae5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610603565b61055d8286868403610c8a565b60003361053a818585610e40565b60006106d1826107a2565b834211156109245760405162461bcd60e51b815260206004820152601d60248201527f4552433230566f7465733a207369676e617475726520657870697265640000006044820152606401610603565b604080517fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60208201526001600160a01b03881691810191909152606081018690526080810185905260009061099e906109969060a001604051602081830303815290604052805190602001206113b5565b858585611403565b90506109a98161142b565b86146109f75760405162461bcd60e51b815260206004820152601960248201527f4552433230566f7465733a20696e76616c6964206e6f6e6365000000000000006044820152606401610603565b610a018188611282565b50505050505050565b83421115610a5a5760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610603565b60007f0000000000000000000000000000000000000000000000000000000000000000888888610a898c61142b565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610ae4826113b5565b90506000610af482878787611403565b9050896001600160a01b0316816001600160a01b031614610b575760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610603565b610b628a8a8a610c8a565b50505050505050505050565b60408051808201909152600080825260208201526001600160a01b0383166000908152600860205260409020805463ffffffff8416908110610bb257610bb2611e6a565b60009182526020918290206040805180820190915291015463ffffffff8116825264010000000090046001600160e01b0316918101919091529392505050565b6000546001600160a01b03163314610c1c5760405162461bcd60e51b815260040161060390611e1e565b6001600160a01b038116610c815760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610603565b6106ac81611365565b6001600160a01b038316610cec5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610603565b6001600160a01b038216610d4d5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610603565b6001600160a01b0383811660008181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b038381166000908152600260209081526040808320938616835292905220546000198114610e3a5781811015610e2d5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610603565b610e3a8484848403610c8a565b50505050565b6001600160a01b038316610ea45760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610603565b6001600160a01b038216610f065760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610603565b6001600160a01b03831660009081526001602052604090205481811015610f7e5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610603565b6001600160a01b03808516600090815260016020526040808220858503905591851681529081208054849290610fb5908490611e06565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161100191815260200190565b60405180910390a3610e3a848484611453565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561106d57507f000000000000000000000000000000000000000000000000000000000000000046145b1561109757507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b8154600090815b8181101561119f5760006111568284611485565b90508486828154811061116b5761116b611e6a565b60009182526020909120015463ffffffff16111561118b57809250611199565b611196816001611e06565b91505b50611142565b81156111e357846111b1600184611e53565b815481106111c1576111c1611e6a565b60009182526020909120015464010000000090046001600160e01b03166111e6565b60005b6001600160e01b031695945050505050565b61120282826114a0565b6003546001600160e01b0310156112745760405162461bcd60e51b815260206004820152603060248201527f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60448201526f766572666c6f77696e6720766f74657360801b6064820152608401610603565b610e3a600961158b83611597565b6001600160a01b03828116600081815260076020818152604080842080546001845282862054949093528787166001600160a01b03198416811790915590519190951694919391928592917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a4610e3a828483611710565b600063ffffffff8211156113615760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b6064820152608401610603565b5090565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006106d16113c2611014565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006114148787878761184d565b915091506114218161193a565b5095945050505050565b6001600160a01b03811660009081526006602052604090208054600181018255905b50919050565b6001600160a01b0383811660009081526007602052604080822054858416835291205461069392918216911683611710565b60006114946002848418611e80565b61062e90848416611e06565b6001600160a01b0382166114f65760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610603565b80600360008282546115089190611e06565b90915550506001600160a01b03821660009081526001602052604081208054839290611535908490611e06565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a361158760008383611453565b5050565b600061062e8284611e06565b8254600090819080156115e257856115b0600183611e53565b815481106115c0576115c0611e6a565b60009182526020909120015464010000000090046001600160e01b03166115e5565b60005b6001600160e01b031692506115fe83858763ffffffff16565b915060008111801561163c57504386611618600184611e53565b8154811061162857611628611e6a565b60009182526020909120015463ffffffff16145b1561169c5761164a82611af5565b86611656600184611e53565b8154811061166657611666611e6a565b9060005260206000200160000160046101000a8154816001600160e01b0302191690836001600160e01b03160217905550611707565b8560405180604001604052806116b1436112fc565b63ffffffff1681526020016116c585611af5565b6001600160e01b0390811690915282546001810184556000938452602093849020835194909301519091166401000000000263ffffffff909316929092179101555b50935093915050565b816001600160a01b0316836001600160a01b0316141580156117325750600081115b15610693576001600160a01b038316156117c0576001600160a01b0383166000908152600860205260408120819061176d90611b5e85611597565b91509150846001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a72483836040516117b5929190918252602082015260400190565b60405180910390a250505b6001600160a01b03821615610693576001600160a01b038216600090815260086020526040812081906117f69061158b85611597565b91509150836001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724838360405161183e929190918252602082015260400190565b60405180910390a25050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156118845750600090506003611931565b8460ff16601b1415801561189c57508460ff16601c14155b156118ad5750600090506004611931565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611901573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661192a57600060019250925050611931565b9150600090505b94509492505050565b600081600481111561194e5761194e611ea2565b14156119575750565b600181600481111561196b5761196b611ea2565b14156119b95760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610603565b60028160048111156119cd576119cd611ea2565b1415611a1b5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610603565b6003816004811115611a2f57611a2f611ea2565b1415611a885760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610603565b6004816004811115611a9c57611a9c611ea2565b14156106ac5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610603565b60006001600160e01b038211156113615760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663234206269747360c81b6064820152608401610603565b600061062e8284611e53565b600060208083528351808285015260005b81811015611b9757858101830151858201604001528201611b7b565b81811115611ba9576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b0381168114611bd657600080fd5b919050565b60008060408385031215611bee57600080fd5b611bf783611bbf565b946020939093013593505050565b600080600060608486031215611c1a57600080fd5b611c2384611bbf565b9250611c3160208501611bbf565b9150604084013590509250925092565b600060208284031215611c5357600080fd5b61062e82611bbf565b600060208284031215611c6e57600080fd5b5035919050565b803560ff81168114611bd657600080fd5b60008060008060008060c08789031215611c9f57600080fd5b611ca887611bbf565b95506020870135945060408701359350611cc460608801611c75565b92506080870135915060a087013590509295509295509295565b600080600080600080600060e0888a031215611cf957600080fd5b611d0288611bbf565b9650611d1060208901611bbf565b95506040880135945060608801359350611d2c60808901611c75565b925060a0880135915060c0880135905092959891949750929550565b60008060408385031215611d5b57600080fd5b611d6483611bbf565b9150611d7260208401611bbf565b90509250929050565b60008060408385031215611d8e57600080fd5b611d9783611bbf565b9150602083013563ffffffff81168114611db057600080fd5b809150509250929050565b600181811c90821680611dcf57607f821691505b6020821081141561144d57634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60008219821115611e1957611e19611df0565b500190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600082821015611e6557611e65611df0565b500390565b634e487b7160e01b600052603260045260246000fd5b600082611e9d57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052602160045260246000fdfea2646970667358221220322700dcac03c7a15f81f9baffe92c5aef6bbe39e0195054788c0e10526b858564736f6c634300080a0033
Deployed ByteCode Sourcemap
65445:1240:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11973:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;14324:201;;;;;;:::i;:::-;;:::i;:::-;;;1218:14:1;;1211:22;1193:41;;1181:2;1166:18;14324:201:0;1053:187:1;13093:108:0;13181:12;;13093:108;;;1391:25:1;;;1379:2;1364:18;13093:108:0;1245:177:1;15105:295:0;;;;;;:::i;:::-;;:::i;12935:93::-;;;13018:2;1902:36:1;;1890:2;1875:18;12935:93:0;1760:184:1;43481:115:0;;;:::i;15809:240::-;;;;;;:::i;:::-;;:::i;58614:268::-;;;;;;:::i;:::-;;:::i;66423:259::-;;;;;;:::i;:::-;;:::i;:::-;;57988:128;;;;;;:::i;:::-;-1:-1:-1;;;;;58089:19:0;;;58062:7;58089:19;;;:10;:19;;;;;;;;57988:128;;;;-1:-1:-1;;;;;2486:32:1;;;2468:51;;2456:2;2441:18;57988:128:0;2322:203:1;61087:114:0;;;;;;:::i;:::-;;:::i;65721:102::-;65537:13;65721:102;;57744:151;;;;;;:::i;:::-;;:::i;:::-;;;2704:10:1;2692:23;;;2674:42;;2662:2;2647:18;57744:151:0;2530:192:1;13264:127:0;;;;;;:::i;:::-;-1:-1:-1;;;;;13365:18:0;13338:7;13365:18;;;:9;:18;;;;;;;13264:127;2721:103;;;:::i;66166:161::-;;;;;;:::i;:::-;;:::i;43223:128::-;;;;;;:::i;:::-;;:::i;2070:87::-;2116:7;2143:6;-1:-1:-1;;;;;2143:6:0;2070:87;;59171:259;;;;;;:::i;:::-;;:::i;12192:104::-;;;:::i;58200:212::-;;;;;;:::i;:::-;;:::i;16552:438::-;;;;;;:::i;:::-;;:::i;13597:193::-;;;;;;:::i;:::-;;:::i;65930:125::-;;;;;;:::i;:::-;;:::i;61283:591::-;;;;;;:::i;:::-;;:::i;42512:645::-;;;;;;:::i;:::-;;:::i;13853:151::-;;;;;;:::i;:::-;-1:-1:-1;;;;;13969:18:0;;;13942:7;13969:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;13853:151;57514:150;;;;;;:::i;:::-;;:::i;:::-;;;;5064:13:1;;5079:10;5060:30;5042:49;;5151:4;5139:17;;;5133:24;-1:-1:-1;;;;;5129:50:1;5107:20;;;5100:80;;;;5015:18;57514:150:0;4840:346:1;2979:201:0;;;;;;:::i;:::-;;:::i;11973:100::-;12027:13;12060:5;12053:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11973:100;:::o;14324:201::-;14407:4;804:10;14463:32;804:10;14479:7;14488:6;14463:8;:32::i;:::-;-1:-1:-1;14513:4:0;;14324:201;-1:-1:-1;;;14324:201:0:o;15105:295::-;15236:4;804:10;15294:38;15310:4;804:10;15325:6;15294:15;:38::i;:::-;15343:27;15353:4;15359:2;15363:6;15343:9;:27::i;:::-;-1:-1:-1;15388:4:0;;15105:295;-1:-1:-1;;;;15105:295:0:o;43481:115::-;43541:7;43568:20;:18;:20::i;:::-;43561:27;;43481:115;:::o;15809:240::-;804:10;15897:4;15978:18;;;:11;:18;;;;;;;;-1:-1:-1;;;;;15978:27:0;;;;;;;;;;15897:4;;804:10;15953:66;;804:10;;15978:27;;:40;;16008:10;;15978:40;:::i;:::-;15953:8;:66::i;58614:268::-;58712:7;58754:12;58740:11;:26;58732:70;;;;-1:-1:-1;;;58732:70:0;;6043:2:1;58732:70:0;;;6025:21:1;6082:2;6062:18;;;6055:30;6121:33;6101:18;;;6094:61;6172:18;;58732:70:0;;;;;;;;;-1:-1:-1;;;;;58839:21:0;;;;;;:12;:21;;;;;58820:54;;58862:11;58820:18;:54::i;:::-;58813:61;58614:268;-1:-1:-1;;;58614:268:0:o;66423:259::-;2116:7;2143:6;-1:-1:-1;;;;;2143:6:0;804:10;2290:23;2282:68;;;;-1:-1:-1;;;2282:68:0;;;;;;;:::i;:::-;66495:14:::1;66530:13;13181:12:::0;;;13093:108;66530:13:::1;66512:31;::::0;65537:13:::1;66512:31;:::i;:::-;66495:48;;66569:7;66560:6;:16;66556:119;;;66593:19;66599:3;66604:7;66593:5;:19::i;:::-;66484:198;66423:259:::0;;:::o;66556:119::-:1;66645:18;66651:3;66656:6;66645:5;:18::i;61087:114::-:0;61159:34;804:10;61183:9;61159;:34::i;:::-;61087:114;:::o;57744:151::-;-1:-1:-1;;;;;57858:21:0;;57814:6;57858:21;;;:12;:21;;;;;:28;57840:47;;:17;:47::i;:::-;57833:54;57744:151;-1:-1:-1;;57744:151:0:o;2721:103::-;2116:7;2143:6;-1:-1:-1;;;;;2143:6:0;804:10;2290:23;2282:68;;;;-1:-1:-1;;;2282:68:0;;;;;;;:::i;:::-;2786:30:::1;2813:1;2786:18;:30::i;:::-;2721:103::o:0;66166:161::-;66258:7;66285:34;66298:7;66307:11;66285:12;:34::i;43223:128::-;-1:-1:-1;;;;;43319:14:0;;43292:7;43319:14;;;:7;:14;;;;;40200;43319:24;40108:114;59171:259;59258:7;59300:12;59286:11;:26;59278:70;;;;-1:-1:-1;;;59278:70:0;;6043:2:1;59278:70:0;;;6025:21:1;6082:2;6062:18;;;6055:30;6121:33;6101:18;;;6094:61;6172:18;;59278:70:0;5841:355:1;59278:70:0;59366:56;59385:23;59410:11;59366:18;:56::i;12192:104::-;12248:13;12281:7;12274:14;;;;;:::i;58200:212::-;-1:-1:-1;;;;;58307:21:0;;58273:7;58307:21;;;:12;:21;;;;;:28;58353:8;;:51;;-1:-1:-1;;;;;58368:21:0;;;;;;:12;:21;;;;;58390:7;58396:1;58390:3;:7;:::i;:::-;58368:30;;;;;;;;:::i;:::-;;;;;;;;;;:36;;;;-1:-1:-1;;;;;58368:36:0;58353:51;;;58364:1;58353:51;-1:-1:-1;;;;;58346:58:0;;58200:212;-1:-1:-1;;;58200:212:0:o;16552:438::-;804:10;16645:4;16728:18;;;:11;:18;;;;;;;;-1:-1:-1;;;;;16728:27:0;;;;;;;;;;16645:4;;804:10;16774:35;;;;16766:85;;;;-1:-1:-1;;;16766:85:0;;7026:2:1;16766:85:0;;;7008:21:1;7065:2;7045:18;;;7038:30;7104:34;7084:18;;;7077:62;-1:-1:-1;;;7155:18:1;;;7148:35;7200:19;;16766:85:0;6824:401:1;16766:85:0;16887:60;16896:5;16903:7;16931:15;16912:16;:34;16887:8;:60::i;13597:193::-;13676:4;804:10;13732:28;804:10;13749:2;13753:6;13732:9;:28::i;65930:125::-;66003:7;66030:17;66039:7;66030:8;:17::i;61283:591::-;61510:6;61491:15;:25;;61483:67;;;;-1:-1:-1;;;61483:67:0;;7432:2:1;61483:67:0;;;7414:21:1;7471:2;7451:18;;;7444:30;7510:31;7490:18;;;7483:59;7559:18;;61483:67:0;7230:353:1;61483:67:0;61633:58;;;57194:71;61633:58;;;7819:25:1;-1:-1:-1;;;;;7880:32:1;;7860:18;;;7853:60;;;;7929:18;;;7922:34;;;7972:18;;;7965:34;;;61561:14:0;;61578:174;;61606:87;;7791:19:1;;61633:58:0;;;;;;;;;;;;61623:69;;;;;;61606:16;:87::i;:::-;61708:1;61724;61740;61578:13;:174::i;:::-;61561:191;;61780:17;61790:6;61780:9;:17::i;:::-;61771:5;:26;61763:64;;;;-1:-1:-1;;;61763:64:0;;8212:2:1;61763:64:0;;;8194:21:1;8251:2;8231:18;;;8224:30;8290:27;8270:18;;;8263:55;8335:18;;61763:64:0;8010:349:1;61763:64:0;61838:28;61848:6;61856:9;61838;:28::i;:::-;61472:402;61283:591;;;;;;:::o;42512:645::-;42756:8;42737:15;:27;;42729:69;;;;-1:-1:-1;;;42729:69:0;;8566:2:1;42729:69:0;;;8548:21:1;8605:2;8585:18;;;8578:30;8644:31;8624:18;;;8617:59;8693:18;;42729:69:0;8364:353:1;42729:69:0;42811:18;42853:16;42871:5;42878:7;42887:5;42894:16;42904:5;42894:9;:16::i;:::-;42842:79;;;;;;9009:25:1;;;;-1:-1:-1;;;;;9108:15:1;;;9088:18;;;9081:43;9160:15;;;;9140:18;;;9133:43;9192:18;;;9185:34;9235:19;;;9228:35;9279:19;;;9272:35;;;8981:19;;42842:79:0;;;;;;;;;;;;42832:90;;;;;;42811:111;;42935:12;42950:28;42967:10;42950:16;:28::i;:::-;42935:43;;42991:14;43008:28;43022:4;43028:1;43031;43034;43008:13;:28::i;:::-;42991:45;;43065:5;-1:-1:-1;;;;;43055:15:0;:6;-1:-1:-1;;;;;43055:15:0;;43047:58;;;;-1:-1:-1;;;43047:58:0;;9520:2:1;43047:58:0;;;9502:21:1;9559:2;9539:18;;;9532:30;9598:32;9578:18;;;9571:60;9648:18;;43047:58:0;9318:354:1;43047:58:0;43118:31;43127:5;43134:7;43143:5;43118:8;:31::i;:::-;42718:439;;;42512:645;;;;;;;:::o;57514:150::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;57630:21:0;;;;;;:12;:21;;;;;:26;;;;;;;;;;;;:::i;:::-;;;;;;;;;;57623:33;;;;;;;;;57630:26;;57623:33;;;;;;;;;-1:-1:-1;;;;;57623:33:0;;;;;;;;;57514:150;-1:-1:-1;;;57514:150:0:o;2979:201::-;2116:7;2143:6;-1:-1:-1;;;;;2143:6:0;804:10;2290:23;2282:68;;;;-1:-1:-1;;;2282:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;3068:22:0;::::1;3060:73;;;::::0;-1:-1:-1;;;3060:73:0;;9879:2:1;3060:73:0::1;::::0;::::1;9861:21:1::0;9918:2;9898:18;;;9891:30;9957:34;9937:18;;;9930:62;-1:-1:-1;;;10008:18:1;;;10001:36;10054:19;;3060:73:0::1;9677:402:1::0;3060:73:0::1;3144:28;3163:8;3144:18;:28::i;20188:380::-:0;-1:-1:-1;;;;;20324:19:0;;20316:68;;;;-1:-1:-1;;;20316:68:0;;10286:2:1;20316:68:0;;;10268:21:1;10325:2;10305:18;;;10298:30;10364:34;10344:18;;;10337:62;-1:-1:-1;;;10415:18:1;;;10408:34;10459:19;;20316:68:0;10084:400:1;20316:68:0;-1:-1:-1;;;;;20403:21:0;;20395:68;;;;-1:-1:-1;;;20395:68:0;;10691:2:1;20395:68:0;;;10673:21:1;10730:2;10710:18;;;10703:30;10769:34;10749:18;;;10742:62;-1:-1:-1;;;10820:18:1;;;10813:32;10862:19;;20395:68:0;10489:398:1;20395:68:0;-1:-1:-1;;;;;20476:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;20528:32;;1391:25:1;;;20528:32:0;;1364:18:1;20528:32:0;;;;;;;20188:380;;;:::o;20855:453::-;-1:-1:-1;;;;;13969:18:0;;;20990:24;13969:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;-1:-1:-1;;21057:37:0;;21053:248;;21139:6;21119:16;:26;;21111:68;;;;-1:-1:-1;;;21111:68:0;;11094:2:1;21111:68:0;;;11076:21:1;11133:2;11113:18;;;11106:30;11172:31;11152:18;;;11145:59;11221:18;;21111:68:0;10892:353:1;21111:68:0;21223:51;21232:5;21239:7;21267:6;21248:16;:25;21223:8;:51::i;:::-;20979:329;20855:453;;;:::o;17469:671::-;-1:-1:-1;;;;;17600:18:0;;17592:68;;;;-1:-1:-1;;;17592:68:0;;11452:2:1;17592:68:0;;;11434:21:1;11491:2;11471:18;;;11464:30;11530:34;11510:18;;;11503:62;-1:-1:-1;;;11581:18:1;;;11574:35;11626:19;;17592:68:0;11250:401:1;17592:68:0;-1:-1:-1;;;;;17679:16:0;;17671:64;;;;-1:-1:-1;;;17671:64:0;;11858:2:1;17671:64:0;;;11840:21:1;11897:2;11877:18;;;11870:30;11936:34;11916:18;;;11909:62;-1:-1:-1;;;11987:18:1;;;11980:33;12030:19;;17671:64:0;11656:399:1;17671:64:0;-1:-1:-1;;;;;17821:15:0;;17799:19;17821:15;;;:9;:15;;;;;;17855:21;;;;17847:72;;;;-1:-1:-1;;;17847:72:0;;12262:2:1;17847:72:0;;;12244:21:1;12301:2;12281:18;;;12274:30;12340:34;12320:18;;;12313:62;-1:-1:-1;;;12391:18:1;;;12384:36;12437:19;;17847:72:0;12060:402:1;17847:72:0;-1:-1:-1;;;;;17955:15:0;;;;;;;:9;:15;;;;;;17973:20;;;17955:38;;18015:13;;;;;;;;:23;;17987:6;;17955:15;18015:23;;17987:6;;18015:23;:::i;:::-;;;;;;;;18071:2;-1:-1:-1;;;;;18056:26:0;18065:4;-1:-1:-1;;;;;18056:26:0;;18075:6;18056:26;;;;1391:25:1;;1379:2;1364:18;;1245:177;18056:26:0;;;;;;;;18095:37;18115:4;18121:2;18125:6;18095:19;:37::i;37821:314::-;37874:7;37906:4;-1:-1:-1;;;;;37915:12:0;37898:29;;:66;;;;;37948:16;37931:13;:33;37898:66;37894:234;;;-1:-1:-1;37988:24:0;;37821:314::o;37894:234::-;-1:-1:-1;38324:73:0;;;38074:10;38324:73;;;;13550:25:1;;;;38086:12:0;13591:18:1;;;13584:34;38100:15:0;13634:18:1;;;13627:34;38368:13:0;13677:18:1;;;13670:34;38391:4:0;13720:19:1;;;;13713:61;;;;38324:73:0;;;;;;;;;;13522:19:1;;;;38324:73:0;;;38314:84;;;;;;43481:115::o;59519:1482::-;60652:12;;59618:7;;;60701:236;60714:4;60708:3;:10;60701:236;;;60735:11;60749:23;60762:3;60767:4;60749:12;:23::i;:::-;60735:37;;60814:11;60791:5;60797:3;60791:10;;;;;;;;:::i;:::-;;;;;;;;;;:20;;;:34;60787:139;;;60853:3;60846:10;;60787:139;;;60903:7;:3;60909:1;60903:7;:::i;:::-;60897:13;;60787:139;60720:217;60701:236;;;60956:9;;:37;;60972:5;60978:8;60985:1;60978:4;:8;:::i;:::-;60972:15;;;;;;;;:::i;:::-;;;;;;;;;;:21;;;;-1:-1:-1;;;;;60972:21:0;60956:37;;;60968:1;60956:37;-1:-1:-1;;;;;60949:44:0;;59519:1482;-1:-1:-1;;;;;59519:1482:0:o;62180:290::-;62265:28;62277:7;62286:6;62265:11;:28::i;:::-;13181:12;;-1:-1:-1;;;;;;62312:29:0;62304:90;;;;-1:-1:-1;;;62304:90:0;;12669:2:1;62304:90:0;;;12651:21:1;12708:2;12688:18;;;12681:30;12747:34;12727:18;;;12720:62;-1:-1:-1;;;12798:18:1;;;12791:46;12854:19;;62304:90:0;12467:412:1;62304:90:0;62407:55;62424:23;62449:4;62455:6;62407:16;:55::i;63324:388::-;-1:-1:-1;;;;;58089:19:0;;;63409:23;58089:19;;;:10;:19;;;;;;;;;;13365:9;:18;;;;;;63524:21;;;;:33;;;-1:-1:-1;;;;;;63524:33:0;;;;;;;63575:54;;58089:19;;;;;13365:18;;63524:33;;58089:19;;;63575:54;;63409:23;63575:54;63642:62;63659:15;63676:9;63687:16;63642;:62::i;50612:190::-;50668:6;50704:16;50695:25;;;50687:76;;;;-1:-1:-1;;;50687:76:0;;13086:2:1;50687:76:0;;;13068:21:1;13125:2;13105:18;;;13098:30;13164:34;13144:18;;;13137:62;-1:-1:-1;;;13215:18:1;;;13208:36;13261:19;;50687:76:0;12884:402:1;50687:76:0;-1:-1:-1;50788:5:0;50612:190::o;3340:191::-;3414:16;3433:6;;-1:-1:-1;;;;;3450:17:0;;;-1:-1:-1;;;;;;3450:17:0;;;;;;3483:40;;3433:6;;;;;;;3483:40;;3414:16;3483:40;3403:128;3340:191;:::o;39048:167::-;39125:7;39152:55;39174:20;:18;:20::i;:::-;39196:10;34437:57;;-1:-1:-1;;;34437:57:0;;;14878:27:1;14921:11;;;14914:27;;;14957:12;;;14950:28;;;34400:7:0;;14994:12:1;;34437:57:0;;;;;;;;;;;;34427:68;;;;;;34420:75;;34307:196;;;;;32616:279;32744:7;32765:17;32784:18;32806:25;32817:4;32823:1;32826;32829;32806:10;:25::i;:::-;32764:67;;;;32842:18;32854:5;32842:11;:18::i;:::-;-1:-1:-1;32878:9:0;32616:279;-1:-1:-1;;;;;32616:279:0:o;43734:207::-;-1:-1:-1;;;;;43855:14:0;;43794:15;43855:14;;;:7;:14;;;;;40200;;40337:1;40319:19;;;;40200:14;43916:17;43811:130;43734:207;;;:::o;62898:262::-;-1:-1:-1;;;;;58089:19:0;;;58062:7;58089:19;;;:10;:19;;;;;;;;;;;;;;;63096:56;;58089:19;;;;;63145:6;63096:16;:56::i;44692:156::-;44754:7;44829:11;44839:1;44830:5;;;44829:11;:::i;:::-;44819:21;;44820:5;;;44819:21;:::i;18427:399::-;-1:-1:-1;;;;;18511:21:0;;18503:65;;;;-1:-1:-1;;;18503:65:0;;14209:2:1;18503:65:0;;;14191:21:1;14248:2;14228:18;;;14221:30;14287:33;14267:18;;;14260:61;14338:18;;18503:65:0;14007:355:1;18503:65:0;18659:6;18643:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;18676:18:0;;;;;;:9;:18;;;;;:28;;18698:6;;18676:18;:28;;18698:6;;18676:28;:::i;:::-;;;;-1:-1:-1;;18720:37:0;;1391:25:1;;;-1:-1:-1;;;;;18720:37:0;;;18737:1;;18720:37;;1379:2:1;1364:18;18720:37:0;;;;;;;18770:48;18798:1;18802:7;18811:6;18770:19;:48::i;:::-;18427:399;;:::o;65024:98::-;65082:7;65109:5;65113:1;65109;:5;:::i;64371:645::-;64608:12;;64545:17;;;;64643:8;;:35;;64658:5;64664:7;64670:1;64664:3;:7;:::i;:::-;64658:14;;;;;;;;:::i;:::-;;;;;;;;;;:20;;;;-1:-1:-1;;;;;64658:20:0;64643:35;;;64654:1;64643:35;-1:-1:-1;;;;;64631:47:0;;;64701:20;64704:9;64715:5;64701:2;:20;;:::i;:::-;64689:32;;64744:1;64738:3;:7;:51;;;;-1:-1:-1;64777:12:0;64749:5;64755:7;64761:1;64755:3;:7;:::i;:::-;64749:14;;;;;;;;:::i;:::-;;;;;;;;;;:24;;;:40;64738:51;64734:275;;;64829:29;64848:9;64829:18;:29::i;:::-;64806:5;64812:7;64818:1;64812:3;:7;:::i;:::-;64806:14;;;;;;;;:::i;:::-;;;;;;;;:20;;;:52;;;;;-1:-1:-1;;;;;64806:52:0;;;;;-1:-1:-1;;;;;64806:52:0;;;;;;64734:275;;;64891:5;64902:94;;;;;;;;64925:31;64943:12;64925:17;:31::i;:::-;64902:94;;;;;;64965:29;64984:9;64965:18;:29::i;:::-;-1:-1:-1;;;;;64902:94:0;;;;;;64891:106;;;;;;;-1:-1:-1;64891:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64734:275;64583:433;64371:645;;;;;;:::o;63720:643::-;63852:3;-1:-1:-1;;;;;63845:10:0;:3;-1:-1:-1;;;;;63845:10:0;;;:24;;;;;63868:1;63859:6;:10;63845:24;63841:515;;;-1:-1:-1;;;;;63890:17:0;;;63886:224;;-1:-1:-1;;;;;63986:17:0;;63929;63986;;;:12;:17;;;;;63929;;63969:54;;64005:9;64016:6;63969:16;:54::i;:::-;63928:95;;;;64068:3;-1:-1:-1;;;;;64047:47:0;;64073:9;64084;64047:47;;;;;;14541:25:1;;;14597:2;14582:18;;14575:34;14529:2;14514:18;;14367:248;64047:47:0;;;;;;;;63909:201;;63886:224;-1:-1:-1;;;;;64130:17:0;;;64126:219;;-1:-1:-1;;;;;64226:17:0;;64169;64226;;;:12;:17;;;;;64169;;64209:49;;64245:4;64251:6;64209:16;:49::i;:::-;64168:90;;;;64303:3;-1:-1:-1;;;;;64282:47:0;;64308:9;64319;64282:47;;;;;;14541:25:1;;;14597:2;14582:18;;14575:34;14529:2;14514:18;;14367:248;64282:47:0;;;;;;;;64149:196;;63720:643;;;:::o;30845:1632::-;30976:7;;31910:66;31897:79;;31893:163;;;-1:-1:-1;32009:1:0;;-1:-1:-1;32013:30:0;31993:51;;31893:163;32070:1;:7;;32075:2;32070:7;;:18;;;;;32081:1;:7;;32086:2;32081:7;;32070:18;32066:102;;;-1:-1:-1;32121:1:0;;-1:-1:-1;32125:30:0;32105:51;;32066:102;32282:24;;;32265:14;32282:24;;;;;;;;;15244:25:1;;;15317:4;15305:17;;15285:18;;;15278:45;;;;15339:18;;;15332:34;;;15382:18;;;15375:34;;;32282:24:0;;15216:19:1;;32282:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32282:24:0;;-1:-1:-1;;32282:24:0;;;-1:-1:-1;;;;;;;32321:20:0;;32317:103;;32374:1;32378:29;32358:50;;;;;;;32317:103;32440:6;-1:-1:-1;32448:20:0;;-1:-1:-1;30845:1632:0;;;;;;;;:::o;25554:643::-;25632:20;25623:5;:29;;;;;;;;:::i;:::-;;25619:571;;;25554:643;:::o;25619:571::-;25730:29;25721:5;:38;;;;;;;;:::i;:::-;;25717:473;;;25776:34;;-1:-1:-1;;;25776:34:0;;15754:2:1;25776:34:0;;;15736:21:1;15793:2;15773:18;;;15766:30;15832:26;15812:18;;;15805:54;15876:18;;25776:34:0;15552:348:1;25717:473:0;25841:35;25832:5;:44;;;;;;;;:::i;:::-;;25828:362;;;25893:41;;-1:-1:-1;;;25893:41:0;;16107:2:1;25893:41:0;;;16089:21:1;16146:2;16126:18;;;16119:30;16185:33;16165:18;;;16158:61;16236:18;;25893:41:0;15905:355:1;25828:362:0;25965:30;25956:5;:39;;;;;;;;:::i;:::-;;25952:238;;;26012:44;;-1:-1:-1;;;26012:44:0;;16467:2:1;26012:44:0;;;16449:21:1;16506:2;16486:18;;;16479:30;16545:34;16525:18;;;16518:62;-1:-1:-1;;;16596:18:1;;;16589:32;16638:19;;26012:44:0;16265:398:1;25952:238:0;26087:30;26078:5;:39;;;;;;;;:::i;:::-;;26074:116;;;26134:44;;-1:-1:-1;;;26134:44:0;;16870:2:1;26134:44:0;;;16852:21:1;16909:2;16889:18;;;16882:30;16948:34;16928:18;;;16921:62;-1:-1:-1;;;16999:18:1;;;16992:32;17041:19;;26134:44:0;16668:398:1;48642:195:0;48699:7;-1:-1:-1;;;;;48727:26:0;;;48719:78;;;;-1:-1:-1;;;48719:78:0;;17273:2:1;48719:78:0;;;17255:21:1;17312:2;17292:18;;;17285:30;17351:34;17331:18;;;17324:62;-1:-1:-1;;;17402:18:1;;;17395:37;17449:19;;48719:78:0;17071:403:1;65130:103:0;65193:7;65220:5;65224:1;65220;:5;:::i;14:597:1:-;126:4;155:2;184;173:9;166:21;216:6;210:13;259:6;254:2;243:9;239:18;232:34;284:1;294:140;308:6;305:1;302:13;294:140;;;403:14;;;399:23;;393:30;369:17;;;388:2;365:26;358:66;323:10;;294:140;;;452:6;449:1;446:13;443:91;;;522:1;517:2;508:6;497:9;493:22;489:31;482:42;443:91;-1:-1:-1;595:2:1;574:15;-1:-1:-1;;570:29:1;555:45;;;;602:2;551:54;;14:597;-1:-1:-1;;;14:597:1:o;616:173::-;684:20;;-1:-1:-1;;;;;733:31:1;;723:42;;713:70;;779:1;776;769:12;713:70;616:173;;;:::o;794:254::-;862:6;870;923:2;911:9;902:7;898:23;894:32;891:52;;;939:1;936;929:12;891:52;962:29;981:9;962:29;:::i;:::-;952:39;1038:2;1023:18;;;;1010:32;;-1:-1:-1;;;794:254:1:o;1427:328::-;1504:6;1512;1520;1573:2;1561:9;1552:7;1548:23;1544:32;1541:52;;;1589:1;1586;1579:12;1541:52;1612:29;1631:9;1612:29;:::i;:::-;1602:39;;1660:38;1694:2;1683:9;1679:18;1660:38;:::i;:::-;1650:48;;1745:2;1734:9;1730:18;1717:32;1707:42;;1427:328;;;;;:::o;2131:186::-;2190:6;2243:2;2231:9;2222:7;2218:23;2214:32;2211:52;;;2259:1;2256;2249:12;2211:52;2282:29;2301:9;2282:29;:::i;2727:180::-;2786:6;2839:2;2827:9;2818:7;2814:23;2810:32;2807:52;;;2855:1;2852;2845:12;2807:52;-1:-1:-1;2878:23:1;;2727:180;-1:-1:-1;2727:180:1:o;2912:156::-;2978:20;;3038:4;3027:16;;3017:27;;3007:55;;3058:1;3055;3048:12;3073:531;3175:6;3183;3191;3199;3207;3215;3268:3;3256:9;3247:7;3243:23;3239:33;3236:53;;;3285:1;3282;3275:12;3236:53;3308:29;3327:9;3308:29;:::i;:::-;3298:39;;3384:2;3373:9;3369:18;3356:32;3346:42;;3435:2;3424:9;3420:18;3407:32;3397:42;;3458:36;3490:2;3479:9;3475:18;3458:36;:::i;:::-;3448:46;;3541:3;3530:9;3526:19;3513:33;3503:43;;3593:3;3582:9;3578:19;3565:33;3555:43;;3073:531;;;;;;;;:::o;3609:606::-;3720:6;3728;3736;3744;3752;3760;3768;3821:3;3809:9;3800:7;3796:23;3792:33;3789:53;;;3838:1;3835;3828:12;3789:53;3861:29;3880:9;3861:29;:::i;:::-;3851:39;;3909:38;3943:2;3932:9;3928:18;3909:38;:::i;:::-;3899:48;;3994:2;3983:9;3979:18;3966:32;3956:42;;4045:2;4034:9;4030:18;4017:32;4007:42;;4068:37;4100:3;4089:9;4085:19;4068:37;:::i;:::-;4058:47;;4152:3;4141:9;4137:19;4124:33;4114:43;;4204:3;4193:9;4189:19;4176:33;4166:43;;3609:606;;;;;;;;;;:::o;4220:260::-;4288:6;4296;4349:2;4337:9;4328:7;4324:23;4320:32;4317:52;;;4365:1;4362;4355:12;4317:52;4388:29;4407:9;4388:29;:::i;:::-;4378:39;;4436:38;4470:2;4459:9;4455:18;4436:38;:::i;:::-;4426:48;;4220:260;;;;;:::o;4485:350::-;4552:6;4560;4613:2;4601:9;4592:7;4588:23;4584:32;4581:52;;;4629:1;4626;4619:12;4581:52;4652:29;4671:9;4652:29;:::i;:::-;4642:39;;4731:2;4720:9;4716:18;4703:32;4775:10;4768:5;4764:22;4757:5;4754:33;4744:61;;4801:1;4798;4791:12;4744:61;4824:5;4814:15;;;4485:350;;;;;:::o;5191:380::-;5270:1;5266:12;;;;5313;;;5334:61;;5388:4;5380:6;5376:17;5366:27;;5334:61;5441:2;5433:6;5430:14;5410:18;5407:38;5404:161;;;5487:10;5482:3;5478:20;5475:1;5468:31;5522:4;5519:1;5512:15;5550:4;5547:1;5540:15;5576:127;5637:10;5632:3;5628:20;5625:1;5618:31;5668:4;5665:1;5658:15;5692:4;5689:1;5682:15;5708:128;5748:3;5779:1;5775:6;5772:1;5769:13;5766:39;;;5785:18;;:::i;:::-;-1:-1:-1;5821:9:1;;5708:128::o;6201:356::-;6403:2;6385:21;;;6422:18;;;6415:30;6481:34;6476:2;6461:18;;6454:62;6548:2;6533:18;;6201:356::o;6562:125::-;6602:4;6630:1;6627;6624:8;6621:34;;;6635:18;;:::i;:::-;-1:-1:-1;6672:9:1;;6562:125::o;6692:127::-;6753:10;6748:3;6744:20;6741:1;6734:31;6784:4;6781:1;6774:15;6808:4;6805:1;6798:15;13785:217;13825:1;13851;13841:132;;13895:10;13890:3;13886:20;13883:1;13876:31;13930:4;13927:1;13920:15;13958:4;13955:1;13948:15;13841:132;-1:-1:-1;13987:9:1;;13785:217::o;15420:127::-;15481:10;15476:3;15472:20;15469:1;15462:31;15512:4;15509:1;15502:15;15536:4;15533:1;15526:15
Swarm Source
ipfs://322700dcac03c7a15f81f9baffe92c5aef6bbe39e0195054788c0e10526b8585
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.