Overview
Max Total Supply
10,000,000,000 KAT
Holders
5,320 (0.00%)
Market
Price
$0.00 @ 0.000000 ETH
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Balance
16,098.285249565765408492 KATValue
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
KatToken
Compiler Version
v0.8.28+commit.7893614a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.28; import {ERC20Permit, ERC20} from "dependencies/@openzeppelin-contracts-5.1.0/token/ERC20/extensions/ERC20Permit.sol"; import {PowUtil} from "./Powutil.sol"; /// @title Network token for the Katana chain /// @author Polygon Labs (@ethyla) /// @notice Standard ERC20 with added initial locking and inflation mechanisms /// @dev Token is not upgradeable contract KatToken is ERC20Permit { /// @dev Inflation has been sent to the INFLATION_BENEFICIARY event InflationDistributed(address receiver, uint256 amount); /// @dev Inflation factor has been changed event InflationChanged(uint256 oldValue, uint256 newValue); /// @dev Mint capacity has been transferred, similar to transfer for token event MintCapacityDistributed(address sender, address receiver, uint256 amount); /// @dev Role change has been initiated event RoleChangeStarted(address newHolder, bytes32 role); /// @dev New role holder has accepted role, old holder got removed event RoleChangeCompleted(address newHolder, bytes32 role); // Roles /// This role can set the inflation percentage bytes32 public constant INFLATION_ADMIN = keccak256("INFLATION_ADMIN"); /// Receiver of the inflation in form of minting capacity, can distribute it away as needed bytes32 public constant INFLATION_BENEFICIARY = keccak256("INFLATION_BENEFICIARY"); /// Can unlock the token early, no relocking bytes32 public constant UNLOCKER = keccak256("UNLOCKER"); /// Can give and take the right to transfer during locking period bytes32 public constant LOCK_EXEMPTION_ADMIN = keccak256("LOCK_EXEMPTION_ADMIN"); /// All current role holder mapping(bytes32 => address) public roleHolder; /// Potential new role holder, if they accept mapping(bytes32 => address) public pendingRoleHolder; // Inflation /// Total token capacity after the last settlement uint256 public distributedSupplyCap; /// Blocktime of last inflated mintCapacity distribution uint256 public lastMintCapacityIncrease; // Inflation Factor /// @notice Be careful when changing this, value needs to be set as the log2 of the expected inflation percentage /// @notice Example: yearly inflation of 2% needs an inflationFactor of log2(1.02) = 0.028569152196770894e18 /// @notice Don't forget the decimals, also take a look at the tests in Inflation.t.sol uint256 public inflationFactor; /// Maximum configurable inflation (1337% annually) /// @dev Added as a security measure against hostile INFLATION_ADMIN takeover uint256 public constant MAX_INFLATION = 3.7409275603186281e18; // log2(13.37) /// Mint capacity distributed from inflation, also initial mint capacity mapping(address => uint256) public mintCapacity; // Lock /// Time of the unlock, can't be changed, lock definitely opens after this uint256 public immutable unlockTime; /// Overrides unlockTime to allow early unlocking, can't be used to lock again, also not required for time based unlocking bool public locked = true; /// Addresses exempted from the lock, can transfer and transferFrom (only if both spender and from are exempted) during lock mapping(address => bool) lockExemption; constructor( string memory _name, string memory _symbol, address _inflationAdmin, address _inflationBeneficiary, address _distributor, uint256 _unlockTime, address _unlocker, address _lockExemptionAdmin ) ERC20(_name, _symbol) ERC20Permit(_name) { require(bytes(_name).length != 0); require(bytes(_symbol).length != 0); require(_inflationAdmin != address(0)); require(_inflationBeneficiary != address(0)); require(_distributor != address(0)); require(_unlockTime > block.timestamp); // Unlock at most 24 months in the future require(_unlockTime < block.timestamp + 24 * 30 days); require(_unlocker != address(0)); require(_lockExemptionAdmin != address(0)); // Initial cap is 10 billion uint256 initialDistribution = 10_000_000_000 * (10 ** decimals()); mintCapacity[_distributor] = initialDistribution; distributedSupplyCap = initialDistribution; // set to sane default value lastMintCapacityIncrease = block.timestamp; // Set initial inflation to 0 inflationFactor = 0; // Assign roles roleHolder[INFLATION_ADMIN] = _inflationAdmin; roleHolder[INFLATION_BENEFICIARY] = _inflationBeneficiary; roleHolder[UNLOCKER] = _unlocker; roleHolder[LOCK_EXEMPTION_ADMIN] = _lockExemptionAdmin; unlockTime = _unlockTime; // Allow transfers for initial token distributor lockExemption[_distributor] = true; } /** * Check the caller has a specific role * @param role The role the caller has to hold */ modifier hasRole(bytes32 role) { require(roleHolder[role] == msg.sender, "Not role holder."); _; } /** * Function to change the current holder of a role, can only be used by current role holder * @notice To finalize the change the new holder needs to call acceptRole() * @param newRoleOwner The the new role holder * @param role The role being transferred */ function changeRoleHolder(address newRoleOwner, bytes32 role) external hasRole(role) { pendingRoleHolder[role] = newRoleOwner; emit RoleChangeStarted(newRoleOwner, role); } /** * Function to accept a role holder change proposal * @notice Only the pending role holder can accept * @param role The role being accepted */ function acceptRole(bytes32 role) external { require(pendingRoleHolder[role] == msg.sender, "Not new role holder."); roleHolder[role] = pendingRoleHolder[role]; pendingRoleHolder[role] = address(0); emit RoleChangeCompleted(roleHolder[role], role); } /** * Function to renounce the inflationAdmin role * @notice This can't be reverted * @notice Inflation can be higher than 0 and INFLATION_BENEFICIARY can still be changed */ function renounceInflationAdmin() external hasRole(INFLATION_ADMIN) { require(pendingRoleHolder[INFLATION_ADMIN] == address(0), "Role transfer in progress."); roleHolder[INFLATION_ADMIN] = address(0); emit RoleChangeCompleted(address(0), INFLATION_ADMIN); } /** * Function to renounce the inflationBeneficiary role * @notice This can't be reverted * @notice Can only happen once inflation is 0 and INFLATION_ADMIN is renounced */ function renounceInflationBeneficiary() external hasRole(INFLATION_BENEFICIARY) { require(pendingRoleHolder[INFLATION_BENEFICIARY] == address(0), "Role transfer in progress."); require(inflationFactor == 0, "Inflation not zero."); require(roleHolder[INFLATION_ADMIN] == address(0), "Inflation admin not 0."); require(pendingRoleHolder[INFLATION_ADMIN] == address(0), "Role transfer in progress."); roleHolder[INFLATION_BENEFICIARY] = address(0); emit RoleChangeCompleted(address(0), INFLATION_BENEFICIARY); } /** * Unlocks the claim function early, afterwards contract can't be locked again * @dev Can be used after unlock to clean unlocker variable */ function unlockAndRenounceUnlocker() external hasRole(UNLOCKER) { locked = false; roleHolder[UNLOCKER] = address(0); pendingRoleHolder[UNLOCKER] = address(0); emit RoleChangeCompleted(address(0), UNLOCKER); } /** * Renounces the LOCK_EXEMPTION_ADMIN * @dev Can be used after unlock to clean LOCK_EXEMPTION_ADMIN variable * @dev For full cleaning lockExemption needs to be manually emptied */ function renounceLockExemptionAdmin() external hasRole(LOCK_EXEMPTION_ADMIN) { roleHolder[LOCK_EXEMPTION_ADMIN] = address(0); pendingRoleHolder[LOCK_EXEMPTION_ADMIN] = address(0); emit RoleChangeCompleted(address(0), LOCK_EXEMPTION_ADMIN); } /** * Check whether token is unlocked and freely transferable * @return true if either the unlock time has passed or a manual unlock has occurred */ function isUnlocked() public view returns (bool) { return (block.timestamp > unlockTime) || !locked; } /** * Adds (or removes) an address to allow it to transfer during the lock period * @param user The address whose permission is being changed * @param value The new permission status */ function setLockExemption(address user, bool value) external hasRole(LOCK_EXEMPTION_ADMIN) { lockExemption[user] = value; } /** * Sets a new inflation factor starting immediately. * @notice Has to be in the format log2(1.xx) with xx being the yearly inflation in percent * @dev Inflation until now will get distributed immediately using the old inflation factor * @param value The new inflation factor */ function changeInflation(uint256 value) external hasRole(INFLATION_ADMIN) { require(roleHolder[INFLATION_BENEFICIARY] != address(0), "No inflation beneficiary."); require(value <= MAX_INFLATION, "Inflation too large."); distributeInflation(); uint256 oldValue = inflationFactor; inflationFactor = value; emit InflationChanged(oldValue, value); } /** * Calculates the current total cap of the token. * @notice Already minted and not yet minted token amounts add up to this value * @return The current total token cap */ function cap() external view returns (uint256) { return distributedSupplyCap + _calcInflation(); } /** * Calculates the inflation since the last distribution till now, using the current inflation factor * @return The unrealized inflation since the last realization */ function _calcInflation() internal view returns (uint256) { if (lastMintCapacityIncrease == block.timestamp) { return 0; } uint256 timeElapsed = block.timestamp - lastMintCapacityIncrease; uint256 supplyFactor = PowUtil.exp2((inflationFactor * timeElapsed) / 365 days); uint256 newCap = (supplyFactor * distributedSupplyCap) / 1e18; return newCap - distributedSupplyCap; } /** * Fully realizes newly available inflation as mint capacity to the INFLATION_BENEFICIARY */ function distributeInflation() public { uint256 inflation = _calcInflation(); address inflationBeneficiary = roleHolder[INFLATION_BENEFICIARY]; distributedSupplyCap += inflation; mintCapacity[inflationBeneficiary] += inflation; lastMintCapacityIncrease = block.timestamp; emit InflationDistributed(inflationBeneficiary, inflation); } /** * Distributes mint capacity to a minter * @param to Receiver of the mint capacity * @param amount Amount to be transferred as mint capacity */ function distributeMintCapacity(address to, uint256 amount) external { require(to != address(0), "Sending to 0 address"); require(mintCapacity[msg.sender] >= amount, "Not enough mint capacity."); mintCapacity[msg.sender] -= amount; mintCapacity[to] += amount; emit MintCapacityDistributed(msg.sender, to, amount); } /** * Mint within confines of mint capacity * @param to Receiver of the newly minted tokens * @param amount Amount to be minted */ function mint(address to, uint256 amount) external { require(mintCapacity[msg.sender] >= amount, "Not enough mint capacity."); mintCapacity[msg.sender] -= amount; _mint(to, amount); } /** * Override _update to check if lock is still in place * Additionally check if `from` is allowed early transfers * @inheritdoc ERC20 */ function _update(address from, address to, uint256 amount) internal override { if (block.timestamp > unlockTime || !locked) { super._update(from, to, amount); } // Only allow transfer for lockExempted addresses during lock // transferFrom is disallowed during lock else if (lockExemption[from] && from == msg.sender) { super._update(from, to, amount); } else if (from == address(0)) { super._update(from, to, amount); } else { revert("Token locked."); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/ERC20Permit.sol) pragma solidity ^0.8.20; import {IERC20Permit} from "./IERC20Permit.sol"; import {ERC20} from "../ERC20.sol"; import {ECDSA} from "../../../utils/cryptography/ECDSA.sol"; import {EIP712} from "../../../utils/cryptography/EIP712.sol"; import {Nonces} from "../../../utils/Nonces.sol"; /** * @dev Implementation of the ERC-20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[ERC-2612]. * * Adds the {permit} method, which can be used to change an account's ERC-20 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. */ abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712, Nonces { bytes32 private constant PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); /** * @dev Permit deadline has expired. */ error ERC2612ExpiredSignature(uint256 deadline); /** * @dev Mismatched signature. */ error ERC2612InvalidSigner(address signer, address owner); /** * @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 ERC-20 token name. */ constructor(string memory name) EIP712(name, "1") {} /** * @inheritdoc IERC20Permit */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { if (block.timestamp > deadline) { revert ERC2612ExpiredSignature(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); if (signer != owner) { revert ERC2612InvalidSigner(signer, owner); } _approve(owner, spender, value); } /** * @inheritdoc IERC20Permit */ function nonces(address owner) public view virtual override(IERC20Permit, Nonces) returns (uint256) { return super.nonces(owner); } /** * @inheritdoc IERC20Permit */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view virtual returns (bytes32) { return _domainSeparatorV4(); } }
//SPDX-License-Identifier: MIT pragma solidity 0.8.28; library PowUtil { function exp2(uint256 x) internal pure returns (uint256 result) { // based on https://github.com/PaulRBerg/prb-math/blob/5959ef59f906d689c2472ed08797872a1cc00644/src/Common.sol#L54 // usually we would make sure that the number doesn't overflow // assert(product <= 192e18 - 1); // but it won't overflow in the next 1000 years // should it overflow at some point which is more than unlikely, the returned supply factor will be 0 x = (x << 64) / 1e18; unchecked { // Start from 0.5 in the 192.64-bit fixed-point format. result = 0x800000000000000000000000000000000000000000000000; // The following logic multiplies the result by $\sqrt{2^{-i}}$ when the bit at position i is 1. Key points: // // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65. // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1, // we know that `x & 0xFF` is also 1. if (x & 0xFF00000000000000 > 0) { if (x & 0x8000000000000000 > 0) result = (result * 0x16A09E667F3BCC909) >> 64; if (x & 0x4000000000000000 > 0) result = (result * 0x1306FE0A31B7152DF) >> 64; if (x & 0x2000000000000000 > 0) result = (result * 0x1172B83C7D517ADCE) >> 64; if (x & 0x1000000000000000 > 0) result = (result * 0x10B5586CF9890F62A) >> 64; if (x & 0x800000000000000 > 0) result = (result * 0x1059B0D31585743AE) >> 64; if (x & 0x400000000000000 > 0) result = (result * 0x102C9A3E778060EE7) >> 64; if (x & 0x200000000000000 > 0) result = (result * 0x10163DA9FB33356D8) >> 64; if (x & 0x100000000000000 > 0) result = (result * 0x100B1AFA5ABCBED61) >> 64; } if (x & 0xFF000000000000 > 0) { if (x & 0x80000000000000 > 0) result = (result * 0x10058C86DA1C09EA2) >> 64; if (x & 0x40000000000000 > 0) result = (result * 0x1002C605E2E8CEC50) >> 64; if (x & 0x20000000000000 > 0) result = (result * 0x100162F3904051FA1) >> 64; if (x & 0x10000000000000 > 0) result = (result * 0x1000B175EFFDC76BA) >> 64; if (x & 0x8000000000000 > 0) result = (result * 0x100058BA01FB9F96D) >> 64; if (x & 0x4000000000000 > 0) result = (result * 0x10002C5CC37DA9492) >> 64; if (x & 0x2000000000000 > 0) result = (result * 0x1000162E525EE0547) >> 64; if (x & 0x1000000000000 > 0) result = (result * 0x10000B17255775C04) >> 64; } if (x & 0xFF0000000000 > 0) { if (x & 0x800000000000 > 0) result = (result * 0x1000058B91B5BC9AE) >> 64; if (x & 0x400000000000 > 0) result = (result * 0x100002C5C89D5EC6D) >> 64; if (x & 0x200000000000 > 0) result = (result * 0x10000162E43F4F831) >> 64; if (x & 0x100000000000 > 0) result = (result * 0x100000B1721BCFC9A) >> 64; if (x & 0x80000000000 > 0) result = (result * 0x10000058B90CF1E6E) >> 64; if (x & 0x40000000000 > 0) result = (result * 0x1000002C5C863B73F) >> 64; if (x & 0x20000000000 > 0) result = (result * 0x100000162E430E5A2) >> 64; if (x & 0x10000000000 > 0) result = (result * 0x1000000B172183551) >> 64; } if (x & 0xFF00000000 > 0) { if (x & 0x8000000000 > 0) result = (result * 0x100000058B90C0B49) >> 64; if (x & 0x4000000000 > 0) result = (result * 0x10000002C5C8601CC) >> 64; if (x & 0x2000000000 > 0) result = (result * 0x1000000162E42FFF0) >> 64; if (x & 0x1000000000 > 0) result = (result * 0x10000000B17217FBB) >> 64; if (x & 0x800000000 > 0) result = (result * 0x1000000058B90BFCE) >> 64; if (x & 0x400000000 > 0) result = (result * 0x100000002C5C85FE3) >> 64; if (x & 0x200000000 > 0) result = (result * 0x10000000162E42FF1) >> 64; if (x & 0x100000000 > 0) result = (result * 0x100000000B17217F8) >> 64; } if (x & 0xFF000000 > 0) { if (x & 0x80000000 > 0) result = (result * 0x10000000058B90BFC) >> 64; if (x & 0x40000000 > 0) result = (result * 0x1000000002C5C85FE) >> 64; if (x & 0x20000000 > 0) result = (result * 0x100000000162E42FF) >> 64; if (x & 0x10000000 > 0) result = (result * 0x1000000000B17217F) >> 64; if (x & 0x8000000 > 0) result = (result * 0x100000000058B90C0) >> 64; if (x & 0x4000000 > 0) result = (result * 0x10000000002C5C860) >> 64; if (x & 0x2000000 > 0) result = (result * 0x1000000000162E430) >> 64; if (x & 0x1000000 > 0) result = (result * 0x10000000000B17218) >> 64; } if (x & 0xFF0000 > 0) { if (x & 0x800000 > 0) result = (result * 0x1000000000058B90C) >> 64; if (x & 0x400000 > 0) result = (result * 0x100000000002C5C86) >> 64; if (x & 0x200000 > 0) result = (result * 0x10000000000162E43) >> 64; if (x & 0x100000 > 0) result = (result * 0x100000000000B1721) >> 64; if (x & 0x80000 > 0) result = (result * 0x10000000000058B91) >> 64; if (x & 0x40000 > 0) result = (result * 0x1000000000002C5C8) >> 64; if (x & 0x20000 > 0) result = (result * 0x100000000000162E4) >> 64; if (x & 0x10000 > 0) result = (result * 0x1000000000000B172) >> 64; } if (x & 0xFF00 > 0) { if (x & 0x8000 > 0) result = (result * 0x100000000000058B9) >> 64; if (x & 0x4000 > 0) result = (result * 0x10000000000002C5D) >> 64; if (x & 0x2000 > 0) result = (result * 0x1000000000000162E) >> 64; if (x & 0x1000 > 0) result = (result * 0x10000000000000B17) >> 64; if (x & 0x800 > 0) result = (result * 0x1000000000000058C) >> 64; if (x & 0x400 > 0) result = (result * 0x100000000000002C6) >> 64; if (x & 0x200 > 0) result = (result * 0x10000000000000163) >> 64; if (x & 0x100 > 0) result = (result * 0x100000000000000B1) >> 64; } if (x & 0xFF > 0) { if (x & 0x80 > 0) result = (result * 0x10000000000000059) >> 64; if (x & 0x40 > 0) result = (result * 0x1000000000000002C) >> 64; if (x & 0x20 > 0) result = (result * 0x10000000000000016) >> 64; if (x & 0x10 > 0) result = (result * 0x1000000000000000B) >> 64; if (x & 0x8 > 0) result = (result * 0x10000000000000006) >> 64; if (x & 0x4 > 0) result = (result * 0x10000000000000003) >> 64; if (x & 0x2 > 0) result = (result * 0x10000000000000001) >> 64; if (x & 0x1 > 0) result = (result * 0x10000000000000001) >> 64; } // In the code snippet below, two operations are executed simultaneously: // // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1 // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192. // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format. // // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the, // integer part, $2^n$. result *= 1e18; result >>= (191 - (x >> 64)); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[ERC-2612]. * * Adds the {permit} method, which can be used to change an account's ERC-20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "./IERC20.sol"; import {IERC20Metadata} from "./extensions/IERC20Metadata.sol"; import {Context} from "../../utils/Context.sol"; import {IERC20Errors} from "../../interfaces/draft-IERC6093.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}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC-20 * applications. */ abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors { mapping(address account => uint256) private _balances; mapping(address account => mapping(address spender => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the default value returned by this function, unless * it's overridden. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual 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 `value`. */ function transfer(address to, uint256 value) public virtual returns (bool) { address owner = _msgSender(); _transfer(owner, to, value); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `value` 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 value) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, value); return true; } /** * @dev See {IERC20-transferFrom}. * * Skips emitting an {Approval} event indicating an allowance update. This is not * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve]. * * 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 `value`. * - the caller must have allowance for ``from``'s tokens of at least * `value`. */ function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, value); _transfer(from, to, value); return true; } /** * @dev Moves a `value` amount of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _transfer(address from, address to, uint256 value) internal { if (from == address(0)) { revert ERC20InvalidSender(address(0)); } if (to == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(from, to, value); } /** * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from` * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding * this function. * * Emits a {Transfer} event. */ function _update(address from, address to, uint256 value) internal virtual { if (from == address(0)) { // Overflow check required: The rest of the code assumes that totalSupply never overflows _totalSupply += value; } else { uint256 fromBalance = _balances[from]; if (fromBalance < value) { revert ERC20InsufficientBalance(from, fromBalance, value); } unchecked { // Overflow not possible: value <= fromBalance <= totalSupply. _balances[from] = fromBalance - value; } } if (to == address(0)) { unchecked { // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply. _totalSupply -= value; } } else { unchecked { // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256. _balances[to] += value; } } emit Transfer(from, to, value); } /** * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0). * Relies on the `_update` mechanism * * Emits a {Transfer} event with `from` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _mint(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(address(0), account, value); } /** * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply. * Relies on the `_update` mechanism. * * Emits a {Transfer} event with `to` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead */ function _burn(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidSender(address(0)); } _update(account, address(0), value); } /** * @dev Sets `value` 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. * * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. */ function _approve(address owner, address spender, uint256 value) internal { _approve(owner, spender, value, true); } /** * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event. * * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any * `Approval` event during `transferFrom` operations. * * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to * true using the following override: * * ```solidity * function _approve(address owner, address spender, uint256 value, bool) internal virtual override { * super._approve(owner, spender, value, true); * } * ``` * * Requirements are the same as {_approve}. */ function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual { if (owner == address(0)) { revert ERC20InvalidApprover(address(0)); } if (spender == address(0)) { revert ERC20InvalidSpender(address(0)); } _allowances[owner][spender] = value; if (emitEvent) { emit Approval(owner, spender, value); } } /** * @dev Updates `owner` s allowance for `spender` based on spent `value`. * * Does not update the allowance value in case of infinite allowance. * Revert if not enough allowance is available. * * Does not emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 value) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { if (currentAllowance < value) { revert ERC20InsufficientAllowance(spender, currentAllowance, value); } unchecked { _approve(owner, spender, currentAllowance - value, false); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.20; /** * @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 } /** * @dev The signature derives the `address(0)`. */ error ECDSAInvalidSignature(); /** * @dev The signature has an invalid length. */ error ECDSAInvalidSignatureLength(uint256 length); /** * @dev The signature has an S value that is in the upper half order. */ error ECDSAInvalidSignatureS(bytes32 s); /** * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not * return address(0) without also returning an error description. Errors are documented using an enum (error type) * and a bytes32 providing additional information about the error. * * If no error is returned, then the address can be used for verification purposes. * * The `ecrecover` EVM precompile 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 {MessageHashUtils-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] */ function tryRecover( bytes32 hash, bytes memory signature ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) { 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 ("memory-safe") { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length)); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM precompile 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 {MessageHashUtils-toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature); _throwError(error, errorArg); 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[ERC-2098 short signatures] */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) { unchecked { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); // We do not check for an overflow here since the shift operation results in 0 or 1. 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. */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs); _throwError(error, errorArg); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) { // 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, s); } // 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, bytes32(0)); } return (signer, RecoverError.NoError, bytes32(0)); } /** * @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, bytes32 errorArg) = tryRecover(hash, v, r, s); _throwError(error, errorArg); return recovered; } /** * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided. */ function _throwError(RecoverError error, bytes32 errorArg) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert ECDSAInvalidSignature(); } else if (error == RecoverError.InvalidSignatureLength) { revert ECDSAInvalidSignatureLength(uint256(errorArg)); } else if (error == RecoverError.InvalidSignatureS) { revert ECDSAInvalidSignatureS(errorArg); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/EIP712.sol) pragma solidity ^0.8.20; import {MessageHashUtils} from "./MessageHashUtils.sol"; import {ShortStrings, ShortString} from "../ShortStrings.sol"; import {IERC5267} from "../../interfaces/IERC5267.sol"; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP-712] is a standard for hashing and signing of typed structured data. * * The encoding scheme specified in the EIP requires a domain separator and a hash of the typed structured data, whose * encoding is very generic and therefore its implementation in Solidity is not feasible, thus this contract * does not implement the encoding itself. Protocols need to implement the type-specific encoding they need in order to * produce the hash of their typed data using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP-712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain * separator of the implementation contract. This will cause the {_domainSeparatorV4} function to always rebuild the * separator from the immutable values, which is cheaper than accessing a cached version in cold storage. * * @custom:oz-upgrades-unsafe-allow state-variable-immutable */ abstract contract EIP712 is IERC5267 { using ShortStrings for *; bytes32 private constant TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to // invalidate the cached domain separator if the chain id changes. bytes32 private immutable _cachedDomainSeparator; uint256 private immutable _cachedChainId; address private immutable _cachedThis; bytes32 private immutable _hashedName; bytes32 private immutable _hashedVersion; ShortString private immutable _name; ShortString private immutable _version; string private _nameFallback; string private _versionFallback; /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP-712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ constructor(string memory name, string memory version) { _name = name.toShortStringWithFallback(_nameFallback); _version = version.toShortStringWithFallback(_versionFallback); _hashedName = keccak256(bytes(name)); _hashedVersion = keccak256(bytes(version)); _cachedChainId = block.chainid; _cachedDomainSeparator = _buildDomainSeparator(); _cachedThis = address(this); } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { if (address(this) == _cachedThis && block.chainid == _cachedChainId) { return _cachedDomainSeparator; } else { return _buildDomainSeparator(); } } function _buildDomainSeparator() private view returns (bytes32) { return keccak256(abi.encode(TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return MessageHashUtils.toTypedDataHash(_domainSeparatorV4(), structHash); } /** * @dev See {IERC-5267}. */ function eip712Domain() public view virtual returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ) { return ( hex"0f", // 01111 _EIP712Name(), _EIP712Version(), block.chainid, address(this), bytes32(0), new uint256[](0) ); } /** * @dev The name parameter for the EIP712 domain. * * NOTE: By default this function reads _name which is an immutable value. * It only reads from storage if necessary (in case the value is too large to fit in a ShortString). */ // solhint-disable-next-line func-name-mixedcase function _EIP712Name() internal view returns (string memory) { return _name.toStringWithFallback(_nameFallback); } /** * @dev The version parameter for the EIP712 domain. * * NOTE: By default this function reads _version which is an immutable value. * It only reads from storage if necessary (in case the value is too large to fit in a ShortString). */ // solhint-disable-next-line func-name-mixedcase function _EIP712Version() internal view returns (string memory) { return _version.toStringWithFallback(_versionFallback); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Nonces.sol) pragma solidity ^0.8.20; /** * @dev Provides tracking nonces for addresses. Nonces will only increment. */ abstract contract Nonces { /** * @dev The nonce used for an `account` is not the expected current nonce. */ error InvalidAccountNonce(address account, uint256 currentNonce); mapping(address account => uint256) private _nonces; /** * @dev Returns the next unused nonce for an address. */ function nonces(address owner) public view virtual returns (uint256) { return _nonces[owner]; } /** * @dev Consumes a nonce. * * Returns the current value and increments nonce. */ function _useNonce(address owner) internal virtual returns (uint256) { // For each account, the nonce has an initial value of 0, can only be incremented by one, and cannot be // decremented or reset. This guarantees that the nonce never overflows. unchecked { // It is important to do x++ and not ++x here. return _nonces[owner]++; } } /** * @dev Same as {_useNonce} but checking that `nonce` is the next valid for `owner`. */ function _useCheckedNonce(address owner, uint256 nonce) internal virtual { uint256 current = _useNonce(owner); if (nonce != current) { revert InvalidAccountNonce(owner, current); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-20 standard as defined in the ERC. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` 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 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC-20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @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; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/draft-IERC6093.sol) pragma solidity ^0.8.20; /** * @dev Standard ERC-20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC-721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC-1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/MessageHashUtils.sol) pragma solidity ^0.8.20; import {Strings} from "../Strings.sol"; /** * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing. * * The library provides methods for generating a hash of a message that conforms to the * https://eips.ethereum.org/EIPS/eip-191[ERC-191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712] * specifications. */ library MessageHashUtils { /** * @dev Returns the keccak256 digest of an ERC-191 signed data with version * `0x45` (`personal_sign` messages). * * The digest is calculated by prefixing a bytes32 `messageHash` with * `"\x19Ethereum Signed Message:\n32"` and hashing the result. It corresponds with the * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method. * * NOTE: The `messageHash` parameter is intended to be the result of hashing a raw message with * keccak256, although any bytes32 value can be safely used because the final digest will * be re-hashed. * * See {ECDSA-recover}. */ function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) { assembly ("memory-safe") { mstore(0x00, "\x19Ethereum Signed Message:\n32") // 32 is the bytes-length of messageHash mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20) } } /** * @dev Returns the keccak256 digest of an ERC-191 signed data with version * `0x45` (`personal_sign` messages). * * The digest is calculated by prefixing an arbitrary `message` with * `"\x19Ethereum Signed Message:\n" + len(message)` and hashing the result. It corresponds with the * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method. * * See {ECDSA-recover}. */ function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32) { return keccak256(bytes.concat("\x19Ethereum Signed Message:\n", bytes(Strings.toString(message.length)), message)); } /** * @dev Returns the keccak256 digest of an ERC-191 signed data with version * `0x00` (data with intended validator). * * The digest is calculated by prefixing an arbitrary `data` with `"\x19\x00"` and the intended * `validator` address. Then hashing the result. * * See {ECDSA-recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked(hex"19_00", validator, data)); } /** * @dev Returns the keccak256 digest of an EIP-712 typed data (ERC-191 version `0x01`). * * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with * `\x19\x01` and hashing the result. It corresponds to the hash signed by the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712. * * See {ECDSA-recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) { assembly ("memory-safe") { let ptr := mload(0x40) mstore(ptr, hex"19_01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) digest := keccak256(ptr, 0x42) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/ShortStrings.sol) pragma solidity ^0.8.20; import {StorageSlot} from "./StorageSlot.sol"; // | string | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | // | length | 0x BB | type ShortString is bytes32; /** * @dev This library provides functions to convert short memory strings * into a `ShortString` type that can be used as an immutable variable. * * Strings of arbitrary length can be optimized using this library if * they are short enough (up to 31 bytes) by packing them with their * length (1 byte) in a single EVM word (32 bytes). Additionally, a * fallback mechanism can be used for every other case. * * Usage example: * * ```solidity * contract Named { * using ShortStrings for *; * * ShortString private immutable _name; * string private _nameFallback; * * constructor(string memory contractName) { * _name = contractName.toShortStringWithFallback(_nameFallback); * } * * function name() external view returns (string memory) { * return _name.toStringWithFallback(_nameFallback); * } * } * ``` */ library ShortStrings { // Used as an identifier for strings longer than 31 bytes. bytes32 private constant FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF; error StringTooLong(string str); error InvalidShortString(); /** * @dev Encode a string of at most 31 chars into a `ShortString`. * * This will trigger a `StringTooLong` error is the input string is too long. */ function toShortString(string memory str) internal pure returns (ShortString) { bytes memory bstr = bytes(str); if (bstr.length > 31) { revert StringTooLong(str); } return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length)); } /** * @dev Decode a `ShortString` back to a "normal" string. */ function toString(ShortString sstr) internal pure returns (string memory) { uint256 len = byteLength(sstr); // using `new string(len)` would work locally but is not memory safe. string memory str = new string(32); assembly ("memory-safe") { mstore(str, len) mstore(add(str, 0x20), sstr) } return str; } /** * @dev Return the length of a `ShortString`. */ function byteLength(ShortString sstr) internal pure returns (uint256) { uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF; if (result > 31) { revert InvalidShortString(); } return result; } /** * @dev Encode a string into a `ShortString`, or write it to storage if it is too long. */ function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) { if (bytes(value).length < 32) { return toShortString(value); } else { StorageSlot.getStringSlot(store).value = value; return ShortString.wrap(FALLBACK_SENTINEL); } } /** * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}. */ function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) { if (ShortString.unwrap(value) != FALLBACK_SENTINEL) { return toString(value); } else { return store; } } /** * @dev Return the length of a string that was encoded to `ShortString` or written to storage using * {setWithFallback}. * * WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of * actual characters as the UTF-8 encoding of a single character can span over multiple bytes. */ function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) { if (ShortString.unwrap(value) != FALLBACK_SENTINEL) { return byteLength(value); } else { return bytes(store).length; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5267.sol) pragma solidity ^0.8.20; interface IERC5267 { /** * @dev MAY be emitted to signal that the domain could have changed. */ event EIP712DomainChanged(); /** * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712 * signature. */ function eip712Domain() external view returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Strings.sol) pragma solidity ^0.8.20; import {Math} from "./math/Math.sol"; import {SignedMath} from "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; assembly ("memory-safe") { ptr := add(buffer, add(32, length)) } while (true) { ptr--; assembly ("memory-safe") { mstore8(ptr, byte(mod(value, 10), HEX_DIGITS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toStringSigned(int256 value) internal pure returns (string memory) { return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { uint256 localValue = value; 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_DIGITS[localValue & 0xf]; localValue >>= 4; } if (localValue != 0) { revert StringsInsufficientHexLength(value, length); } return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal * representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH); } /** * @dev Converts an `address` with fixed length of 20 bytes to its checksummed ASCII `string` hexadecimal * representation, according to EIP-55. */ function toChecksumHexString(address addr) internal pure returns (string memory) { bytes memory buffer = bytes(toHexString(addr)); // hash the hex part of buffer (skip length + 2 bytes, length 40) uint256 hashValue; assembly ("memory-safe") { hashValue := shr(96, keccak256(add(buffer, 0x22), 40)) } for (uint256 i = 41; i > 1; --i) { // possible values for buffer[i] are 48 (0) to 57 (9) and 97 (a) to 102 (f) if (hashValue & 0xf > 7 && uint8(buffer[i]) > 96) { // case shift by xoring with 0x20 buffer[i] ^= 0x20; } hashValue >>= 4; } return string(buffer); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.20; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC-1967 implementation slot: * ```solidity * contract ERC1967 { * // Define the slot. Alternatively, use the SlotDerivation library to derive the slot. * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(newImplementation.code.length > 0); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * TIP: Consider using this library along with {SlotDerivation}. */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct Int256Slot { int256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns a `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns a `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns a `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns a `Int256Slot` with member `value` located at `slot`. */ function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns a `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { assembly ("memory-safe") { r.slot := store.slot } } /** * @dev Returns a `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { assembly ("memory-safe") { r.slot := store.slot } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/Math.sol) pragma solidity ^0.8.20; import {Panic} from "../Panic.sol"; import {SafeCast} from "./SafeCast.sol"; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an success flag (no overflow). */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an success flag (no overflow). */ function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an success flag (no overflow). */ function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a success flag (no division by zero). */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero). */ function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant. * * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone. * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute * one branch when needed, making this function more expensive. */ function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) { unchecked { // branchless ternary works because: // b ^ (a ^ b) == a // b ^ 0 == b return b ^ ((a ^ b) * SafeCast.toUint(condition)); } } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return ternary(a > b, a, b); } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return ternary(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 towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. Panic.panic(Panic.DIVISION_BY_ZERO); } // The following calculation ensures accurate ceiling division without overflow. // Since a is non-zero, (a - 1) / b will not overflow. // The largest possible result occurs when (a - 1) / b is type(uint256).max, // but the largest value we can obtain is type(uint256).max - 1, which happens // when a = type(uint256).max and b = 1. unchecked { return SafeCast.toUint(a > 0) * ((a - 1) / b + 1); } } /** * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or * denominator == 0. * * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by * Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2²⁵⁶ + prod0. uint256 prod0 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0. if (denominator <= prod1) { Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW)); } /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. // Always >= 1. See https://cs.stackexchange.com/q/138556/92363. uint256 twos = denominator & (0 - denominator); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv ≡ 1 mod 2⁴. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also // works in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2⁸ inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶ inverse *= 2 - denominator * inverse; // inverse mod 2³² inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴ inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸ inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶ // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @dev Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0); } /** * @dev Calculate the modular multiplicative inverse of a number in Z/nZ. * * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0. * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible. * * If the input value is not inversible, 0 is returned. * * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}. */ function invMod(uint256 a, uint256 n) internal pure returns (uint256) { unchecked { if (n == 0) return 0; // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version) // Used to compute integers x and y such that: ax + ny = gcd(a, n). // When the gcd is 1, then the inverse of a modulo n exists and it's x. // ax + ny = 1 // ax = 1 + (-y)n // ax ≡ 1 (mod n) # x is the inverse of a modulo n // If the remainder is 0 the gcd is n right away. uint256 remainder = a % n; uint256 gcd = n; // Therefore the initial coefficients are: // ax + ny = gcd(a, n) = n // 0a + 1n = n int256 x = 0; int256 y = 1; while (remainder != 0) { uint256 quotient = gcd / remainder; (gcd, remainder) = ( // The old remainder is the next gcd to try. remainder, // Compute the next remainder. // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd // where gcd is at most n (capped to type(uint256).max) gcd - remainder * quotient ); (x, y) = ( // Increment the coefficient of a. y, // Decrement the coefficient of n. // Can overflow, but the result is casted to uint256 so that the // next value of y is "wrapped around" to a value between 0 and n - 1. x - y * int256(quotient) ); } if (gcd != 1) return 0; // No inverse exists. return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative. } } /** * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`. * * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that * `a**(p-2)` is the modular multiplicative inverse of a in Fp. * * NOTE: this function does NOT check that `p` is a prime greater than `2`. */ function invModPrime(uint256 a, uint256 p) internal view returns (uint256) { unchecked { return Math.modExp(a, p - 2, p); } } /** * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m) * * Requirements: * - modulus can't be zero * - underlying staticcall to precompile must succeed * * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make * sure the chain you're using it on supports the precompiled contract for modular exponentiation * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, * the underlying function will succeed given the lack of a revert, but the result may be incorrectly * interpreted as 0. */ function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) { (bool success, uint256 result) = tryModExp(b, e, m); if (!success) { Panic.panic(Panic.DIVISION_BY_ZERO); } return result; } /** * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m). * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying * to operate modulo 0 or if the underlying precompile reverted. * * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack * of a revert, but the result may be incorrectly interpreted as 0. */ function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) { if (m == 0) return (false, 0); assembly ("memory-safe") { let ptr := mload(0x40) // | Offset | Content | Content (Hex) | // |-----------|------------|--------------------------------------------------------------------| // | 0x00:0x1f | size of b | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x20:0x3f | size of e | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x40:0x5f | size of m | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x60:0x7f | value of b | 0x<.............................................................b> | // | 0x80:0x9f | value of e | 0x<.............................................................e> | // | 0xa0:0xbf | value of m | 0x<.............................................................m> | mstore(ptr, 0x20) mstore(add(ptr, 0x20), 0x20) mstore(add(ptr, 0x40), 0x20) mstore(add(ptr, 0x60), b) mstore(add(ptr, 0x80), e) mstore(add(ptr, 0xa0), m) // Given the result < m, it's guaranteed to fit in 32 bytes, // so we can use the memory scratch space located at offset 0. success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20) result := mload(0x00) } } /** * @dev Variant of {modExp} that supports inputs of arbitrary length. */ function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) { (bool success, bytes memory result) = tryModExp(b, e, m); if (!success) { Panic.panic(Panic.DIVISION_BY_ZERO); } return result; } /** * @dev Variant of {tryModExp} that supports inputs of arbitrary length. */ function tryModExp( bytes memory b, bytes memory e, bytes memory m ) internal view returns (bool success, bytes memory result) { if (_zeroBytes(m)) return (false, new bytes(0)); uint256 mLen = m.length; // Encode call args in result and move the free memory pointer result = abi.encodePacked(b.length, e.length, mLen, b, e, m); assembly ("memory-safe") { let dataPtr := add(result, 0x20) // Write result on top of args to avoid allocating extra memory. success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen) // Overwrite the length. // result.length > returndatasize() is guaranteed because returndatasize() == m.length mstore(result, mLen) // Set the memory pointer after the returned data. mstore(0x40, add(dataPtr, mLen)) } } /** * @dev Returns whether the provided byte array is zero. */ function _zeroBytes(bytes memory byteArray) private pure returns (bool) { for (uint256 i = 0; i < byteArray.length; ++i) { if (byteArray[i] != 0) { return false; } } return true; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded * towards zero. * * This method is based on Newton's method for computing square roots; the algorithm is restricted to only * using integer operations. */ function sqrt(uint256 a) internal pure returns (uint256) { unchecked { // Take care of easy edge cases when a == 0 or a == 1 if (a <= 1) { return a; } // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between // the current value as `ε_n = | x_n - sqrt(a) |`. // // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is // bigger than any uint256. // // By noticing that // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)` // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar // to the msb function. uint256 aa = a; uint256 xn = 1; if (aa >= (1 << 128)) { aa >>= 128; xn <<= 64; } if (aa >= (1 << 64)) { aa >>= 64; xn <<= 32; } if (aa >= (1 << 32)) { aa >>= 32; xn <<= 16; } if (aa >= (1 << 16)) { aa >>= 16; xn <<= 8; } if (aa >= (1 << 8)) { aa >>= 8; xn <<= 4; } if (aa >= (1 << 4)) { aa >>= 4; xn <<= 2; } if (aa >= (1 << 2)) { xn <<= 1; } // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1). // // We can refine our estimation by noticing that the middle of that interval minimizes the error. // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2). // This is going to be our x_0 (and ε_0) xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2) // From here, Newton's method give us: // x_{n+1} = (x_n + a / x_n) / 2 // // One should note that: // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a // = ((x_n² + a) / (2 * x_n))² - a // = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a // = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²) // = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²) // = (x_n² - a)² / (2 * x_n)² // = ((x_n² - a) / (2 * x_n))² // ≥ 0 // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n // // This gives us the proof of quadratic convergence of the sequence: // ε_{n+1} = | x_{n+1} - sqrt(a) | // = | (x_n + a / x_n) / 2 - sqrt(a) | // = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) | // = | (x_n - sqrt(a))² / (2 * x_n) | // = | ε_n² / (2 * x_n) | // = ε_n² / | (2 * x_n) | // // For the first iteration, we have a special case where x_0 is known: // ε_1 = ε_0² / | (2 * x_0) | // ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2))) // ≤ 2**(2*e-4) / (3 * 2**(e-1)) // ≤ 2**(e-3) / 3 // ≤ 2**(e-3-log2(3)) // ≤ 2**(e-4.5) // // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n: // ε_{n+1} = ε_n² / | (2 * x_n) | // ≤ (2**(e-k))² / (2 * 2**(e-1)) // ≤ 2**(2*e-2*k) / 2**e // ≤ 2**(e-2*k) xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5) -- special case, see above xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9) -- general case with k = 4.5 xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18) -- general case with k = 9 xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36) -- general case with k = 18 xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72) -- general case with k = 36 xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144) -- general case with k = 72 // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either // sqrt(a) or sqrt(a) + 1. return xn - SafeCast.toUint(xn > a / xn); } } /** * @dev Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; uint256 exp; unchecked { exp = 128 * SafeCast.toUint(value > (1 << 128) - 1); value >>= exp; result += exp; exp = 64 * SafeCast.toUint(value > (1 << 64) - 1); value >>= exp; result += exp; exp = 32 * SafeCast.toUint(value > (1 << 32) - 1); value >>= exp; result += exp; exp = 16 * SafeCast.toUint(value > (1 << 16) - 1); value >>= exp; result += exp; exp = 8 * SafeCast.toUint(value > (1 << 8) - 1); value >>= exp; result += exp; exp = 4 * SafeCast.toUint(value > (1 << 4) - 1); value >>= exp; result += exp; exp = 2 * SafeCast.toUint(value > (1 << 2) - 1); value >>= exp; result += exp; result += SafeCast.toUint(value > 1); } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; uint256 isGt; unchecked { isGt = SafeCast.toUint(value > (1 << 128) - 1); value >>= isGt * 128; result += isGt * 16; isGt = SafeCast.toUint(value > (1 << 64) - 1); value >>= isGt * 64; result += isGt * 8; isGt = SafeCast.toUint(value > (1 << 32) - 1); value >>= isGt * 32; result += isGt * 4; isGt = SafeCast.toUint(value > (1 << 16) - 1); value >>= isGt * 16; result += isGt * 2; result += SafeCast.toUint(value > (1 << 8) - 1); } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.20; import {SafeCast} from "./SafeCast.sol"; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant. * * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone. * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute * one branch when needed, making this function more expensive. */ function ternary(bool condition, int256 a, int256 b) internal pure returns (int256) { unchecked { // branchless ternary works because: // b ^ (a ^ b) == a // b ^ 0 == b return b ^ ((a ^ b) * int256(SafeCast.toUint(condition))); } } /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return ternary(a > b, a, b); } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return ternary(a < b, a, b); } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // Formula from the "Bit Twiddling Hacks" by Sean Eron Anderson. // Since `n` is a signed integer, the generated bytecode will use the SAR opcode to perform the right shift, // taking advantage of the most significant (or "sign" bit) in two's complement representation. // This opcode adds new most significant bits set to the value of the previous most significant bit. As a result, // the mask will either be `bytes32(0)` (if n is positive) or `~bytes32(0)` (if n is negative). int256 mask = n >> 255; // A `bytes32(0)` mask leaves the input unchanged, while a `~bytes32(0)` mask complements it. return uint256((n + mask) ^ mask); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol) pragma solidity ^0.8.20; /** * @dev Helper library for emitting standardized panic codes. * * ```solidity * contract Example { * using Panic for uint256; * * // Use any of the declared internal constants * function foo() { Panic.GENERIC.panic(); } * * // Alternatively * function foo() { Panic.panic(Panic.GENERIC); } * } * ``` * * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil]. * * _Available since v5.1._ */ // slither-disable-next-line unused-state library Panic { /// @dev generic / unspecified error uint256 internal constant GENERIC = 0x00; /// @dev used by the assert() builtin uint256 internal constant ASSERT = 0x01; /// @dev arithmetic underflow or overflow uint256 internal constant UNDER_OVERFLOW = 0x11; /// @dev division or modulo by zero uint256 internal constant DIVISION_BY_ZERO = 0x12; /// @dev enum conversion error uint256 internal constant ENUM_CONVERSION_ERROR = 0x21; /// @dev invalid encoding in storage uint256 internal constant STORAGE_ENCODING_ERROR = 0x22; /// @dev empty array pop uint256 internal constant EMPTY_ARRAY_POP = 0x31; /// @dev array out of bounds access uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32; /// @dev resource error (too large allocation or too large array) uint256 internal constant RESOURCE_ERROR = 0x41; /// @dev calling invalid internal function uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51; /// @dev Reverts with a panic code. Recommended to use with /// the internal constants with predefined codes. function panic(uint256 code) internal pure { assembly ("memory-safe") { mstore(0x00, 0x4e487b71) mstore(0x20, code) revert(0x1c, 0x24) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.20; /** * @dev Wrappers over Solidity's uintXX/intXX/bool 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. */ library SafeCast { /** * @dev Value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value); /** * @dev An int value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedIntToUint(int256 value); /** * @dev Value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedIntDowncast(uint8 bits, int256 value); /** * @dev An uint value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedUintToInt(uint256 value); /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits */ function toUint248(uint256 value) internal pure returns (uint248) { if (value > type(uint248).max) { revert SafeCastOverflowedUintDowncast(248, value); } return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits */ function toUint240(uint256 value) internal pure returns (uint240) { if (value > type(uint240).max) { revert SafeCastOverflowedUintDowncast(240, value); } return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits */ function toUint232(uint256 value) internal pure returns (uint232) { if (value > type(uint232).max) { revert SafeCastOverflowedUintDowncast(232, value); } return uint232(value); } /** * @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) { if (value > type(uint224).max) { revert SafeCastOverflowedUintDowncast(224, value); } return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits */ function toUint216(uint256 value) internal pure returns (uint216) { if (value > type(uint216).max) { revert SafeCastOverflowedUintDowncast(216, value); } return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits */ function toUint208(uint256 value) internal pure returns (uint208) { if (value > type(uint208).max) { revert SafeCastOverflowedUintDowncast(208, value); } return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits */ function toUint200(uint256 value) internal pure returns (uint200) { if (value > type(uint200).max) { revert SafeCastOverflowedUintDowncast(200, value); } return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits */ function toUint192(uint256 value) internal pure returns (uint192) { if (value > type(uint192).max) { revert SafeCastOverflowedUintDowncast(192, value); } return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits */ function toUint184(uint256 value) internal pure returns (uint184) { if (value > type(uint184).max) { revert SafeCastOverflowedUintDowncast(184, value); } return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits */ function toUint176(uint256 value) internal pure returns (uint176) { if (value > type(uint176).max) { revert SafeCastOverflowedUintDowncast(176, value); } return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits */ function toUint168(uint256 value) internal pure returns (uint168) { if (value > type(uint168).max) { revert SafeCastOverflowedUintDowncast(168, value); } return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits */ function toUint160(uint256 value) internal pure returns (uint160) { if (value > type(uint160).max) { revert SafeCastOverflowedUintDowncast(160, value); } return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits */ function toUint152(uint256 value) internal pure returns (uint152) { if (value > type(uint152).max) { revert SafeCastOverflowedUintDowncast(152, value); } return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits */ function toUint144(uint256 value) internal pure returns (uint144) { if (value > type(uint144).max) { revert SafeCastOverflowedUintDowncast(144, value); } return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits */ function toUint136(uint256 value) internal pure returns (uint136) { if (value > type(uint136).max) { revert SafeCastOverflowedUintDowncast(136, value); } return uint136(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) { if (value > type(uint128).max) { revert SafeCastOverflowedUintDowncast(128, value); } return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits */ function toUint120(uint256 value) internal pure returns (uint120) { if (value > type(uint120).max) { revert SafeCastOverflowedUintDowncast(120, value); } return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits */ function toUint112(uint256 value) internal pure returns (uint112) { if (value > type(uint112).max) { revert SafeCastOverflowedUintDowncast(112, value); } return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits */ function toUint104(uint256 value) internal pure returns (uint104) { if (value > type(uint104).max) { revert SafeCastOverflowedUintDowncast(104, value); } return uint104(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) { if (value > type(uint96).max) { revert SafeCastOverflowedUintDowncast(96, value); } return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits */ function toUint88(uint256 value) internal pure returns (uint88) { if (value > type(uint88).max) { revert SafeCastOverflowedUintDowncast(88, value); } return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits */ function toUint80(uint256 value) internal pure returns (uint80) { if (value > type(uint80).max) { revert SafeCastOverflowedUintDowncast(80, value); } return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits */ function toUint72(uint256 value) internal pure returns (uint72) { if (value > type(uint72).max) { revert SafeCastOverflowedUintDowncast(72, value); } return uint72(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) { if (value > type(uint64).max) { revert SafeCastOverflowedUintDowncast(64, value); } return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits */ function toUint56(uint256 value) internal pure returns (uint56) { if (value > type(uint56).max) { revert SafeCastOverflowedUintDowncast(56, value); } return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits */ function toUint48(uint256 value) internal pure returns (uint48) { if (value > type(uint48).max) { revert SafeCastOverflowedUintDowncast(48, value); } return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits */ function toUint40(uint256 value) internal pure returns (uint40) { if (value > type(uint40).max) { revert SafeCastOverflowedUintDowncast(40, value); } return uint40(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) { if (value > type(uint32).max) { revert SafeCastOverflowedUintDowncast(32, value); } return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits */ function toUint24(uint256 value) internal pure returns (uint24) { if (value > type(uint24).max) { revert SafeCastOverflowedUintDowncast(24, value); } return uint24(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) { if (value > type(uint16).max) { revert SafeCastOverflowedUintDowncast(16, value); } 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) { if (value > type(uint8).max) { revert SafeCastOverflowedUintDowncast(8, value); } 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) { if (value < 0) { revert SafeCastOverflowedIntToUint(value); } return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(248, value); } } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(240, value); } } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(232, value); } } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(224, value); } } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(216, value); } } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(208, value); } } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(200, value); } } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(192, value); } } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(184, value); } } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(176, value); } } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(168, value); } } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(160, value); } } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(152, value); } } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(144, value); } } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(136, 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 */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(128, value); } } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(120, value); } } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(112, value); } } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(104, value); } } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(96, value); } } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(88, value); } } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(80, value); } } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(72, 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 */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(64, value); } } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(56, value); } } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(48, value); } } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(40, 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 */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(32, value); } } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(24, 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 */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(16, 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 */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(8, 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 if (value > uint256(type(int256).max)) { revert SafeCastOverflowedUintToInt(value); } return int256(value); } /** * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump. */ function toUint(bool b) internal pure returns (uint256 u) { assembly ("memory-safe") { u := iszero(iszero(b)) } } }
{ "remappings": [ "@openzeppelin-contracts-5.1.0/=dependencies/@openzeppelin-contracts-5.1.0/", "forge-std-1.9.4/=dependencies/forge-std-1.9.4/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "evmVersion": "cancun", "viaIR": false }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_inflationAdmin","type":"address"},{"internalType":"address","name":"_inflationBeneficiary","type":"address"},{"internalType":"address","name":"_distributor","type":"address"},{"internalType":"uint256","name":"_unlockTime","type":"uint256"},{"internalType":"address","name":"_unlocker","type":"address"},{"internalType":"address","name":"_lockExemptionAdmin","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ECDSAInvalidSignature","type":"error"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"name":"ECDSAInvalidSignatureLength","type":"error"},{"inputs":[{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"ECDSAInvalidSignatureS","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"ERC2612ExpiredSignature","type":"error"},{"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC2612InvalidSigner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"currentNonce","type":"uint256"}],"name":"InvalidAccountNonce","type":"error"},{"inputs":[],"name":"InvalidShortString","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"InflationChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"InflationDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"MintCapacityDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newHolder","type":"address"},{"indexed":false,"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"RoleChangeCompleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newHolder","type":"address"},{"indexed":false,"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"RoleChangeStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"INFLATION_ADMIN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"INFLATION_BENEFICIARY","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LOCK_EXEMPTION_ADMIN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_INFLATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNLOCKER","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"acceptRole","outputs":[],"stateMutability":"nonpayable","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":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"changeInflation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newRoleOwner","type":"address"},{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"changeRoleHolder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"distributeInflation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"distributeMintCapacity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distributedSupplyCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"inflationFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isUnlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastMintCapacityIncrease","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"locked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mintCapacity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"bytes32","name":"","type":"bytes32"}],"name":"pendingRoleHolder","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":"renounceInflationAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceInflationBeneficiary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceLockExemptionAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"roleHolder","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bool","name":"value","type":"bool"}],"name":"setLockExemption","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":"value","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":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unlockAndRenounceUnlocker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unlockTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
610180604052600e805460ff1916600117905534801561001d575f5ffd5b5060405161302938038061302983398101604081905261003c9161041e565b6040805180820190915260018152603160f81b602082015288908190818a60036100668382610561565b5060046100738282610561565b50610083915083905060056102ee565b610120526100928160066102ee565b61014052815160208084019190912060e052815190820120610100524660a05261011e60e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b60805250503060c0525087515f03610134575f5ffd5b86515f03610140575f5ffd5b6001600160a01b038616610152575f5ffd5b6001600160a01b038516610164575f5ffd5b6001600160a01b038416610176575f5ffd5b428311610181575f5ffd5b61018f426303b5380061062f565b8310610199575f5ffd5b6001600160a01b0382166101ab575f5ffd5b6001600160a01b0381166101bd575f5ffd5b5f6101ca6012600a610725565b6101d9906402540be40061073a565b6001600160a01b039586165f908152600d60209081526040808320849055600a9390935542600b55600c8290557fb521cc951ed9755340601b8a7f63a0bd6c89110fdd21850902bb60ab4fc3f7b080549a89166001600160a01b03199b8c161790557fef99cce924c96d8dbe2300db77854d44fa213667cf26fababda543a2fa80b5c98054998916998b16999099179098557ffe18803ae90e6065a13f80d13c726a612a5f4bde35c678d0a6892ebcb7910d758054958816958a16959095179094557fad46a584c12dee19dd3315865dd8f658321644e2fc0d8ec87376d55e731dfd9c805493909616929097169190911790935561016091909152600f9092525020805460ff19166001179055506107a99050565b5f6020835110156103095761030283610320565b905061031a565b816103148482610561565b5060ff90505b92915050565b5f5f829050601f81511115610353578260405163305a27a960e01b815260040161034a9190610751565b60405180910390fd5b805161035e82610786565b179392505050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f830112610389575f5ffd5b81516001600160401b038111156103a2576103a2610366565b604051601f8201601f19908116603f011681016001600160401b03811182821017156103d0576103d0610366565b6040528181528382016020018510156103e7575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b80516001600160a01b0381168114610419575f5ffd5b919050565b5f5f5f5f5f5f5f5f610100898b031215610436575f5ffd5b88516001600160401b0381111561044b575f5ffd5b6104578b828c0161037a565b60208b015190995090506001600160401b03811115610474575f5ffd5b6104808b828c0161037a565b97505061048f60408a01610403565b955061049d60608a01610403565b94506104ab60808a01610403565b935060a089015192506104c060c08a01610403565b91506104ce60e08a01610403565b90509295985092959890939650565b600181811c908216806104f157607f821691505b60208210810361050f57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561055c57805f5260205f20601f840160051c8101602085101561053a5750805b601f840160051c820191505b81811015610559575f8155600101610546565b50505b505050565b81516001600160401b0381111561057a5761057a610366565b61058e8161058884546104dd565b84610515565b6020601f8211600181146105c0575f83156105a95750848201515b5f19600385901b1c1916600184901b178455610559565b5f84815260208120601f198516915b828110156105ef57878501518255602094850194600190920191016105cf565b508482101561060c57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561031a5761031a61061b565b6001815b600184111561067d578085048111156106615761066161061b565b600184161561066f57908102905b60019390931c928002610646565b935093915050565b5f826106935750600161031a565b8161069f57505f61031a565b81600181146106b557600281146106bf576106db565b600191505061031a565b60ff8411156106d0576106d061061b565b50506001821b61031a565b5060208310610133831016604e8410600b84101617156106fe575081810a61031a565b61070a5f198484610642565b805f190482111561071d5761071d61061b565b029392505050565b5f61073360ff841683610685565b9392505050565b808202811582820484141761031a5761031a61061b565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b8051602080830151919081101561050f575f1960209190910360031b1b16919050565b60805160a05160c05160e051610100516101205161014051610160516128176108125f395f81816102c101528181610dcb01526117a601525f61165401525f61162701525f61159c01525f61157401525f6114cf01525f6114f901525f61152301526128175ff3fe608060405234801561000f575f5ffd5b5060043610610234575f3560e01c806370a0823111610135578063c23e9707116100b4578063dd62ed3e11610079578063dd62ed3e146104ee578063e4a063c314610526578063ed3de2e31461052f578063f8205ebb14610543578063fdb04bbf14610556575f5ffd5b8063c23e9707146104aa578063c373fee3146104b3578063cf309012146104bb578063d18ced1d146104c8578063d505accf146104db575f5ffd5b8063866558e9116100fa578063866558e914610440578063886eaddc1461045f5780639286c9311461046757806395d89b411461048f578063a9059cbb14610497575f5ffd5b806370a08231146103bb57806378150ff8146103e35780637ecebe001461040a5780638380edb71461041d57806384b0196e14610425575f5ffd5b8063343b3cde116101c157806340c10f191161018657806340c10f191461037057806344dd936c146103835780634d3591ec1461038c5780634e5a7680146103a05780635cfd8a65146103a8575f5ffd5b8063343b3cde14610305578063355274ea146103455780633644e5151461034d57806336fc1787146103555780633f5090ee14610368575f5ffd5b80631fe2256b116102075780631fe2256b1461029557806323b872dd146102a9578063251c1aa3146102bc5780632b911eaf146102e3578063313ce567146102f6575f5ffd5b806306fdde0314610238578063095ea7b31461025657806318160ddd146102795780631bf544431461028b575b5f5ffd5b610240610565565b60405161024d91906123d1565b60405180910390f35b610269610264366004612405565b6105f5565b604051901515815260200161024d565b6002545b60405190815260200161024d565b61029361060e565b005b61027d5f5160206127c25f395f51905f5281565b6102696102b736600461242d565b610715565b61027d7f000000000000000000000000000000000000000000000000000000000000000081565b6102936102f1366004612467565b610738565b6040516012815260200161024d565b61032d6103133660046124a0565b60086020525f90815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200161024d565b61027d6107c3565b61027d6107de565b6102936103633660046124a0565b6107e7565b6102936108a1565b61029361037e366004612405565b6109a3565b61027d600a5481565b61027d5f5160206127a25f395f51905f5281565b610293610a2f565b6102936103b63660046124a0565b610c47565b61027d6103c93660046124b7565b6001600160a01b03165f9081526020819052604090205490565b61027d7f54c9b4c80715cee47dde7f1b62b0c6cd06cacb92458efa077def5f27d03415d481565b61027d6104183660046124b7565b610dab565b610269610dc8565b61042d610dfd565b60405161024d97969594939291906124d0565b61027d61044e3660046124b7565b600d6020525f908152604090205481565b610293610e3f565b61032d6104753660046124a0565b60096020525f90815260409020546001600160a01b031681565b610240610f66565b6102696104a5366004612405565b610f75565b61027d600b5481565b610293610f82565b600e546102699060ff1681565b6102936104d6366004612405565b61104e565b6102936104e9366004612566565b6110e5565b61027d6104fc3660046125d3565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b61027d600c5481565b61027d5f5160206127625f395f51905f5281565b610293610551366004612405565b61121b565b61027d6733ea71cbbb42b10481565b60606003805461057490612604565b80601f01602080910402602001604051908101604052809291908181526020018280546105a090612604565b80156105eb5780601f106105c2576101008083540402835291602001916105eb565b820191905f5260205f20905b8154815290600101906020018083116105ce57829003601f168201915b5050505050905090565b5f33610602818585611357565b60019150505b92915050565b5f5160206127c25f395f51905f525f81905260086020527fad46a584c12dee19dd3315865dd8f658321644e2fc0d8ec87376d55e731dfd9c546001600160a01b031633146106775760405162461bcd60e51b815260040161066e9061263c565b60405180910390fd5b5f5160206127c25f395f51905f525f8181527fad46a584c12dee19dd3315865dd8f658321644e2fc0d8ec87376d55e731dfd9c80546001600160a01b0319908116909155600960209081527f2cfeb242b3e2a551873efb7f5409af68ae82192c4daa647b798f6ffd68dbdbeb805490921690915560408051928352908201929092525f5160206127825f395f51905f5291015b60405180910390a150565b5f33610722858285611369565b61072d8585856113e4565b506001949350505050565b5f5160206127c25f395f51905f525f81905260086020527fad46a584c12dee19dd3315865dd8f658321644e2fc0d8ec87376d55e731dfd9c546001600160a01b031633146107985760405162461bcd60e51b815260040161066e9061263c565b506001600160a01b03919091165f908152600f60205260409020805460ff1916911515919091179055565b5f6107cc611441565b600a546107d9919061267a565b905090565b5f6107d96114c3565b5f818152600960205260409020546001600160a01b031633146108435760405162461bcd60e51b81526020600482015260146024820152732737ba103732bb903937b632903437b63232b91760611b604482015260640161066e565b5f8181526009602090815260408083208054600884529382902080546001600160a01b039586166001600160a01b0319918216178255825416909155548151931683529082018390525f5160206127825f395f51905f52910161070a565b5f5160206127a25f395f51905f525f81905260086020525f5160206127425f395f51905f52546001600160a01b031633146108ee5760405162461bcd60e51b815260040161066e9061263c565b5f5160206127a25f395f51905f525f5260096020527ff20486fe1a2a0fc5e4d4f4bd2ea802b01028bd0d3680182b6ac378d9234898a7546001600160a01b03161561094b5760405162461bcd60e51b815260040161066e9061268d565b5f5160206127a25f395f51905f525f818152600860209081525f5160206127425f395f51905f5280546001600160a01b031916905560408051928352908201929092525f5160206127825f395f51905f52910161070a565b335f908152600d60205260409020548111156109fd5760405162461bcd60e51b81526020600482015260196024820152782737ba1032b737bab3b41036b4b73a1031b0b830b1b4ba3c9760391b604482015260640161066e565b335f908152600d602052604081208054839290610a1b9084906126c4565b90915550610a2b905082826115ec565b5050565b5f5160206127625f395f51905f525f81905260086020525f5160206127225f395f51905f52546001600160a01b03163314610a7c5760405162461bcd60e51b815260040161066e9061263c565b5f5160206127625f395f51905f525f5260096020527f3f9d107ab11d3fd2cdd10e4d1851944c81a2523e5341fb140b585ded940719bf546001600160a01b031615610ad95760405162461bcd60e51b815260040161066e9061268d565b600c5415610b1f5760405162461bcd60e51b815260206004820152601360248201527224b7333630ba34b7b7103737ba103d32b9379760691b604482015260640161066e565b5f5160206127a25f395f51905f525f5260086020525f5160206127425f395f51905f52546001600160a01b031615610b925760405162461bcd60e51b815260206004820152601660248201527524b7333630ba34b7b71030b236b4b7103737ba10181760511b604482015260640161066e565b5f5160206127a25f395f51905f525f5260096020527ff20486fe1a2a0fc5e4d4f4bd2ea802b01028bd0d3680182b6ac378d9234898a7546001600160a01b031615610bef5760405162461bcd60e51b815260040161066e9061268d565b5f5160206127625f395f51905f525f818152600860209081525f5160206127225f395f51905f5280546001600160a01b031916905560408051928352908201929092525f5160206127825f395f51905f52910161070a565b5f5160206127a25f395f51905f525f81905260086020525f5160206127425f395f51905f52546001600160a01b03163314610c945760405162461bcd60e51b815260040161066e9061263c565b5f5160206127625f395f51905f525f5260086020525f5160206127225f395f51905f52546001600160a01b0316610d0d5760405162461bcd60e51b815260206004820152601960248201527f4e6f20696e666c6174696f6e2062656e65666963696172792e00000000000000604482015260640161066e565b6733ea71cbbb42b104821115610d5c5760405162461bcd60e51b815260206004820152601460248201527324b7333630ba34b7b7103a37b7903630b933b29760611b604482015260640161066e565b610d64610f82565b600c80549083905560408051828152602081018590527f0c347accb94360b551ed917758bc5358525405e1b91ac5407913b81d4c3e86b691015b60405180910390a1505050565b6001600160a01b0381165f90815260076020526040812054610608565b5f7f00000000000000000000000000000000000000000000000000000000000000004211806107d9575050600e5460ff161590565b5f6060805f5f5f6060610e0e611620565b610e1661164d565b604080515f80825260208201909252600f60f81b9b939a50919850469750309650945092509050565b7f54c9b4c80715cee47dde7f1b62b0c6cd06cacb92458efa077def5f27d03415d45f81905260086020527ffe18803ae90e6065a13f80d13c726a612a5f4bde35c678d0a6892ebcb7910d75546001600160a01b03163314610eb25760405162461bcd60e51b815260040161066e9061263c565b600e805460ff191690557f54c9b4c80715cee47dde7f1b62b0c6cd06cacb92458efa077def5f27d03415d45f8181527ffe18803ae90e6065a13f80d13c726a612a5f4bde35c678d0a6892ebcb7910d7580546001600160a01b0319908116909155600960209081527ffe4fa762c7c70a39e2a3cadfc51d39dffde606fcc63dc244c53ce43f7dbb091a805490921690915560408051928352908201929092525f5160206127825f395f51905f52910161070a565b60606004805461057490612604565b5f336106028185856113e4565b5f610f8b611441565b5f5160206127625f395f51905f525f90815260086020525f5160206127225f395f51905f5254600a80549394506001600160a01b0390911692849290610fd290849061267a565b90915550506001600160a01b0381165f908152600d602052604081208054849290610ffe90849061267a565b909155505042600b55604080516001600160a01b0383168152602081018490527f853d3d7e29278422c75860e77aff784c6587d84b19d0e212f562b91f60b3390f91015b60405180910390a15050565b5f8181526008602052604090205481906001600160a01b031633146110855760405162461bcd60e51b815260040161066e9061263c565b5f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03871690811790915582519081529081018490527fe925262108dd98ff133f1ba628eb25c76de057168ddd49910ab8eaba84b792fe9101610d9e565b834211156111095760405163313c898160e11b81526004810185905260240161066e565b5f7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886111548c6001600160a01b03165f90815260076020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090505f6111ae8261167a565b90505f6111bd828787876116a6565b9050896001600160a01b0316816001600160a01b031614611204576040516325c0072360e11b81526001600160a01b0380831660048301528b16602482015260440161066e565b61120f8a8a8a611357565b50505050505050505050565b6001600160a01b0382166112685760405162461bcd60e51b815260206004820152601460248201527353656e64696e6720746f2030206164647265737360601b604482015260640161066e565b335f908152600d60205260409020548111156112c25760405162461bcd60e51b81526020600482015260196024820152782737ba1032b737bab3b41036b4b73a1031b0b830b1b4ba3c9760391b604482015260640161066e565b335f908152600d6020526040812080548392906112e09084906126c4565b90915550506001600160a01b0382165f908152600d60205260408120805483929061130c90849061267a565b9091555050604080513381526001600160a01b03841660208201529081018290527f447b0379ed6803974a36a2a794fced1ee7777a67630a29f50f88924f80876a0490606001611042565b61136483838360016116d2565b505050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f1981146113de57818110156113d057604051637dc7a0d960e11b81526001600160a01b0384166004820152602481018290526044810183905260640161066e565b6113de84848484035f6116d2565b50505050565b6001600160a01b03831661140d57604051634b637e8f60e11b81525f600482015260240161066e565b6001600160a01b0382166114365760405163ec442f0560e01b81525f600482015260240161066e565b6113648383836117a4565b5f42600b540361145057505f90565b5f600b544261145f91906126c4565b90505f6114876301e1338083600c5461147891906126d7565b61148291906126ee565b611875565b90505f670de0b6b3a7640000600a54836114a191906126d7565b6114ab91906126ee565b9050600a54816114bb91906126c4565b935050505090565b5f306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561151b57507f000000000000000000000000000000000000000000000000000000000000000046145b1561154557507f000000000000000000000000000000000000000000000000000000000000000090565b6107d9604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b6001600160a01b0382166116155760405163ec442f0560e01b81525f600482015260240161066e565b610a2b5f83836117a4565b60606107d97f00000000000000000000000000000000000000000000000000000000000000006005611ff0565b60606107d97f00000000000000000000000000000000000000000000000000000000000000006006611ff0565b5f6106086116866114c3565b8360405161190160f01b8152600281019290925260228201526042902090565b5f5f5f5f6116b688888888612099565b9250925092506116c68282612161565b50909695505050505050565b6001600160a01b0384166116fb5760405163e602df0560e01b81525f600482015260240161066e565b6001600160a01b03831661172457604051634a1406b160e11b81525f600482015260240161066e565b6001600160a01b038085165f90815260016020908152604080832093871683529290522082905580156113de57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161179691815260200190565b60405180910390a350505050565b7f00000000000000000000000000000000000000000000000000000000000000004211806117d55750600e5460ff16155b156117e557611364838383612219565b6001600160a01b0383165f908152600f602052604090205460ff16801561181457506001600160a01b03831633145b1561182457611364838383612219565b6001600160a01b03831661183d57611364838383612219565b60405162461bcd60e51b815260206004820152600d60248201526c2a37b5b2b7103637b1b5b2b21760991b604482015260640161066e565b5f61188c670de0b6b3a7640000604084901b6126ee565b9150600160bf1b905067ff0000000000000082161561199d576780000000000000008216156118c45768016a09e667f3bcc9090260401c5b6740000000000000008216156118e3576801306fe0a31b7152df0260401c5b672000000000000000821615611902576801172b83c7d517adce0260401c5b6710000000000000008216156119215768010b5586cf9890f62a0260401c5b670800000000000000821615611940576801059b0d31585743ae0260401c5b67040000000000000082161561195f57680102c9a3e778060ee70260401c5b67020000000000000082161561197e5768010163da9fb33356d80260401c5b67010000000000000082161561199d57680100b1afa5abcbed610260401c5b66ff000000000000821615611a9c5766800000000000008216156119ca5768010058c86da1c09ea20260401c5b66400000000000008216156119e8576801002c605e2e8cec500260401c5b6620000000000000821615611a0657680100162f3904051fa10260401c5b6610000000000000821615611a24576801000b175effdc76ba0260401c5b6608000000000000821615611a4257680100058ba01fb9f96d0260401c5b6604000000000000821615611a605768010002c5cc37da94920260401c5b6602000000000000821615611a7e576801000162e525ee05470260401c5b6601000000000000821615611a9c5768010000b17255775c040260401c5b65ff0000000000821615611b925765800000000000821615611ac7576801000058b91b5bc9ae0260401c5b65400000000000821615611ae457680100002c5c89d5ec6d0260401c5b65200000000000821615611b015768010000162e43f4f8310260401c5b65100000000000821615611b1e57680100000b1721bcfc9a0260401c5b65080000000000821615611b3b5768010000058b90cf1e6e0260401c5b65040000000000821615611b58576801000002c5c863b73f0260401c5b65020000000000821615611b7557680100000162e430e5a20260401c5b65010000000000821615611b92576801000000b1721835510260401c5b64ff00000000821615611c7f57648000000000821615611bbb57680100000058b90c0b490260401c5b644000000000821615611bd75768010000002c5c8601cc0260401c5b642000000000821615611bf3576801000000162e42fff00260401c5b641000000000821615611c0f5768010000000b17217fbb0260401c5b640800000000821615611c2b576801000000058b90bfce0260401c5b640400000000821615611c4757680100000002c5c85fe30260401c5b640200000000821615611c635768010000000162e42ff10260401c5b640100000000821615611c7f57680100000000b17217f80260401c5b63ff000000821615611d63576380000000821615611ca65768010000000058b90bfc0260401c5b6340000000821615611cc1576801000000002c5c85fe0260401c5b6320000000821615611cdc57680100000000162e42ff0260401c5b6310000000821615611cf7576801000000000b17217f0260401c5b6308000000821615611d1257680100000000058b90c00260401c5b6304000000821615611d2d5768010000000002c5c8600260401c5b6302000000821615611d48576801000000000162e4300260401c5b6301000000821615611d635768010000000000b172180260401c5b62ff0000821615611e3e5762800000821615611d88576801000000000058b90c0260401c5b62400000821615611da257680100000000002c5c860260401c5b62200000821615611dbc5768010000000000162e430260401c5b62100000821615611dd657680100000000000b17210260401c5b62080000821615611df05768010000000000058b910260401c5b62040000821615611e0a576801000000000002c5c80260401c5b62020000821615611e2457680100000000000162e40260401c5b62010000821615611e3e576801000000000000b1720260401c5b61ff00821615611f1057618000821615611e6157680100000000000058b90260401c5b614000821615611e7a5768010000000000002c5d0260401c5b612000821615611e93576801000000000000162e0260401c5b611000821615611eac5768010000000000000b170260401c5b610800821615611ec5576801000000000000058c0260401c5b610400821615611ede57680100000000000002c60260401c5b610200821615611ef757680100000000000001630260401c5b610100821615611f1057680100000000000000b10260401c5b60ff821615611fd9576080821615611f3157680100000000000000590260401c5b6040821615611f49576801000000000000002c0260401c5b6020821615611f6157680100000000000000160260401c5b6010821615611f79576801000000000000000b0260401c5b6008821615611f9157680100000000000000060260401c5b6004821615611fa957680100000000000000030260401c5b6002821615611fc157680100000000000000010260401c5b6001821615611fd957680100000000000000010260401c5b670de0b6b3a76400000260409190911c60bf031c90565b606060ff831461200a576120038361233f565b9050610608565b81805461201690612604565b80601f016020809104026020016040519081016040528092919081815260200182805461204290612604565b801561208d5780601f106120645761010080835404028352916020019161208d565b820191905f5260205f20905b81548152906001019060200180831161207057829003601f168201915b50505050509050610608565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08411156120d257505f91506003905082612157565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015612123573d5f5f3e3d5ffd5b5050604051601f1901519150506001600160a01b03811661214e57505f925060019150829050612157565b92505f91508190505b9450945094915050565b5f8260038111156121745761217461270d565b0361217d575050565b60018260038111156121915761219161270d565b036121af5760405163f645eedf60e01b815260040160405180910390fd5b60028260038111156121c3576121c361270d565b036121e45760405163fce698f760e01b81526004810182905260240161066e565b60038260038111156121f8576121f861270d565b03610a2b576040516335e2f38360e21b81526004810182905260240161066e565b6001600160a01b038316612243578060025f828254612238919061267a565b909155506122b39050565b6001600160a01b0383165f90815260208190526040902054818110156122955760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640161066e565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b0382166122cf576002805482900390556122ed565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161233291815260200190565b60405180910390a3505050565b60605f61234b8361237c565b6040805160208082528183019092529192505f91906020820181803683375050509182525060208101929092525090565b5f60ff8216601f81111561060857604051632cd44ac360e21b815260040160405180910390fd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f6123e360208301846123a3565b9392505050565b80356001600160a01b0381168114612400575f5ffd5b919050565b5f5f60408385031215612416575f5ffd5b61241f836123ea565b946020939093013593505050565b5f5f5f6060848603121561243f575f5ffd5b612448846123ea565b9250612456602085016123ea565b929592945050506040919091013590565b5f5f60408385031215612478575f5ffd5b612481836123ea565b915060208301358015158114612495575f5ffd5b809150509250929050565b5f602082840312156124b0575f5ffd5b5035919050565b5f602082840312156124c7575f5ffd5b6123e3826123ea565b60ff60f81b8816815260e060208201525f6124ee60e08301896123a3565b828103604084015261250081896123a3565b606084018890526001600160a01b038716608085015260a0840186905283810360c0850152845180825260208087019350909101905f5b81811015612555578351835260209384019390920191600101612537565b50909b9a5050505050505050505050565b5f5f5f5f5f5f5f60e0888a03121561257c575f5ffd5b612585886123ea565b9650612593602089016123ea565b95506040880135945060608801359350608088013560ff811681146125b6575f5ffd5b9699959850939692959460a0840135945060c09093013592915050565b5f5f604083850312156125e4575f5ffd5b6125ed836123ea565b91506125fb602084016123ea565b90509250929050565b600181811c9082168061261857607f821691505b60208210810361263657634e487b7160e01b5f52602260045260245ffd5b50919050565b60208082526010908201526f2737ba103937b632903437b63232b91760811b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561060857610608612666565b6020808252601a908201527f526f6c65207472616e7366657220696e2070726f67726573732e000000000000604082015260600190565b8181038181111561060857610608612666565b808202811582820484141761060857610608612666565b5f8261270857634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52602160045260245ffdfeef99cce924c96d8dbe2300db77854d44fa213667cf26fababda543a2fa80b5c9b521cc951ed9755340601b8a7f63a0bd6c89110fdd21850902bb60ab4fc3f7b00ec560a57e72e1ad7c888fa95b5a74170e915e2173a447b50c3cefd1fe82f510f54f5cceb448ef806753e004d4516a584e5d52ee04e57717762f87bd2cce6e9bf8541c194a0b2749cdcc163377d32fae37700c72cef0857ad24aa49792741b2ef8bea3b6ac1f7ecd96cf424727980e36f4569781fe0559ce9088bb153106d262a2646970667358221220885582c1b5ccc42c614c537866554764f343616c0e35e434f7713cc3dbd7c79464736f6c634300081c00330000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000014000000000000000000000000092d8ce89ff02c640daf0b7c23d497ccf1880c39000000000000000000000000092d8ce89ff02c640daf0b7c23d497ccf1880c39000000000000000000000000092d8ce89ff02c640daf0b7c23d497ccf1880c390000000000000000000000000000000000000000000000000000000006998850000000000000000000000000092d8ce89ff02c640daf0b7c23d497ccf1880c39000000000000000000000000092d8ce89ff02c640daf0b7c23d497ccf1880c39000000000000000000000000000000000000000000000000000000000000000144b6174616e61204e6574776f726b20546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000034b41540000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561000f575f5ffd5b5060043610610234575f3560e01c806370a0823111610135578063c23e9707116100b4578063dd62ed3e11610079578063dd62ed3e146104ee578063e4a063c314610526578063ed3de2e31461052f578063f8205ebb14610543578063fdb04bbf14610556575f5ffd5b8063c23e9707146104aa578063c373fee3146104b3578063cf309012146104bb578063d18ced1d146104c8578063d505accf146104db575f5ffd5b8063866558e9116100fa578063866558e914610440578063886eaddc1461045f5780639286c9311461046757806395d89b411461048f578063a9059cbb14610497575f5ffd5b806370a08231146103bb57806378150ff8146103e35780637ecebe001461040a5780638380edb71461041d57806384b0196e14610425575f5ffd5b8063343b3cde116101c157806340c10f191161018657806340c10f191461037057806344dd936c146103835780634d3591ec1461038c5780634e5a7680146103a05780635cfd8a65146103a8575f5ffd5b8063343b3cde14610305578063355274ea146103455780633644e5151461034d57806336fc1787146103555780633f5090ee14610368575f5ffd5b80631fe2256b116102075780631fe2256b1461029557806323b872dd146102a9578063251c1aa3146102bc5780632b911eaf146102e3578063313ce567146102f6575f5ffd5b806306fdde0314610238578063095ea7b31461025657806318160ddd146102795780631bf544431461028b575b5f5ffd5b610240610565565b60405161024d91906123d1565b60405180910390f35b610269610264366004612405565b6105f5565b604051901515815260200161024d565b6002545b60405190815260200161024d565b61029361060e565b005b61027d5f5160206127c25f395f51905f5281565b6102696102b736600461242d565b610715565b61027d7f000000000000000000000000000000000000000000000000000000006998850081565b6102936102f1366004612467565b610738565b6040516012815260200161024d565b61032d6103133660046124a0565b60086020525f90815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200161024d565b61027d6107c3565b61027d6107de565b6102936103633660046124a0565b6107e7565b6102936108a1565b61029361037e366004612405565b6109a3565b61027d600a5481565b61027d5f5160206127a25f395f51905f5281565b610293610a2f565b6102936103b63660046124a0565b610c47565b61027d6103c93660046124b7565b6001600160a01b03165f9081526020819052604090205490565b61027d7f54c9b4c80715cee47dde7f1b62b0c6cd06cacb92458efa077def5f27d03415d481565b61027d6104183660046124b7565b610dab565b610269610dc8565b61042d610dfd565b60405161024d97969594939291906124d0565b61027d61044e3660046124b7565b600d6020525f908152604090205481565b610293610e3f565b61032d6104753660046124a0565b60096020525f90815260409020546001600160a01b031681565b610240610f66565b6102696104a5366004612405565b610f75565b61027d600b5481565b610293610f82565b600e546102699060ff1681565b6102936104d6366004612405565b61104e565b6102936104e9366004612566565b6110e5565b61027d6104fc3660046125d3565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b61027d600c5481565b61027d5f5160206127625f395f51905f5281565b610293610551366004612405565b61121b565b61027d6733ea71cbbb42b10481565b60606003805461057490612604565b80601f01602080910402602001604051908101604052809291908181526020018280546105a090612604565b80156105eb5780601f106105c2576101008083540402835291602001916105eb565b820191905f5260205f20905b8154815290600101906020018083116105ce57829003601f168201915b5050505050905090565b5f33610602818585611357565b60019150505b92915050565b5f5160206127c25f395f51905f525f81905260086020527fad46a584c12dee19dd3315865dd8f658321644e2fc0d8ec87376d55e731dfd9c546001600160a01b031633146106775760405162461bcd60e51b815260040161066e9061263c565b60405180910390fd5b5f5160206127c25f395f51905f525f8181527fad46a584c12dee19dd3315865dd8f658321644e2fc0d8ec87376d55e731dfd9c80546001600160a01b0319908116909155600960209081527f2cfeb242b3e2a551873efb7f5409af68ae82192c4daa647b798f6ffd68dbdbeb805490921690915560408051928352908201929092525f5160206127825f395f51905f5291015b60405180910390a150565b5f33610722858285611369565b61072d8585856113e4565b506001949350505050565b5f5160206127c25f395f51905f525f81905260086020527fad46a584c12dee19dd3315865dd8f658321644e2fc0d8ec87376d55e731dfd9c546001600160a01b031633146107985760405162461bcd60e51b815260040161066e9061263c565b506001600160a01b03919091165f908152600f60205260409020805460ff1916911515919091179055565b5f6107cc611441565b600a546107d9919061267a565b905090565b5f6107d96114c3565b5f818152600960205260409020546001600160a01b031633146108435760405162461bcd60e51b81526020600482015260146024820152732737ba103732bb903937b632903437b63232b91760611b604482015260640161066e565b5f8181526009602090815260408083208054600884529382902080546001600160a01b039586166001600160a01b0319918216178255825416909155548151931683529082018390525f5160206127825f395f51905f52910161070a565b5f5160206127a25f395f51905f525f81905260086020525f5160206127425f395f51905f52546001600160a01b031633146108ee5760405162461bcd60e51b815260040161066e9061263c565b5f5160206127a25f395f51905f525f5260096020527ff20486fe1a2a0fc5e4d4f4bd2ea802b01028bd0d3680182b6ac378d9234898a7546001600160a01b03161561094b5760405162461bcd60e51b815260040161066e9061268d565b5f5160206127a25f395f51905f525f818152600860209081525f5160206127425f395f51905f5280546001600160a01b031916905560408051928352908201929092525f5160206127825f395f51905f52910161070a565b335f908152600d60205260409020548111156109fd5760405162461bcd60e51b81526020600482015260196024820152782737ba1032b737bab3b41036b4b73a1031b0b830b1b4ba3c9760391b604482015260640161066e565b335f908152600d602052604081208054839290610a1b9084906126c4565b90915550610a2b905082826115ec565b5050565b5f5160206127625f395f51905f525f81905260086020525f5160206127225f395f51905f52546001600160a01b03163314610a7c5760405162461bcd60e51b815260040161066e9061263c565b5f5160206127625f395f51905f525f5260096020527f3f9d107ab11d3fd2cdd10e4d1851944c81a2523e5341fb140b585ded940719bf546001600160a01b031615610ad95760405162461bcd60e51b815260040161066e9061268d565b600c5415610b1f5760405162461bcd60e51b815260206004820152601360248201527224b7333630ba34b7b7103737ba103d32b9379760691b604482015260640161066e565b5f5160206127a25f395f51905f525f5260086020525f5160206127425f395f51905f52546001600160a01b031615610b925760405162461bcd60e51b815260206004820152601660248201527524b7333630ba34b7b71030b236b4b7103737ba10181760511b604482015260640161066e565b5f5160206127a25f395f51905f525f5260096020527ff20486fe1a2a0fc5e4d4f4bd2ea802b01028bd0d3680182b6ac378d9234898a7546001600160a01b031615610bef5760405162461bcd60e51b815260040161066e9061268d565b5f5160206127625f395f51905f525f818152600860209081525f5160206127225f395f51905f5280546001600160a01b031916905560408051928352908201929092525f5160206127825f395f51905f52910161070a565b5f5160206127a25f395f51905f525f81905260086020525f5160206127425f395f51905f52546001600160a01b03163314610c945760405162461bcd60e51b815260040161066e9061263c565b5f5160206127625f395f51905f525f5260086020525f5160206127225f395f51905f52546001600160a01b0316610d0d5760405162461bcd60e51b815260206004820152601960248201527f4e6f20696e666c6174696f6e2062656e65666963696172792e00000000000000604482015260640161066e565b6733ea71cbbb42b104821115610d5c5760405162461bcd60e51b815260206004820152601460248201527324b7333630ba34b7b7103a37b7903630b933b29760611b604482015260640161066e565b610d64610f82565b600c80549083905560408051828152602081018590527f0c347accb94360b551ed917758bc5358525405e1b91ac5407913b81d4c3e86b691015b60405180910390a1505050565b6001600160a01b0381165f90815260076020526040812054610608565b5f7f00000000000000000000000000000000000000000000000000000000699885004211806107d9575050600e5460ff161590565b5f6060805f5f5f6060610e0e611620565b610e1661164d565b604080515f80825260208201909252600f60f81b9b939a50919850469750309650945092509050565b7f54c9b4c80715cee47dde7f1b62b0c6cd06cacb92458efa077def5f27d03415d45f81905260086020527ffe18803ae90e6065a13f80d13c726a612a5f4bde35c678d0a6892ebcb7910d75546001600160a01b03163314610eb25760405162461bcd60e51b815260040161066e9061263c565b600e805460ff191690557f54c9b4c80715cee47dde7f1b62b0c6cd06cacb92458efa077def5f27d03415d45f8181527ffe18803ae90e6065a13f80d13c726a612a5f4bde35c678d0a6892ebcb7910d7580546001600160a01b0319908116909155600960209081527ffe4fa762c7c70a39e2a3cadfc51d39dffde606fcc63dc244c53ce43f7dbb091a805490921690915560408051928352908201929092525f5160206127825f395f51905f52910161070a565b60606004805461057490612604565b5f336106028185856113e4565b5f610f8b611441565b5f5160206127625f395f51905f525f90815260086020525f5160206127225f395f51905f5254600a80549394506001600160a01b0390911692849290610fd290849061267a565b90915550506001600160a01b0381165f908152600d602052604081208054849290610ffe90849061267a565b909155505042600b55604080516001600160a01b0383168152602081018490527f853d3d7e29278422c75860e77aff784c6587d84b19d0e212f562b91f60b3390f91015b60405180910390a15050565b5f8181526008602052604090205481906001600160a01b031633146110855760405162461bcd60e51b815260040161066e9061263c565b5f8281526009602090815260409182902080546001600160a01b0319166001600160a01b03871690811790915582519081529081018490527fe925262108dd98ff133f1ba628eb25c76de057168ddd49910ab8eaba84b792fe9101610d9e565b834211156111095760405163313c898160e11b81526004810185905260240161066e565b5f7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886111548c6001600160a01b03165f90815260076020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090505f6111ae8261167a565b90505f6111bd828787876116a6565b9050896001600160a01b0316816001600160a01b031614611204576040516325c0072360e11b81526001600160a01b0380831660048301528b16602482015260440161066e565b61120f8a8a8a611357565b50505050505050505050565b6001600160a01b0382166112685760405162461bcd60e51b815260206004820152601460248201527353656e64696e6720746f2030206164647265737360601b604482015260640161066e565b335f908152600d60205260409020548111156112c25760405162461bcd60e51b81526020600482015260196024820152782737ba1032b737bab3b41036b4b73a1031b0b830b1b4ba3c9760391b604482015260640161066e565b335f908152600d6020526040812080548392906112e09084906126c4565b90915550506001600160a01b0382165f908152600d60205260408120805483929061130c90849061267a565b9091555050604080513381526001600160a01b03841660208201529081018290527f447b0379ed6803974a36a2a794fced1ee7777a67630a29f50f88924f80876a0490606001611042565b61136483838360016116d2565b505050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f1981146113de57818110156113d057604051637dc7a0d960e11b81526001600160a01b0384166004820152602481018290526044810183905260640161066e565b6113de84848484035f6116d2565b50505050565b6001600160a01b03831661140d57604051634b637e8f60e11b81525f600482015260240161066e565b6001600160a01b0382166114365760405163ec442f0560e01b81525f600482015260240161066e565b6113648383836117a4565b5f42600b540361145057505f90565b5f600b544261145f91906126c4565b90505f6114876301e1338083600c5461147891906126d7565b61148291906126ee565b611875565b90505f670de0b6b3a7640000600a54836114a191906126d7565b6114ab91906126ee565b9050600a54816114bb91906126c4565b935050505090565b5f306001600160a01b037f0000000000000000000000007f1f4b4b29f5058fa32cc7a97141b8d7e5abdc2d1614801561151b57507f00000000000000000000000000000000000000000000000000000000000b67d246145b1561154557507fb18b12dea1cdb9b97e4259ca816f311175f1bf2c435742677e583f10253eacc390565b6107d9604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f610cde522034964b05f04b95ac60af4ecd899f69517e2104d5ab57264d1ffec9918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b6001600160a01b0382166116155760405163ec442f0560e01b81525f600482015260240161066e565b610a2b5f83836117a4565b60606107d97f4b6174616e61204e6574776f726b20546f6b656e0000000000000000000000146005611ff0565b60606107d97f31000000000000000000000000000000000000000000000000000000000000016006611ff0565b5f6106086116866114c3565b8360405161190160f01b8152600281019290925260228201526042902090565b5f5f5f5f6116b688888888612099565b9250925092506116c68282612161565b50909695505050505050565b6001600160a01b0384166116fb5760405163e602df0560e01b81525f600482015260240161066e565b6001600160a01b03831661172457604051634a1406b160e11b81525f600482015260240161066e565b6001600160a01b038085165f90815260016020908152604080832093871683529290522082905580156113de57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161179691815260200190565b60405180910390a350505050565b7f00000000000000000000000000000000000000000000000000000000699885004211806117d55750600e5460ff16155b156117e557611364838383612219565b6001600160a01b0383165f908152600f602052604090205460ff16801561181457506001600160a01b03831633145b1561182457611364838383612219565b6001600160a01b03831661183d57611364838383612219565b60405162461bcd60e51b815260206004820152600d60248201526c2a37b5b2b7103637b1b5b2b21760991b604482015260640161066e565b5f61188c670de0b6b3a7640000604084901b6126ee565b9150600160bf1b905067ff0000000000000082161561199d576780000000000000008216156118c45768016a09e667f3bcc9090260401c5b6740000000000000008216156118e3576801306fe0a31b7152df0260401c5b672000000000000000821615611902576801172b83c7d517adce0260401c5b6710000000000000008216156119215768010b5586cf9890f62a0260401c5b670800000000000000821615611940576801059b0d31585743ae0260401c5b67040000000000000082161561195f57680102c9a3e778060ee70260401c5b67020000000000000082161561197e5768010163da9fb33356d80260401c5b67010000000000000082161561199d57680100b1afa5abcbed610260401c5b66ff000000000000821615611a9c5766800000000000008216156119ca5768010058c86da1c09ea20260401c5b66400000000000008216156119e8576801002c605e2e8cec500260401c5b6620000000000000821615611a0657680100162f3904051fa10260401c5b6610000000000000821615611a24576801000b175effdc76ba0260401c5b6608000000000000821615611a4257680100058ba01fb9f96d0260401c5b6604000000000000821615611a605768010002c5cc37da94920260401c5b6602000000000000821615611a7e576801000162e525ee05470260401c5b6601000000000000821615611a9c5768010000b17255775c040260401c5b65ff0000000000821615611b925765800000000000821615611ac7576801000058b91b5bc9ae0260401c5b65400000000000821615611ae457680100002c5c89d5ec6d0260401c5b65200000000000821615611b015768010000162e43f4f8310260401c5b65100000000000821615611b1e57680100000b1721bcfc9a0260401c5b65080000000000821615611b3b5768010000058b90cf1e6e0260401c5b65040000000000821615611b58576801000002c5c863b73f0260401c5b65020000000000821615611b7557680100000162e430e5a20260401c5b65010000000000821615611b92576801000000b1721835510260401c5b64ff00000000821615611c7f57648000000000821615611bbb57680100000058b90c0b490260401c5b644000000000821615611bd75768010000002c5c8601cc0260401c5b642000000000821615611bf3576801000000162e42fff00260401c5b641000000000821615611c0f5768010000000b17217fbb0260401c5b640800000000821615611c2b576801000000058b90bfce0260401c5b640400000000821615611c4757680100000002c5c85fe30260401c5b640200000000821615611c635768010000000162e42ff10260401c5b640100000000821615611c7f57680100000000b17217f80260401c5b63ff000000821615611d63576380000000821615611ca65768010000000058b90bfc0260401c5b6340000000821615611cc1576801000000002c5c85fe0260401c5b6320000000821615611cdc57680100000000162e42ff0260401c5b6310000000821615611cf7576801000000000b17217f0260401c5b6308000000821615611d1257680100000000058b90c00260401c5b6304000000821615611d2d5768010000000002c5c8600260401c5b6302000000821615611d48576801000000000162e4300260401c5b6301000000821615611d635768010000000000b172180260401c5b62ff0000821615611e3e5762800000821615611d88576801000000000058b90c0260401c5b62400000821615611da257680100000000002c5c860260401c5b62200000821615611dbc5768010000000000162e430260401c5b62100000821615611dd657680100000000000b17210260401c5b62080000821615611df05768010000000000058b910260401c5b62040000821615611e0a576801000000000002c5c80260401c5b62020000821615611e2457680100000000000162e40260401c5b62010000821615611e3e576801000000000000b1720260401c5b61ff00821615611f1057618000821615611e6157680100000000000058b90260401c5b614000821615611e7a5768010000000000002c5d0260401c5b612000821615611e93576801000000000000162e0260401c5b611000821615611eac5768010000000000000b170260401c5b610800821615611ec5576801000000000000058c0260401c5b610400821615611ede57680100000000000002c60260401c5b610200821615611ef757680100000000000001630260401c5b610100821615611f1057680100000000000000b10260401c5b60ff821615611fd9576080821615611f3157680100000000000000590260401c5b6040821615611f49576801000000000000002c0260401c5b6020821615611f6157680100000000000000160260401c5b6010821615611f79576801000000000000000b0260401c5b6008821615611f9157680100000000000000060260401c5b6004821615611fa957680100000000000000030260401c5b6002821615611fc157680100000000000000010260401c5b6001821615611fd957680100000000000000010260401c5b670de0b6b3a76400000260409190911c60bf031c90565b606060ff831461200a576120038361233f565b9050610608565b81805461201690612604565b80601f016020809104026020016040519081016040528092919081815260200182805461204290612604565b801561208d5780601f106120645761010080835404028352916020019161208d565b820191905f5260205f20905b81548152906001019060200180831161207057829003601f168201915b50505050509050610608565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08411156120d257505f91506003905082612157565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015612123573d5f5f3e3d5ffd5b5050604051601f1901519150506001600160a01b03811661214e57505f925060019150829050612157565b92505f91508190505b9450945094915050565b5f8260038111156121745761217461270d565b0361217d575050565b60018260038111156121915761219161270d565b036121af5760405163f645eedf60e01b815260040160405180910390fd5b60028260038111156121c3576121c361270d565b036121e45760405163fce698f760e01b81526004810182905260240161066e565b60038260038111156121f8576121f861270d565b03610a2b576040516335e2f38360e21b81526004810182905260240161066e565b6001600160a01b038316612243578060025f828254612238919061267a565b909155506122b39050565b6001600160a01b0383165f90815260208190526040902054818110156122955760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640161066e565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b0382166122cf576002805482900390556122ed565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161233291815260200190565b60405180910390a3505050565b60605f61234b8361237c565b6040805160208082528183019092529192505f91906020820181803683375050509182525060208101929092525090565b5f60ff8216601f81111561060857604051632cd44ac360e21b815260040160405180910390fd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f6123e360208301846123a3565b9392505050565b80356001600160a01b0381168114612400575f5ffd5b919050565b5f5f60408385031215612416575f5ffd5b61241f836123ea565b946020939093013593505050565b5f5f5f6060848603121561243f575f5ffd5b612448846123ea565b9250612456602085016123ea565b929592945050506040919091013590565b5f5f60408385031215612478575f5ffd5b612481836123ea565b915060208301358015158114612495575f5ffd5b809150509250929050565b5f602082840312156124b0575f5ffd5b5035919050565b5f602082840312156124c7575f5ffd5b6123e3826123ea565b60ff60f81b8816815260e060208201525f6124ee60e08301896123a3565b828103604084015261250081896123a3565b606084018890526001600160a01b038716608085015260a0840186905283810360c0850152845180825260208087019350909101905f5b81811015612555578351835260209384019390920191600101612537565b50909b9a5050505050505050505050565b5f5f5f5f5f5f5f60e0888a03121561257c575f5ffd5b612585886123ea565b9650612593602089016123ea565b95506040880135945060608801359350608088013560ff811681146125b6575f5ffd5b9699959850939692959460a0840135945060c09093013592915050565b5f5f604083850312156125e4575f5ffd5b6125ed836123ea565b91506125fb602084016123ea565b90509250929050565b600181811c9082168061261857607f821691505b60208210810361263657634e487b7160e01b5f52602260045260245ffd5b50919050565b60208082526010908201526f2737ba103937b632903437b63232b91760811b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561060857610608612666565b6020808252601a908201527f526f6c65207472616e7366657220696e2070726f67726573732e000000000000604082015260600190565b8181038181111561060857610608612666565b808202811582820484141761060857610608612666565b5f8261270857634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52602160045260245ffdfeef99cce924c96d8dbe2300db77854d44fa213667cf26fababda543a2fa80b5c9b521cc951ed9755340601b8a7f63a0bd6c89110fdd21850902bb60ab4fc3f7b00ec560a57e72e1ad7c888fa95b5a74170e915e2173a447b50c3cefd1fe82f510f54f5cceb448ef806753e004d4516a584e5d52ee04e57717762f87bd2cce6e9bf8541c194a0b2749cdcc163377d32fae37700c72cef0857ad24aa49792741b2ef8bea3b6ac1f7ecd96cf424727980e36f4569781fe0559ce9088bb153106d262a2646970667358221220885582c1b5ccc42c614c537866554764f343616c0e35e434f7713cc3dbd7c79464736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000014000000000000000000000000092d8ce89ff02c640daf0b7c23d497ccf1880c39000000000000000000000000092d8ce89ff02c640daf0b7c23d497ccf1880c39000000000000000000000000092d8ce89ff02c640daf0b7c23d497ccf1880c390000000000000000000000000000000000000000000000000000000006998850000000000000000000000000092d8ce89ff02c640daf0b7c23d497ccf1880c39000000000000000000000000092d8ce89ff02c640daf0b7c23d497ccf1880c39000000000000000000000000000000000000000000000000000000000000000144b6174616e61204e6574776f726b20546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000034b41540000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _name (string): Katana Network Token
Arg [1] : _symbol (string): KAT
Arg [2] : _inflationAdmin (address): 0x92D8Ce89fF02C640daf0B7c23d497cCF1880C390
Arg [3] : _inflationBeneficiary (address): 0x92D8Ce89fF02C640daf0B7c23d497cCF1880C390
Arg [4] : _distributor (address): 0x92D8Ce89fF02C640daf0B7c23d497cCF1880C390
Arg [5] : _unlockTime (uint256): 1771603200
Arg [6] : _unlocker (address): 0x92D8Ce89fF02C640daf0B7c23d497cCF1880C390
Arg [7] : _lockExemptionAdmin (address): 0x92D8Ce89fF02C640daf0B7c23d497cCF1880C390
-----Encoded View---------------
12 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [2] : 00000000000000000000000092d8ce89ff02c640daf0b7c23d497ccf1880c390
Arg [3] : 00000000000000000000000092d8ce89ff02c640daf0b7c23d497ccf1880c390
Arg [4] : 00000000000000000000000092d8ce89ff02c640daf0b7c23d497ccf1880c390
Arg [5] : 0000000000000000000000000000000000000000000000000000000069988500
Arg [6] : 00000000000000000000000092d8ce89ff02c640daf0b7c23d497ccf1880c390
Arg [7] : 00000000000000000000000092d8ce89ff02c640daf0b7c23d497ccf1880c390
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [9] : 4b6174616e61204e6574776f726b20546f6b656e000000000000000000000000
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [11] : 4b41540000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
416:12249:19:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1779:89:2;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3998:186;;;;;;:::i;:::-;;:::i;:::-;;;1181:14:21;;1174:22;1156:41;;1144:2;1129:18;3998:186:2;1016:187:21;2849:97:2;2927:12;;2849:97;;;1354:25:21;;;1342:2;1327:18;2849:97:2;1208:177:21;7950:269:19;;;:::i;:::-;;1609:80;;-1:-1:-1;;;;;;;;;;;1609:80:19;;4776:244:2;;;;;;:::i;:::-;;:::i;2934:35:19:-;;;;;8723:135;;;;;;:::i;:::-;;:::i;2707:82:2:-;;;2780:2;2445:36:21;;2433:2;2418:18;2707:82:2;2303:184:21;1728:45:19;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;1728:45:19;;;;;;-1:-1:-1;;;;;2887:32:21;;;2869:51;;2857:2;2842:18;1728:45:19;2723:203:21;9774:110:19;;;:::i;2659:112:4:-;;;:::i;5786:286:19:-;;;;;;:::i;:::-;;:::i;6277:285::-;;;:::i;11712:211::-;;;;;;:::i;:::-;;:::i;1960:35::-;;;;;;1168:70;;-1:-1:-1;;;;;;;;;;;1168:70:19;;6764:560;;;:::i;9174:397::-;;;;;;:::i;:::-;;:::i;3004:116:2:-;;;;;;:::i;:::-;-1:-1:-1;;;;;3095:18:2;3069:7;3095:18;;;;;;;;;;;;3004:116;1477:56:19;;1512:21;1477:56;;2409:143:4;;;;;;:::i;:::-;;:::i;8393:114:19:-;;;:::i;5144:557:14:-;;;:::i;:::-;;;;;;;;;;;;;:::i;2789:47:19:-;;;;;;:::i;:::-;;;;;;;;;;;;;;7493:244;;;:::i;1829:52::-;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;1829:52:19;;;1981:93:2;;;:::i;3315:178::-;;;;;;:::i;:::-;;:::i;2062:39:19:-;;;;;;10630:385;;;:::i;3102:25::-;;;;;;;;;5418:192;;;;;;:::i;:::-;;:::i;1683:672:4:-;;;;;;:::i;:::-;;:::i;3551:140:2:-;;;;;;:::i;:::-;-1:-1:-1;;;;;3657:18:2;;;3631:7;3657:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;3551:140;2454:30:19;;;;;;1340:82;;-1:-1:-1;;;;;;;;;;;1340:82:19;;11192:359;;;;;;:::i;:::-;;:::i;2629:61::-;;2669:21;2629:61;;1779:89:2;1824:13;1856:5;1849:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1779:89;:::o;3998:186::-;4071:4;735:10:7;4125:31:2;735:10:7;4141:7:2;4150:5;4125:8;:31::i;:::-;4173:4;4166:11;;;3998:186;;;;;:::o;7950:269:19:-;-1:-1:-1;;;;;;;;;;;5054:16:19;;;;:10;:16;;;;-1:-1:-1;;;;;5054:16:19;5074:10;5054:30;5046:59;;;;-1:-1:-1;;;5046:59:19;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;;;;;;;8080:1:19::1;8037:32:::0;;;;:45;;-1:-1:-1;;;;;;8037:45:19;;::::1;::::0;;;8092:17:::1;8037:32;8092:39:::0;;;;:52;;;;::::1;::::0;;;8037:32;8159:53;;6978:51:21;;;7045:18;;;7038:34;;;;-1:-1:-1;;;;;;;;;;;8159:53:19;6951:18:21;8159:53:19::1;;;;;;;;7950:269:::0;:::o;4776:244:2:-;4863:4;735:10:7;4919:37:2;4935:4;735:10:7;4950:5:2;4919:15;:37::i;:::-;4966:26;4976:4;4982:2;4986:5;4966:9;:26::i;:::-;-1:-1:-1;5009:4:2;;4776:244;-1:-1:-1;;;;4776:244:2:o;8723:135:19:-;-1:-1:-1;;;;;;;;;;;5054:16:19;;;;:10;:16;;;;-1:-1:-1;;;;;5054:16:19;5074:10;5054:30;5046:59;;;;-1:-1:-1;;;5046:59:19;;;;;;;:::i;:::-;-1:-1:-1;;;;;;8824:19:19;;;::::1;;::::0;;;:13:::1;:19;::::0;;;;:27;;-1:-1:-1;;8824:27:19::1;::::0;::::1;;::::0;;;::::1;::::0;;8723:135::o;9774:110::-;9812:7;9861:16;:14;:16::i;:::-;9838:20;;:39;;;;:::i;:::-;9831:46;;9774:110;:::o;2659:112:4:-;2718:7;2744:20;:18;:20::i;5786:286:19:-;5847:23;;;;:17;:23;;;;;;-1:-1:-1;;;;;5847:23:19;5874:10;5847:37;5839:70;;;;-1:-1:-1;;;5839:70:19;;7547:2:21;5839:70:19;;;7529:21:21;7586:2;7566:18;;;7559:30;-1:-1:-1;;;7605:18:21;;;7598:50;7665:18;;5839:70:19;7345:344:21;5839:70:19;5938:23;;;;:17;:23;;;;;;;;;;5919:10;:16;;;;;;:42;;-1:-1:-1;;;;;5938:23:19;;;-1:-1:-1;;;;;;5919:42:19;;;;;;5971:36;;;;;;6042:16;6022:43;;6042:16;;6978:51:21;;7045:18;;;7038:34;;;-1:-1:-1;;;;;;;;;;;6022:43:19;6951:18:21;6022:43:19;6804:274:21;6277:285:19;-1:-1:-1;;;;;;;;;;;5054:16:19;;;;:10;:16;;-1:-1:-1;;;;;;;;;;;5054:16:19;-1:-1:-1;;;;;5054:16:19;5074:10;5054:30;5046:59;;;;-1:-1:-1;;;5046:59:19;;;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;;;6409:1:19::1;6363:34:::0;:17:::1;:34;::::0;;;-1:-1:-1;;;;;6363:34:19::1;:48:::0;6355:87:::1;;;;-1:-1:-1::0;;;6355:87:19::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;;;;;;6490:1:19::1;6452:27:::0;;;:10:::1;:27;::::0;;;-1:-1:-1;;;;;;;;;;;6452:40:19;;-1:-1:-1;;;;;;6452:40:19::1;::::0;;:27;6507:48;;6978:51:21;;;7045:18;;;7038:34;;;;-1:-1:-1;;;;;;;;;;;6507:48:19;6951:18:21;6507:48:19::1;6804:274:21::0;11712:211:19;11794:10;11781:24;;;;:12;:24;;;;;;:34;-1:-1:-1;11781:34:19;11773:72;;;;-1:-1:-1;;;11773:72:19;;8251:2:21;11773:72:19;;;8233:21:21;8290:2;8270:18;;;8263:30;-1:-1:-1;;;8309:18:21;;;8302:55;8374:18;;11773:72:19;8049:349:21;11773:72:19;11868:10;11855:24;;;;:12;:24;;;;;:34;;11883:6;;11855:24;:34;;11883:6;;11855:34;:::i;:::-;;;;-1:-1:-1;11899:17:19;;-1:-1:-1;11905:2:19;11909:6;11899:5;:17::i;:::-;11712:211;;:::o;6764:560::-;-1:-1:-1;;;;;;;;;;;5054:16:19;;;;:10;:16;;-1:-1:-1;;;;;;;;;;;5054:16:19;-1:-1:-1;;;;;5054:16:19;5074:10;5054:30;5046:59;;;;-1:-1:-1;;;5046:59:19;;;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;;;6914:1:19::1;6862:40:::0;:17:::1;:40;::::0;;;-1:-1:-1;;;;;6862:40:19::1;:54:::0;6854:93:::1;;;;-1:-1:-1::0;;;6854:93:19::1;;;;;;;:::i;:::-;6965:15;::::0;:20;6957:52:::1;;;::::0;-1:-1:-1;;;6957:52:19;;8738:2:21;6957:52:19::1;::::0;::::1;8720:21:21::0;8777:2;8757:18;;;8750:30;-1:-1:-1;;;8796:18:21;;;8789:49;8855:18;;6957:52:19::1;8536:343:21::0;6957:52:19::1;-1:-1:-1::0;;;;;;;;;;;7066:1:19::1;7027:27:::0;:10:::1;:27;::::0;-1:-1:-1;;;;;;;;;;;7027:27:19;-1:-1:-1;;;;;7027:27:19::1;:41:::0;7019:76:::1;;;::::0;-1:-1:-1;;;7019:76:19;;9086:2:21;7019:76:19::1;::::0;::::1;9068:21:21::0;9125:2;9105:18;;;9098:30;-1:-1:-1;;;9144:18:21;;;9137:52;9206:18;;7019:76:19::1;8884:346:21::0;7019:76:19::1;-1:-1:-1::0;;;;;;;;;;;7159:1:19::1;7113:34:::0;:17:::1;:34;::::0;;;-1:-1:-1;;;;;7113:34:19::1;:48:::0;7105:87:::1;;;;-1:-1:-1::0;;;7105:87:19::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;;;;;;7246:1:19::1;7202:33:::0;;;:10:::1;:33;::::0;;;-1:-1:-1;;;;;;;;;;;7202:46:19;;-1:-1:-1;;;;;;7202:46:19::1;::::0;;:33;7263:54;;6978:51:21;;;7045:18;;;7038:34;;;;-1:-1:-1;;;;;;;;;;;7263:54:19;6951:18:21;7263:54:19::1;6804:274:21::0;9174:397:19;-1:-1:-1;;;;;;;;;;;5054:16:19;;;;:10;:16;;-1:-1:-1;;;;;;;;;;;5054:16:19;-1:-1:-1;;;;;5054:16:19;5074:10;5054:30;5046:59;;;;-1:-1:-1;;;5046:59:19;;;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;;;9311:1:19::1;9266:33:::0;:10:::1;:33;::::0;-1:-1:-1;;;;;;;;;;;9266:33:19;-1:-1:-1;;;;;9266:33:19::1;9258:85;;;::::0;-1:-1:-1;;;9258:85:19;;9437:2:21;9258:85:19::1;::::0;::::1;9419:21:21::0;9476:2;9456:18;;;9449:30;9515:27;9495:18;;;9488:55;9560:18;;9258:85:19::1;9235:349:21::0;9258:85:19::1;2669:21;9361:5;:22;;9353:55;;;::::0;-1:-1:-1;;;9353:55:19;;9791:2:21;9353:55:19::1;::::0;::::1;9773:21:21::0;9830:2;9810:18;;;9803:30;-1:-1:-1;;;9849:18:21;;;9842:50;9909:18;;9353:55:19::1;9589:344:21::0;9353:55:19::1;9418:21;:19;:21::i;:::-;9468:15;::::0;;9493:23;;;;9531:33:::1;::::0;;10112:25:21;;;10168:2;10153:18;;10146:34;;;9531:33:19::1;::::0;10085:18:21;9531:33:19::1;;;;;;;;9248:323;9174:397:::0;;:::o;2409:143:4:-;-1:-1:-1;;;;;624:14:8;;2500:7:4;624:14:8;;;:7;:14;;;;;;2526:19:4;538:107:8;8393:114:19;8436:4;8478:10;8460:15;:28;8459:41;;;-1:-1:-1;;8494:6:19;;;;8493:7;;8393:114::o;5144:557:14:-;5242:13;5269:18;5301:21;5336:15;5365:25;5404:12;5430:27;5533:13;:11;:13::i;:::-;5560:16;:14;:16::i;:::-;5668;;;5652:1;5668:16;;;;;;;;;-1:-1:-1;;;5482:212:14;;;-1:-1:-1;5482:212:14;;-1:-1:-1;5590:13:14;;-1:-1:-1;5625:4:14;;-1:-1:-1;5652:1:14;-1:-1:-1;5668:16:14;-1:-1:-1;5482:212:14;-1:-1:-1;5144:557:14:o;7493:244:19:-;1512:21;5054:16;;;;:10;:16;;;;-1:-1:-1;;;;;5054:16:19;5074:10;5054:30;5046:59;;;;-1:-1:-1;;;5046:59:19;;;;;;;:::i;:::-;7567:6:::1;:14:::0;;-1:-1:-1;;7567:14:19::1;::::0;;1512:21:::1;-1:-1:-1::0;7591:20:19;;;;:33;;-1:-1:-1;;;;;;7591:33:19;;::::1;::::0;;;7634:17:::1;7591:20;7634:27:::0;;;;:40;;;;::::1;::::0;;;7591:20;7689:41;;6978:51:21;;;7045:18;;;7038:34;;;;-1:-1:-1;;;;;;;;;;;7689:41:19;6951:18:21;7689:41:19::1;6804:274:21::0;1981:93:2;2028:13;2060:7;2053:14;;;;;:::i;3315:178::-;3384:4;735:10:7;3438:27:2;735:10:7;3455:2:2;3459:5;3438:9;:27::i;10630:385:19:-;10678:17;10698:16;:14;:16::i;:::-;-1:-1:-1;;;;;;;;;;;10724:28:19;10755:33;;;:10;:33;;-1:-1:-1;;;;;;;;;;;10755:33:19;10798:20;:33;;10678:36;;-1:-1:-1;;;;;;10755:33:19;;;;10678:36;;10724:28;10798:33;;10678:36;;10798:33;:::i;:::-;;;;-1:-1:-1;;;;;;;10841:34:19;;;;;;:12;:34;;;;;:47;;10879:9;;10841:34;:47;;10879:9;;10841:47;:::i;:::-;;;;-1:-1:-1;;10925:15:19;10898:24;:42;10955:53;;;-1:-1:-1;;;;;6996:32:21;;6978:51;;7060:2;7045:18;;7038:34;;;10955:53:19;;6951:18:21;10955:53:19;;;;;;;;10668:347;;10630:385::o;5418:192::-;5054:16;;;;:10;:16;;;;;;5497:4;;-1:-1:-1;;;;;5054:16:19;5074:10;5054:30;5046:59;;;;-1:-1:-1;;;5046:59:19;;;;;;;:::i;:::-;5513:23:::1;::::0;;;:17:::1;:23;::::0;;;;;;;;:38;;-1:-1:-1;;;;;;5513:38:19::1;-1:-1:-1::0;;;;;5513:38:19;::::1;::::0;;::::1;::::0;;;5566:37;;6978:51:21;;;7045:18;;;7038:34;;;5566:37:19::1;::::0;6951:18:21;5566:37:19::1;6804:274:21::0;1683:672:4;1904:8;1886:15;:26;1882:97;;;1935:33;;-1:-1:-1;;;1935:33:4;;;;;1354:25:21;;;1327:18;;1935:33:4;1208:177:21;1882:97:4;1989:18;1024:95;2048:5;2055:7;2064:5;2071:16;2081:5;-1:-1:-1;;;;;1121:14:8;819:7;1121:14;;;:7;:14;;;;;:16;;;;;;;;;759:395;2071:16:4;2020:78;;;;;;10889:25:21;;;;-1:-1:-1;;;;;10950:32:21;;;10930:18;;;10923:60;11019:32;;;;10999:18;;;10992:60;11068:18;;;11061:34;11111:19;;;11104:35;11155:19;;;11148:35;;;10861:19;;2020:78:4;;;;;;;;;;;;2010:89;;;;;;1989:110;;2110:12;2125:28;2142:10;2125:16;:28::i;:::-;2110:43;;2164:14;2181:28;2195:4;2201:1;2204;2207;2181:13;:28::i;:::-;2164:45;;2233:5;-1:-1:-1;;;;;2223:15:4;:6;-1:-1:-1;;;;;2223:15:4;;2219:88;;2261:35;;-1:-1:-1;;;2261:35:4;;-1:-1:-1;;;;;11386:32:21;;;2261:35:4;;;11368:51:21;11455:32;;11435:18;;;11428:60;11341:18;;2261:35:4;11194:300:21;2219:88:4;2317:31;2326:5;2333:7;2342:5;2317:8;:31::i;:::-;1872:483;;;1683:672;;;;;;;:::o;11192:359:19:-;-1:-1:-1;;;;;11279:16:19;;11271:49;;;;-1:-1:-1;;;11271:49:19;;11701:2:21;11271:49:19;;;11683:21:21;11740:2;11720:18;;;11713:30;-1:-1:-1;;;11759:18:21;;;11752:50;11819:18;;11271:49:19;11499:344:21;11271:49:19;11351:10;11338:24;;;;:12;:24;;;;;;:34;-1:-1:-1;11338:34:19;11330:72;;;;-1:-1:-1;;;11330:72:19;;8251:2:21;11330:72:19;;;8233:21:21;8290:2;8270:18;;;8263:30;-1:-1:-1;;;8309:18:21;;;8302:55;8374:18;;11330:72:19;8049:349:21;11330:72:19;11425:10;11412:24;;;;:12;:24;;;;;:34;;11440:6;;11412:24;:34;;11440:6;;11412:34;:::i;:::-;;;;-1:-1:-1;;;;;;;11456:16:19;;;;;;:12;:16;;;;;:26;;11476:6;;11456:16;:26;;11476:6;;11456:26;:::i;:::-;;;;-1:-1:-1;;11497:47:19;;;11521:10;12050:51:21;;-1:-1:-1;;;;;12137:32:21;;12132:2;12117:18;;12110:60;12186:18;;;12179:34;;;11497:47:19;;12038:2:21;12023:18;11497:47:19;11848:371:21;8726:128:2;8810:37;8819:5;8826:7;8835:5;8842:4;8810:8;:37::i;:::-;8726:128;;;:::o;10415:477::-;-1:-1:-1;;;;;3657:18:2;;;10514:24;3657:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;-1:-1:-1;;10580:37:2;;10576:310;;10656:5;10637:16;:24;10633:130;;;10688:60;;-1:-1:-1;;;10688:60:2;;-1:-1:-1;;;;;12444:32:21;;10688:60:2;;;12426:51:21;12493:18;;;12486:34;;;12536:18;;;12529:34;;;12399:18;;10688:60:2;12224:345:21;10633:130:2;10804:57;10813:5;10820:7;10848:5;10829:16;:24;10855:5;10804:8;:57::i;:::-;10504:388;10415:477;;;:::o;5393:300::-;-1:-1:-1;;;;;5476:18:2;;5472:86;;5517:30;;-1:-1:-1;;;5517:30:2;;5544:1;5517:30;;;2869:51:21;2842:18;;5517:30:2;2723:203:21;5472:86:2;-1:-1:-1;;;;;5571:16:2;;5567:86;;5610:32;;-1:-1:-1;;;5610:32:2;;5639:1;5610:32;;;2869:51:21;2842:18;;5610:32:2;2723:203:21;5567:86:2;5662:24;5670:4;5676:2;5680:5;5662:7;:24::i;10078:436:19:-;10127:7;10178:15;10150:24;;:43;10146:82;;-1:-1:-1;10216:1:19;;10078:436::o;10146:82::-;10237:19;10277:24;;10259:15;:42;;;;:::i;:::-;10237:64;;10311:20;10334:56;10381:8;10366:11;10348:15;;:29;;;;:::i;:::-;10347:42;;;;:::i;:::-;10334:12;:56::i;:::-;10311:79;;10400:14;10457:4;10433:20;;10418:12;:35;;;;:::i;:::-;10417:44;;;;:::i;:::-;10400:61;;10487:20;;10478:6;:29;;;;:::i;:::-;10471:36;;;;;10078:436;:::o;3845:262:14:-;3898:7;3929:4;-1:-1:-1;;;;;3938:11:14;3921:28;;:63;;;;;3970:14;3953:13;:31;3921:63;3917:184;;;-1:-1:-1;4007:22:14;;3845:262::o;3917:184::-;4067:23;4204:80;;;2079:95;4204:80;;;13570:25:21;4226:11:14;13611:18:21;;;13604:34;;;;4239:14:14;13654:18:21;;;13647:34;4255:13:14;13697:18:21;;;13690:34;4278:4:14;13740:19:21;;;13733:61;4168:7:14;;13542:19:21;;4204:80:14;;;;;;;;;;;;4194:91;;;;;;4187:98;;4113:179;;7458:208:2;-1:-1:-1;;;;;7528:21:2;;7524:91;;7572:32;;-1:-1:-1;;;7572:32:2;;7601:1;7572:32;;;2869:51:21;2842:18;;7572:32:2;2723:203:21;7524:91:2;7624:35;7640:1;7644:7;7653:5;7624:7;:35::i;6021:126:14:-;6067:13;6099:41;:5;6126:13;6099:26;:41::i;6473:135::-;6522:13;6554:47;:8;6584:16;6554:29;:47::i;4917:176::-;4994:7;5020:66;5053:20;:18;:20::i;:::-;5075:10;3501:4:15;3495:11;-1:-1:-1;;;3519:23:15;;3571:4;3562:14;;3555:39;;;;3623:4;3614:14;;3607:34;3679:4;3664:20;;;3326:374;6887:260:13;6972:7;6992:17;7011:18;7031:16;7051:25;7062:4;7068:1;7071;7074;7051:10;:25::i;:::-;6991:85;;;;;;7086:28;7098:5;7105:8;7086:11;:28::i;:::-;-1:-1:-1;7131:9:13;;6887:260;-1:-1:-1;;;;;;6887:260:13:o;9701:432:2:-;-1:-1:-1;;;;;9813:19:2;;9809:89;;9855:32;;-1:-1:-1;;;9855:32:2;;9884:1;9855:32;;;2869:51:21;2842:18;;9855:32:2;2723:203:21;9809:89:2;-1:-1:-1;;;;;9911:21:2;;9907:90;;9955:31;;-1:-1:-1;;;9955:31:2;;9983:1;9955:31;;;2869:51:21;2842:18;;9955:31:2;2723:203:21;9907:90:2;-1:-1:-1;;;;;10006:18:2;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;:35;;;10051:76;;;;10101:7;-1:-1:-1;;;;;10085:31:2;10094:5;-1:-1:-1;;;;;10085:31:2;;10110:5;10085:31;;;;1354:25:21;;1342:2;1327:18;;1208:177;10085:31:2;;;;;;;;9701:432;;;;:::o;12092:571:19:-;12201:10;12183:15;:28;:39;;;-1:-1:-1;12216:6:19;;;;12215:7;12183:39;12179:478;;;12238:31;12252:4;12258:2;12262:6;12238:13;:31::i;12179:478::-;-1:-1:-1;;;;;12418:19:19;;;;;;:13;:19;;;;;;;;:41;;;;-1:-1:-1;;;;;;12441:18:19;;12449:10;12441:18;12418:41;12414:243;;;12475:31;12489:4;12495:2;12499:6;12475:13;:31::i;12414:243::-;-1:-1:-1;;;;;12527:18:19;;12523:134;;12561:31;12575:4;12581:2;12585:6;12561:13;:31::i;12523:134::-;12623:23;;-1:-1:-1;;;12623:23:19;;13171:2:21;12623:23:19;;;13153:21:21;13210:2;13190:18;;;13183:30;-1:-1:-1;;;13229:18:21;;;13222:43;13282:18;;12623:23:19;12969:337:21;78:9070:20;126:14;558:16;570:4;564:2;559:7;;;558:16;:::i;:::-;554:20;-1:-1:-1;;;;686:50:20;-1:-1:-1;1329:18:20;1325:22;;:26;1321:963;;1379:18;1375:22;;:26;1371:97;;1442:19;1433:28;1466:2;1432:36;1371:97;1494:18;1490:22;;:26;1486:97;;1557:19;1548:28;1581:2;1547:36;1486:97;1609:18;1605:22;;:26;1601:97;;1672:19;1663:28;1696:2;1662:36;1601:97;1724:18;1720:22;;:26;1716:97;;1787:19;1778:28;1811:2;1777:36;1716:97;1839:17;1835:21;;:25;1831:96;;1901:19;1892:28;1925:2;1891:36;1831:96;1953:17;1949:21;;:25;1945:96;;2015:19;2006:28;2039:2;2005:36;1945:96;2067:17;2063:21;;:25;2059:96;;2129:19;2120:28;2153:2;2119:36;2059:96;2181:17;2177:21;;:25;2173:96;;2243:19;2234:28;2267:2;2233:36;2173:96;2306:16;2302:20;;:24;2298:945;;2354:16;2350:20;;:24;2346:95;;2415:19;2406:28;2439:2;2405:36;2346:95;2467:16;2463:20;;:24;2459:95;;2528:19;2519:28;2552:2;2518:36;2459:95;2580:16;2576:20;;:24;2572:95;;2641:19;2632:28;2665:2;2631:36;2572:95;2693:16;2689:20;;:24;2685:95;;2754:19;2745:28;2778:2;2744:36;2685:95;2806:15;2802:19;;:23;2798:94;;2866:19;2857:28;2890:2;2856:36;2798:94;2918:15;2914:19;;:23;2910:94;;2978:19;2969:28;3002:2;2968:36;2910:94;3030:15;3026:19;;:23;3022:94;;3090:19;3081:28;3114:2;3080:36;3022:94;3142:15;3138:19;;:23;3134:94;;3202:19;3193:28;3226:2;3192:36;3134:94;3265:14;3261:18;;:22;3257:927;;3311:14;3307:18;;:22;3303:93;;3370:19;3361:28;3394:2;3360:36;3303:93;3422:14;3418:18;;:22;3414:93;;3481:19;3472:28;3505:2;3471:36;3414:93;3533:14;3529:18;;:22;3525:93;;3592:19;3583:28;3616:2;3582:36;3525:93;3644:14;3640:18;;:22;3636:93;;3703:19;3694:28;3727:2;3693:36;3636:93;3755:13;3751:17;;:21;3747:92;;3813:19;3804:28;3837:2;3803:36;3747:92;3865:13;3861:17;;:21;3857:92;;3923:19;3914:28;3947:2;3913:36;3857:92;3975:13;3971:17;;:21;3967:92;;4033:19;4024:28;4057:2;4023:36;3967:92;4085:13;4081:17;;:21;4077:92;;4143:19;4134:28;4167:2;4133:36;4077:92;4206:12;4202:16;;:20;4198:909;;4250:12;4246:16;;:20;4242:91;;4307:19;4298:28;4331:2;4297:36;4242:91;4359:12;4355:16;;:20;4351:91;;4416:19;4407:28;4440:2;4406:36;4351:91;4468:12;4464:16;;:20;4460:91;;4525:19;4516:28;4549:2;4515:36;4460:91;4577:12;4573:16;;:20;4569:91;;4634:19;4625:28;4658:2;4624:36;4569:91;4686:11;4682:15;;:19;4678:90;;4742:19;4733:28;4766:2;4732:36;4678:90;4794:11;4790:15;;:19;4786:90;;4850:19;4841:28;4874:2;4840:36;4786:90;4902:11;4898:15;;:19;4894:90;;4958:19;4949:28;4982:2;4948:36;4894:90;5010:11;5006:15;;:19;5002:90;;5066:19;5057:28;5090:2;5056:36;5002:90;5129:10;5125:14;;:18;5121:891;;5171:10;5167:14;;:18;5163:89;;5226:19;5217:28;5250:2;5216:36;5163:89;5278:10;5274:14;;:18;5270:89;;5333:19;5324:28;5357:2;5323:36;5270:89;5385:10;5381:14;;:18;5377:89;;5440:19;5431:28;5464:2;5430:36;5377:89;5492:10;5488:14;;:18;5484:89;;5547:19;5538:28;5571:2;5537:36;5484:89;5599:9;5595:13;;:17;5591:88;;5653:19;5644:28;5677:2;5643:36;5591:88;5705:9;5701:13;;:17;5697:88;;5759:19;5750:28;5783:2;5749:36;5697:88;5811:9;5807:13;;:17;5803:88;;5865:19;5856:28;5889:2;5855:36;5803:88;5917:9;5913:13;;:17;5909:88;;5971:19;5962:28;5995:2;5961:36;5909:88;6034:8;6030:12;;:16;6026:873;;6074:8;6070:12;;:16;6066:87;;6127:19;6118:28;6151:2;6117:36;6066:87;6179:8;6175:12;;:16;6171:87;;6232:19;6223:28;6256:2;6222:36;6171:87;6284:8;6280:12;;:16;6276:87;;6337:19;6328:28;6361:2;6327:36;6276:87;6389:8;6385:12;;:16;6381:87;;6442:19;6433:28;6466:2;6432:36;6381:87;6494:7;6490:11;;:15;6486:86;;6546:19;6537:28;6570:2;6536:36;6486:86;6598:7;6594:11;;:15;6590:86;;6650:19;6641:28;6674:2;6640:36;6590:86;6702:7;6698:11;;:15;6694:86;;6754:19;6745:28;6778:2;6744:36;6694:86;6806:7;6802:11;;:15;6798:86;;6858:19;6849:28;6882:2;6848:36;6798:86;6921:6;6917:10;;:14;6913:855;;6959:6;6955:10;;:14;6951:85;;7010:19;7001:28;7034:2;7000:36;6951:85;7062:6;7058:10;;:14;7054:85;;7113:19;7104:28;7137:2;7103:36;7054:85;7165:6;7161:10;;:14;7157:85;;7216:19;7207:28;7240:2;7206:36;7157:85;7268:6;7264:10;;:14;7260:85;;7319:19;7310:28;7343:2;7309:36;7260:85;7371:5;7367:9;;:13;7363:84;;7421:19;7412:28;7445:2;7411:36;7363:84;7473:5;7469:9;;:13;7465:84;;7523:19;7514:28;7547:2;7513:36;7465:84;7575:5;7571:9;;:13;7567:84;;7625:19;7616:28;7649:2;7615:36;7567:84;7677:5;7673:9;;:13;7669:84;;7727:19;7718:28;7751:2;7717:36;7669:84;7790:4;7786:8;;:12;7782:677;;7826:4;7822:8;;:12;7818:63;;7855:19;7846:28;7879:2;7845:36;7818:63;7907:4;7903:8;;:12;7899:63;;7936:19;7927:28;7960:2;7926:36;7899:63;7988:4;7984:8;;:12;7980:63;;8017:19;8008:28;8041:2;8007:36;7980:63;8069:4;8065:8;;:12;8061:63;;8098:19;8089:28;8122:2;8088:36;8061:63;8150:3;8146:7;;:11;8142:62;;8178:19;8169:28;8202:2;8168:36;8142:62;8230:3;8226:7;;:11;8222:62;;8258:19;8249:28;8282:2;8248:36;8222:62;8310:3;8306:7;;:11;8302:62;;8338:19;8329:28;8362:2;8328:36;8302:62;8390:3;8386:7;;:11;8382:62;;8418:19;8409:28;8442:2;8408:36;8382:62;9085:4;9075:14;9127:2;9122:7;;;;9115:3;:15;9103:28;;78:9070::o;3358:267:10:-;3452:13;1390:66;3481:46;;3477:142;;3550:15;3559:5;3550:8;:15::i;:::-;3543:22;;;;3477:142;3603:5;3596:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5203:1551:13;5329:17;;;6283:66;6270:79;;6266:164;;;-1:-1:-1;6381:1:13;;-1:-1:-1;6385:30:13;;-1:-1:-1;6417:1:13;6365:54;;6266:164;6541:24;;;6524:14;6541:24;;;;;;;;;14032:25:21;;;14105:4;14093:17;;14073:18;;;14066:45;;;;14127:18;;;14120:34;;;14170:18;;;14163:34;;;6541:24:13;;14004:19:21;;6541:24:13;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6541:24:13;;-1:-1:-1;;6541:24:13;;;-1:-1:-1;;;;;;;6579:20:13;;6575:113;;-1:-1:-1;6631:1:13;;-1:-1:-1;6635:29:13;;-1:-1:-1;6631:1:13;;-1:-1:-1;6615:62:13;;6575:113;6706:6;-1:-1:-1;6714:20:13;;-1:-1:-1;6714:20:13;;-1:-1:-1;5203:1551:13;;;;;;;;;:::o;7280:532::-;7375:20;7366:5;:29;;;;;;;;:::i;:::-;;7362:444;;7280:532;;:::o;7362:444::-;7471:29;7462:5;:38;;;;;;;;:::i;:::-;;7458:348;;7523:23;;-1:-1:-1;;;7523:23:13;;;;;;;;;;;7458:348;7576:35;7567:5;:44;;;;;;;;:::i;:::-;;7563:243;;7634:46;;-1:-1:-1;;;7634:46:13;;;;;1354:25:21;;;1327:18;;7634:46:13;1208:177:21;7563:243:13;7710:30;7701:5;:39;;;;;;;;:::i;:::-;;7697:109;;7763:32;;-1:-1:-1;;;7763:32:13;;;;;1354:25:21;;;1327:18;;7763:32:13;1208:177:21;6008:1107:2;-1:-1:-1;;;;;6097:18:2;;6093:540;;6249:5;6233:12;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;6093:540:2;;-1:-1:-1;6093:540:2;;-1:-1:-1;;;;;6307:15:2;;6285:19;6307:15;;;;;;;;;;;6340:19;;;6336:115;;;6386:50;;-1:-1:-1;;;6386:50:2;;-1:-1:-1;;;;;12444:32:21;;6386:50:2;;;12426:51:21;12493:18;;;12486:34;;;12536:18;;;12529:34;;;12399:18;;6386:50:2;12224:345:21;6336:115:2;-1:-1:-1;;;;;6571:15:2;;:9;:15;;;;;;;;;;6589:19;;;;6571:37;;6093:540;-1:-1:-1;;;;;6647:16:2;;6643:425;;6810:12;:21;;;;;;;6643:425;;;-1:-1:-1;;;;;7021:13:2;;:9;:13;;;;;;;;;;:22;;;;;;6643:425;7098:2;-1:-1:-1;;;;;7083:25:2;7092:4;-1:-1:-1;;;;;7083:25:2;;7102:5;7083:25;;;;1354::21;;1342:2;1327:18;;1208:177;7083:25:2;;;;;;;;6008:1107;;;:::o;2078:378:10:-;2137:13;2162:11;2176:16;2187:4;2176:10;:16::i;:::-;2300:14;;;2311:2;2300:14;;;;;;;;;2162:30;;-1:-1:-1;2280:17:10;;2300:14;;;;;;;;;-1:-1:-1;;;2363:16:10;;;-1:-1:-1;2408:4:10;2399:14;;2392:28;;;;-1:-1:-1;2363:16:10;2078:378::o;2528:245::-;2589:7;2661:4;2625:40;;2688:2;2679:11;;2675:69;;;2713:20;;-1:-1:-1;;;2713:20:10;;;;;;;;;;;14:289:21;56:3;94:5;88:12;121:6;116:3;109:19;177:6;170:4;163:5;159:16;152:4;147:3;143:14;137:47;229:1;222:4;213:6;208:3;204:16;200:27;193:38;292:4;285:2;281:7;276:2;268:6;264:15;260:29;255:3;251:39;247:50;240:57;;;14:289;;;;:::o;308:220::-;457:2;446:9;439:21;420:4;477:45;518:2;507:9;503:18;495:6;477:45;:::i;:::-;469:53;308:220;-1:-1:-1;;;308:220:21:o;533:173::-;601:20;;-1:-1:-1;;;;;650:31:21;;640:42;;630:70;;696:1;693;686:12;630:70;533:173;;;:::o;711:300::-;779:6;787;840:2;828:9;819:7;815:23;811:32;808:52;;;856:1;853;846:12;808:52;879:29;898:9;879:29;:::i;:::-;869:39;977:2;962:18;;;;949:32;;-1:-1:-1;;;711:300:21:o;1572:374::-;1649:6;1657;1665;1718:2;1706:9;1697:7;1693:23;1689:32;1686:52;;;1734:1;1731;1724:12;1686:52;1757:29;1776:9;1757:29;:::i;:::-;1747:39;;1805:38;1839:2;1828:9;1824:18;1805:38;:::i;:::-;1572:374;;1795:48;;-1:-1:-1;;;1912:2:21;1897:18;;;;1884:32;;1572:374::o;1951:347::-;2016:6;2024;2077:2;2065:9;2056:7;2052:23;2048:32;2045:52;;;2093:1;2090;2083:12;2045:52;2116:29;2135:9;2116:29;:::i;:::-;2106:39;;2195:2;2184:9;2180:18;2167:32;2242:5;2235:13;2228:21;2221:5;2218:32;2208:60;;2264:1;2261;2254:12;2208:60;2287:5;2277:15;;;1951:347;;;;;:::o;2492:226::-;2551:6;2604:2;2592:9;2583:7;2579:23;2575:32;2572:52;;;2620:1;2617;2610:12;2572:52;-1:-1:-1;2665:23:21;;2492:226;-1:-1:-1;2492:226:21:o;3162:186::-;3221:6;3274:2;3262:9;3253:7;3249:23;3245:32;3242:52;;;3290:1;3287;3280:12;3242:52;3313:29;3332:9;3313:29;:::i;3353:1238::-;3759:3;3754;3750:13;3742:6;3738:26;3727:9;3720:45;3801:3;3796:2;3785:9;3781:18;3774:31;3701:4;3828:46;3869:3;3858:9;3854:19;3846:6;3828:46;:::i;:::-;3922:9;3914:6;3910:22;3905:2;3894:9;3890:18;3883:50;3956:33;3982:6;3974;3956:33;:::i;:::-;4020:2;4005:18;;3998:34;;;-1:-1:-1;;;;;4069:32:21;;4063:3;4048:19;;4041:61;4089:3;4118:19;;4111:35;;;4183:22;;;4177:3;4162:19;;4155:51;4255:13;;4277:22;;;4327:2;4353:15;;;;-1:-1:-1;4315:15:21;;;;-1:-1:-1;4396:169:21;4410:6;4407:1;4404:13;4396:169;;;4471:13;;4459:26;;4514:2;4540:15;;;;4505:12;;;;4432:1;4425:9;4396:169;;;-1:-1:-1;4582:3:21;;3353:1238;-1:-1:-1;;;;;;;;;;;3353:1238:21:o;4901:903::-;5012:6;5020;5028;5036;5044;5052;5060;5113:3;5101:9;5092:7;5088:23;5084:33;5081:53;;;5130:1;5127;5120:12;5081:53;5153:29;5172:9;5153:29;:::i;:::-;5143:39;;5201:38;5235:2;5224:9;5220:18;5201:38;:::i;:::-;5191:48;-1:-1:-1;5308:2:21;5293:18;;5280:32;;-1:-1:-1;5409:2:21;5394:18;;5381:32;;-1:-1:-1;5491:3:21;5476:19;;5463:33;5540:4;5527:18;;5515:31;;5505:59;;5560:1;5557;5550:12;5505:59;4901:903;;;;-1:-1:-1;4901:903:21;;;;5583:7;5663:3;5648:19;;5635:33;;-1:-1:-1;5767:3:21;5752:19;;;5739:33;;4901:903;-1:-1:-1;;4901:903:21:o;5809:260::-;5877:6;5885;5938:2;5926:9;5917:7;5913:23;5909:32;5906:52;;;5954:1;5951;5944:12;5906:52;5977:29;5996:9;5977:29;:::i;:::-;5967:39;;6025:38;6059:2;6048:9;6044:18;6025:38;:::i;:::-;6015:48;;5809:260;;;;;:::o;6074:380::-;6153:1;6149:12;;;;6196;;;6217:61;;6271:4;6263:6;6259:17;6249:27;;6217:61;6324:2;6316:6;6313:14;6293:18;6290:38;6287:161;;6370:10;6365:3;6361:20;6358:1;6351:31;6405:4;6402:1;6395:15;6433:4;6430:1;6423:15;6287:161;;6074:380;;;:::o;6459:340::-;6661:2;6643:21;;;6700:2;6680:18;;;6673:30;-1:-1:-1;;;6734:2:21;6719:18;;6712:46;6790:2;6775:18;;6459:340::o;7083:127::-;7144:10;7139:3;7135:20;7132:1;7125:31;7175:4;7172:1;7165:15;7199:4;7196:1;7189:15;7215:125;7280:9;;;7301:10;;;7298:36;;;7314:18;;:::i;7694:350::-;7896:2;7878:21;;;7935:2;7915:18;;;7908:30;7974:28;7969:2;7954:18;;7947:56;8035:2;8020:18;;7694:350::o;8403:128::-;8470:9;;;8491:11;;;8488:37;;;8505:18;;:::i;12574:168::-;12647:9;;;12678;;12695:15;;;12689:22;;12675:37;12665:71;;12716:18;;:::i;12747:217::-;12787:1;12813;12803:132;;12857:10;12852:3;12848:20;12845:1;12838:31;12892:4;12889:1;12882:15;12920:4;12917:1;12910:15;12803:132;-1:-1:-1;12949:9:21;;12747:217::o;14208:127::-;14269:10;14264:3;14260:20;14257:1;14250:31;14300:4;14297:1;14290:15;14324:4;14321:1;14314:15
Swarm Source
ipfs://885582c1b5ccc42c614c537866554764f343616c0e35e434f7713cc3dbd7c794
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.