Token Fantom Idexo Token

 

Overview ERC-20

Price
$0.00 @ 0.000000 FTM
Fully Diluted Market Cap
Total Supply:
9,876,282.467077 FIDO

Holders:
108 addresses

Transfers:
-

Contract:
0x7aa1d538bc7b8f756179d37fb92dc0435fb71ab10x7AA1D538Bc7B8f756179D37FB92DC0435FB71aB1

Decimals:
18

Social Profiles:
Not Available, Update ?

Loading
[ Download CSV Export  ] 
Loading
[ Download CSV Export  ] 
Loading

Click here to update the token ICO / general information
# Exchange Pair Price  24H Volume % Volume
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
FIDO

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-11-24
*/

pragma solidity 0.8.4;


// SPDX-License-Identifier: MIT
/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}


/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}


/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}


/*
 * @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) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}


/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping (address => uint256) private _balances;

    mapping (address => mapping (address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The defaut value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor (string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);

        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        _approve(sender, _msgSender(), currentAllowance - amount);

        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        uint256 currentAllowance = _allowances[_msgSender()][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        _approve(_msgSender(), spender, currentAllowance - subtractedValue);

        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        _balances[sender] = senderBalance - amount;
        _balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        _balances[account] = accountBalance - amount;
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be to transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}


/**
 * @dev 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 {
    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        // Divide the signature in r, s and v variables
        bytes32 r;
        bytes32 s;
        uint8 v;

        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        if (signature.length == 65) {
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            // solhint-disable-next-line no-inline-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
        } else if (signature.length == 64) {
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            // solhint-disable-next-line no-inline-assembly
            assembly {
                let vs := mload(add(signature, 0x40))
                r := mload(add(signature, 0x20))
                s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
                v := add(shr(255, vs), 27)
            }
        } else {
            revert("ECDSA: invalid signature length");
        }

        return recover(hash, v, r, s);
    }

    /**
     * @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) {
        // 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 (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): 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.
        require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "ECDSA: invalid signature 's' value");
        require(v == 27 || v == 28, "ECDSA: invalid signature 'v' value");

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        require(signer != address(0), "ECDSA: invalid signature");

        return signer;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}


/**
 * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
 *
 * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
 * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
 * they need in their contracts using a combination of `abi.encode` and `keccak256`.
 *
 * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
 * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
 * ({_hashTypedDataV4}).
 *
 * The implementation of the domain separator was designed to be as efficient as possible while still properly updating
 * the chain id to protect against replay attacks on an eventual fork of the chain.
 *
 * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
 * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
 *
 * _Available since v3.4._
 */
abstract contract EIP712 {
    /* solhint-disable var-name-mixedcase */
    // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to
    // invalidate the cached domain separator if the chain id changes.
    bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;
    uint256 private immutable _CACHED_CHAIN_ID;

    bytes32 private immutable _HASHED_NAME;
    bytes32 private immutable _HASHED_VERSION;
    bytes32 private immutable _TYPE_HASH;
    /* solhint-enable var-name-mixedcase */

    /**
     * @dev Initializes the domain separator and parameter caches.
     *
     * The meaning of `name` and `version` is specified in
     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
     *
     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
     * - `version`: the current major version of the signing domain.
     *
     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
     * contract upgrade].
     */
    constructor(string memory name, string memory version) {
        bytes32 hashedName = keccak256(bytes(name));
        bytes32 hashedVersion = keccak256(bytes(version));
        bytes32 typeHash = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
        _HASHED_NAME = hashedName;
        _HASHED_VERSION = hashedVersion;
        _CACHED_CHAIN_ID = block.chainid;
        _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);
        _TYPE_HASH = typeHash;
    }

    /**
     * @dev Returns the domain separator for the current chain.
     */
    function _domainSeparatorV4() internal view returns (bytes32) {
        if (block.chainid == _CACHED_CHAIN_ID) {
            return _CACHED_DOMAIN_SEPARATOR;
        } else {
            return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
        }
    }

    function _buildDomainSeparator(bytes32 typeHash, bytes32 name, bytes32 version) private view returns (bytes32) {
        return keccak256(
            abi.encode(
                typeHash,
                name,
                version,
                block.chainid,
                address(this)
            )
        );
    }

    /**
     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
     * function returns the hash of the fully encoded EIP712 message for this domain.
     *
     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
     *
     * ```solidity
     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
     *     keccak256("Mail(address to,string contents)"),
     *     mailTo,
     *     keccak256(bytes(mailContents))
     * )));
     * address signer = ECDSA.recover(digest, signature);
     * ```
     */
    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
        return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);
    }
}


/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }
}


/**
 * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 *
 * _Available since v3.4._
 */
abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {
    using Counters for Counters.Counter;

    mapping (address => Counters.Counter) private _nonces;

    // solhint-disable-next-line var-name-mixedcase
    bytes32 private immutable _PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");

    /**
     * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`.
     *
     * It's a good idea to use the same `name` that is defined as the ERC20 token name.
     */
    constructor(string memory name) EIP712(name, "1") {
    }

    /**
     * @dev See {IERC20Permit-permit}.
     */
    function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override {
        // solhint-disable-next-line not-rely-on-time
        require(block.timestamp <= deadline, "ERC20Permit: expired deadline");

        bytes32 structHash = keccak256(
            abi.encode(
                _PERMIT_TYPEHASH,
                owner,
                spender,
                value,
                _useNonce(owner),
                deadline
            )
        );

        bytes32 hash = _hashTypedDataV4(structHash);

        address signer = ECDSA.recover(hash, v, r, s);
        require(signer == owner, "ERC20Permit: invalid signature");

        _approve(owner, spender, value);
    }

    /**
     * @dev See {IERC20Permit-nonces}.
     */
    function nonces(address owner) public view virtual override returns (uint256) {
        return _nonces[owner].current();
    }

    /**
     * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view override returns (bytes32) {
        return _domainSeparatorV4();
    }

    /**
     * @dev "Consume a nonce": return the current value and increment.
     *
     * _Available since v4.1._
     */
    function _useNonce(address owner) internal virtual returns (uint256 current) {
        Counters.Counter storage nonce = _nonces[owner];
        current = nonce.current();
        nonce.increment();
    }
}


interface IFIDO is IERC20 {
    function setRelayer(address newRelayer) external;

    function renounceOwnership() external;

    function transferOwnership(address _newOwner) external;

    function acceptOwnership() external;

    function mint(
        address account,
        uint256 amount
    ) external;

    function burn(
        address account,
        uint256 amount
    ) external;

    function getChainId() external view returns (uint256);
}


contract FIDO is IFIDO, ERC20Permit {
    // Contract owner address
    address public owner;
    // Proposed new contract owner address
    address public newOwner;
    // Cross-chain transfer relayer contract address
    address public relayer;
    uint256 public constant cap = 100 * 1000 * 1000 * 1 ether;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    event RelayerAddressChanged(address indexed relayer);

    constructor() ERC20("Fantom Idexo Token", "FIDO") ERC20Permit("Fantom Idexo Token") {
        owner = _msgSender();
        emit OwnershipTransferred(address(0), _msgSender());
    }

    /**************************|
    |          Setters         |
    |_________________________*/

    /**
     * @dev Set relayer address
     * Only owner can call
     */
    function setRelayer(address newRelayer) external override onlyOwner {
        require(newRelayer != address(0), "WIDO: NEW_RELAYER_ADDRESS_INVALID");
        relayer = newRelayer;

        emit RelayerAddressChanged(newRelayer);
    }

    /****************************|
    |          Ownership         |
    |___________________________*/

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner == _msgSender(), "WIDO: CALLER_NO_OWNER");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() external override onlyOwner {
        emit OwnershipTransferred(owner, address(0));
        owner = address(0);
    }

    /**
     * @dev Transfer the contract ownership.
     * The new owner still needs to accept the transfer.
     * can only be called by the contract owner.
     *
     * @param _newOwner new contract owner.
     */
    function transferOwnership(address _newOwner) external override onlyOwner {
        require(_newOwner != address(0), "WIDO: INVALID_ADDRESS");
        require(_newOwner != owner, "WIDO: OWNERSHIP_SELF_TRANSFER");
        newOwner = _newOwner;
    }

    /**
     * @dev The new owner accept an ownership transfer.
     */
    function acceptOwnership() external override {
        require(_msgSender() == newOwner, "WIDO: CALLER_NO_NEW_OWNER");
        emit OwnershipTransferred(owner, newOwner);
        owner = newOwner;
        newOwner = address(0);
    }

    /************************|
    |          Token         |
    |_______________________*/

    /**
     * @dev Mint new WIDO
     * Only relayer can call
     */
    function mint(
        address account,
        uint256 amount
    ) external override {
        require(_msgSender() == relayer, "WIDO: CALLER_NO_RELAYER");
        require(totalSupply() + amount <= cap, "WIDO: AMOUNT_EXCEEDS_CAP");
        _mint(account, amount);
    }

    /**
     * @dev Burn WIDO
     * Only relayer can call
     */
    function burn(
        address account,
        uint256 amount
    ) external override {
        require(_msgSender() == relayer, "WIDO: CALLER_NO_RELAYER");
        _burn(account, amount);
    }

    /**
     * @dev Get chain id.
     */
    function getChainId() public override view returns (uint256) {
        uint256 id;
        assembly { id := chainid() }
        return id;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"relayer","type":"address"}],"name":"RelayerAddressChanged","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":"acceptOwnership","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":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"newOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"relayer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newRelayer","type":"address"}],"name":"setRelayer","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":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6101406040527f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9610120523480156200003757600080fd5b50604051806040016040528060128152602001712330b73a37b69024b232bc37902a37b5b2b760711b81525080604051806040016040528060018152602001603160f81b815250604051806040016040528060128152602001712330b73a37b69024b232bc37902a37b5b2b760711b815250604051806040016040528060048152602001634649444f60e01b8152508160039080519060200190620000de929190620001c5565b508051620000f4906004906020840190620001c5565b5050825160209384012082519284019290922060c083815260e08290524660a0818152604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818a018190528183019890985260608101959095526080808601939093523085830152805180860390920182529390920192839052815191909501209093525061010052600680546001600160a01b0319163390811790915591506000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3620002a8565b828054620001d3906200026b565b90600052602060002090601f016020900481019282620001f7576000855562000242565b82601f106200021257805160ff191683800117855562000242565b8280016001018555821562000242579182015b828111156200024257825182559160200191906001019062000225565b506200025092915062000254565b5090565b5b8082111562000250576000815560010162000255565b600181811c908216806200028057607f821691505b60208210811415620002a257634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05160e0516101005161012051611660620002f860003960006109a501526000610f0001526000610f4f01526000610f2a01526000610eae01526000610ed701526116606000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c8063715018a6116100de5780639dc29fac11610097578063d4ee1d9011610071578063d4ee1d9014610313578063d505accf14610326578063dd62ed3e14610339578063f2fde38b1461037257600080fd5b80639dc29fac146102da578063a457c2d7146102ed578063a9059cbb1461030057600080fd5b8063715018a61461027157806379ba5097146102795780637ecebe00146102815780638406c079146102945780638da5cb5b146102bf57806395d89b41146102d257600080fd5b8063355274ea11610130578063355274ea146101f35780633644e51514610205578063395093511461020d57806340c10f19146102205780636548e9bc1461023557806370a082311461024857600080fd5b806306fdde0314610178578063095ea7b31461019657806318160ddd146101b957806323b872dd146101cb578063313ce567146101de5780633408e470146101ed575b600080fd5b610180610385565b60405161018d919061152e565b60405180910390f35b6101a96101a4366004611505565b610417565b604051901515815260200161018d565b6002545b60405190815260200161018d565b6101a96101d9366004611459565b61042d565b6040516012815260200161018d565b466101bd565b6101bd6a52b7d2dcc80cd2e400000081565b6101bd6104e3565b6101a961021b366004611505565b6104f2565b61023361022e366004611505565b610529565b005b610233610243366004611406565b610602565b6101bd610256366004611406565b6001600160a01b031660009081526020819052604090205490565b6102336106d6565b61023361074a565b6101bd61028f366004611406565b610813565b6008546102a7906001600160a01b031681565b6040516001600160a01b03909116815260200161018d565b6006546102a7906001600160a01b031681565b610180610833565b6102336102e8366004611505565b610842565b6101a96102fb366004611505565b6108a9565b6101a961030e366004611505565b610944565b6007546102a7906001600160a01b031681565b610233610334366004611494565b610951565b6101bd610347366004611427565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610233610380366004611406565b610ab5565b606060038054610394906115df565b80601f01602080910402602001604051908101604052809291908181526020018280546103c0906115df565b801561040d5780601f106103e25761010080835404028352916020019161040d565b820191906000526020600020905b8154815290600101906020018083116103f057829003601f168201915b5050505050905090565b6000610424338484610bad565b50600192915050565b600061043a848484610cd2565b6001600160a01b0384166000908152600160209081526040808320338452909152902054828110156104c45760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b60648201526084015b60405180910390fd5b6104d885336104d386856115c8565b610bad565b506001949350505050565b60006104ed610eaa565b905090565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916104249185906104d39086906115b0565b6008546001600160a01b0316336001600160a01b0316146105865760405162461bcd60e51b81526020600482015260176024820152762ba4a2279d1021a0a62622a92fa727afa922a620aca2a960491b60448201526064016104bb565b6a52b7d2dcc80cd2e40000008161059c60025490565b6105a691906115b0565b11156105f45760405162461bcd60e51b815260206004820152601860248201527f5749444f3a20414d4f554e545f455843454544535f434150000000000000000060448201526064016104bb565b6105fe8282610f9d565b5050565b6006546001600160a01b0316331461062c5760405162461bcd60e51b81526004016104bb90611581565b6001600160a01b03811661068c5760405162461bcd60e51b815260206004820152602160248201527f5749444f3a204e45575f52454c415945525f414444524553535f494e56414c496044820152601160fa1b60648201526084016104bb565b600880546001600160a01b0319166001600160a01b0383169081179091556040517f83e487c6ca4a8fee9120216fcef0e6e791e0848baaefe085e58b0e5d674a6d4d90600090a250565b6006546001600160a01b031633146107005760405162461bcd60e51b81526004016104bb90611581565b6006546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600680546001600160a01b0319169055565b6007546001600160a01b0316336001600160a01b0316146107ad5760405162461bcd60e51b815260206004820152601960248201527f5749444f3a2043414c4c45525f4e4f5f4e45575f4f574e45520000000000000060448201526064016104bb565b6007546006546040516001600160a01b0392831692909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a360078054600680546001600160a01b03199081166001600160a01b03841617909155169055565b6001600160a01b0381166000908152600560205260408120545b92915050565b606060048054610394906115df565b6008546001600160a01b0316336001600160a01b03161461089f5760405162461bcd60e51b81526020600482015260176024820152762ba4a2279d1021a0a62622a92fa727afa922a620aca2a960491b60448201526064016104bb565b6105fe828261107c565b3360009081526001602090815260408083206001600160a01b03861684529091528120548281101561092b5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016104bb565b61093a33856104d386856115c8565b5060019392505050565b6000610424338484610cd2565b834211156109a15760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e6500000060448201526064016104bb565b60007f00000000000000000000000000000000000000000000000000000000000000008888886109d08c6111cb565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610a2b826111f3565b90506000610a3b82878787611241565b9050896001600160a01b0316816001600160a01b031614610a9e5760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e6174757265000060448201526064016104bb565b610aa98a8a8a610bad565b50505050505050505050565b6006546001600160a01b03163314610adf5760405162461bcd60e51b81526004016104bb90611581565b6001600160a01b038116610b2d5760405162461bcd60e51b81526020600482015260156024820152745749444f3a20494e56414c49445f4144445245535360581b60448201526064016104bb565b6006546001600160a01b0382811691161415610b8b5760405162461bcd60e51b815260206004820152601d60248201527f5749444f3a204f574e4552534849505f53454c465f5452414e5346455200000060448201526064016104bb565b600780546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038316610c0f5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016104bb565b6001600160a01b038216610c705760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016104bb565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b038316610d365760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016104bb565b6001600160a01b038216610d985760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016104bb565b6001600160a01b03831660009081526020819052604090205481811015610e105760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016104bb565b610e1a82826115c8565b6001600160a01b038086166000908152602081905260408082209390935590851681529081208054849290610e509084906115b0565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e9c91815260200190565b60405180910390a350505050565b60007f0000000000000000000000000000000000000000000000000000000000000000461415610ef957507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b6001600160a01b038216610ff35760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016104bb565b806002600082825461100591906115b0565b90915550506001600160a01b038216600090815260208190526040812080548392906110329084906115b0565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b0382166110dc5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016104bb565b6001600160a01b038216600090815260208190526040902054818110156111505760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016104bb565b61115a82826115c8565b6001600160a01b038416600090815260208190526040812091909155600280548492906111889084906115c8565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610cc5565b6001600160a01b03811660009081526005602052604090208054600181018255905b50919050565b600061082d611200610eaa565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08211156112be5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016104bb565b8360ff16601b14806112d357508360ff16601c145b61132a5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016104bb565b6040805160008082526020820180845288905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa15801561137e573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166113e15760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016104bb565b95945050505050565b80356001600160a01b038116811461140157600080fd5b919050565b600060208284031215611417578081fd5b611420826113ea565b9392505050565b60008060408385031215611439578081fd5b611442836113ea565b9150611450602084016113ea565b90509250929050565b60008060006060848603121561146d578081fd5b611476846113ea565b9250611484602085016113ea565b9150604084013590509250925092565b600080600080600080600060e0888a0312156114ae578283fd5b6114b7886113ea565b96506114c5602089016113ea565b95506040880135945060608801359350608088013560ff811681146114e8578384fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215611517578182fd5b611520836113ea565b946020939093013593505050565b6000602080835283518082850152825b8181101561155a5785810183015185820160400152820161153e565b8181111561156b5783604083870101525b50601f01601f1916929092016040019392505050565b6020808252601590820152742ba4a2279d1021a0a62622a92fa727afa7aba722a960591b604082015260600190565b600082198211156115c3576115c3611614565b500190565b6000828210156115da576115da611614565b500390565b600181811c908216806115f357607f821691505b602082108114156111ed57634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fdfea2646970667358221220f5b2940570b86c2e4ac608fc1b196f88660b7208053af00ee0e0f764630f551964736f6c63430008040033

Deployed ByteCode Sourcemap

31197:3649:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8285:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10452:169;;;;;;:::i;:::-;;:::i;:::-;;;2768:14:1;;2761:22;2743:41;;2731:2;2716:18;10452:169:0;2698:92:1;9405:108:0;9493:12;;9405:108;;;2941:25:1;;;2929:2;2914:18;9405:108:0;2896:76:1;11103:422:0;;;;;;:::i;:::-;;:::i;9247:93::-;;;9330:2;13802:36:1;;13790:2;13775:18;9247:93:0;13757:87:1;34695:148:0;34805:9;34695:148;;31455:57;;31485:27;31455:57;;30244:115;;;:::i;11934:215::-;;;;;;:::i;:::-;;:::i;34084:278::-;;;;;;:::i;:::-;;:::i;:::-;;32048:239;;;;;;:::i;:::-;;:::i;9576:127::-;;;;;;:::i;:::-;-1:-1:-1;;;;;9677:18:0;9650:7;9677:18;;;;;;;;;;;;9576:127;32948:149;;;:::i;33665:238::-;;;:::i;29986:128::-;;;;;;:::i;:::-;;:::i;31426:22::-;;;;;-1:-1:-1;;;;;31426:22:0;;;;;;-1:-1:-1;;;;;2559:32:1;;;2541:51;;2529:2;2514:18;31426:22:0;2496:102:1;31271:20:0;;;;;-1:-1:-1;;;;;31271:20:0;;;8504:104;;;:::i;34441:201::-;;;;;;:::i;:::-;;:::i;12652:377::-;;;;;;:::i;:::-;;:::i;9916:175::-;;;;;;:::i;:::-;;:::i;31342:23::-;;;;;-1:-1:-1;;;;;31342:23:0;;;29149:771;;;;;;:::i;:::-;;:::i;10154:151::-;;;;;;:::i;:::-;-1:-1:-1;;;;;10270:18:0;;;10243:7;10270:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;10154:151;33330:252;;;;;;:::i;:::-;;:::i;8285:100::-;8339:13;8372:5;8365:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8285:100;:::o;10452:169::-;10535:4;10552:39;6045:10;10575:7;10584:6;10552:8;:39::i;:::-;-1:-1:-1;10609:4:0;10452:169;;;;:::o;11103:422::-;11209:4;11226:36;11236:6;11244:9;11255:6;11226:9;:36::i;:::-;-1:-1:-1;;;;;11302:19:0;;11275:24;11302:19;;;:11;:19;;;;;;;;6045:10;11302:33;;;;;;;;11354:26;;;;11346:79;;;;-1:-1:-1;;;11346:79:0;;10584:2:1;11346:79:0;;;10566:21:1;10623:2;10603:18;;;10596:30;10662:34;10642:18;;;10635:62;-1:-1:-1;;;10713:18:1;;;10706:38;10761:19;;11346:79:0;;;;;;;;;11436:57;11445:6;6045:10;11467:25;11486:6;11467:16;:25;:::i;:::-;11436:8;:57::i;:::-;-1:-1:-1;11513:4:0;;11103:422;-1:-1:-1;;;;11103:422:0:o;30244:115::-;30304:7;30331:20;:18;:20::i;:::-;30324:27;;30244:115;:::o;11934:215::-;6045:10;12022:4;12071:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;12071:34:0;;;;;;;;;;12022:4;;12039:80;;12062:7;;12071:47;;12108:10;;12071:47;:::i;34084:278::-;34209:7;;-1:-1:-1;;;;;34209:7:0;6045:10;-1:-1:-1;;;;;34193:23:0;;34185:59;;;;-1:-1:-1;;;34185:59:0;;9873:2:1;34185:59:0;;;9855:21:1;9912:2;9892:18;;;9885:30;-1:-1:-1;;;9931:18:1;;;9924:53;9994:18;;34185:59:0;9845:173:1;34185:59:0;31485:27;34279:6;34263:13;9493:12;;;9405:108;34263:13;:22;;;;:::i;:::-;:29;;34255:66;;;;-1:-1:-1;;;34255:66:0;;6391:2:1;34255:66:0;;;6373:21:1;6430:2;6410:18;;;6403:30;6469:26;6449:18;;;6442:54;6513:18;;34255:66:0;6363:174:1;34255:66:0;34332:22;34338:7;34347:6;34332:5;:22::i;:::-;34084:278;;:::o;32048:239::-;32530:5;;-1:-1:-1;;;;;32530:5:0;6045:10;32530:21;32522:55;;;;-1:-1:-1;;;32522:55:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;32135:24:0;::::1;32127:70;;;::::0;-1:-1:-1;;;32127:70:0;;8718:2:1;32127:70:0::1;::::0;::::1;8700:21:1::0;8757:2;8737:18;;;8730:30;8796:34;8776:18;;;8769:62;-1:-1:-1;;;8847:18:1;;;8840:31;8888:19;;32127:70:0::1;8690:223:1::0;32127:70:0::1;32208:7;:20:::0;;-1:-1:-1;;;;;;32208:20:0::1;-1:-1:-1::0;;;;;32208:20:0;::::1;::::0;;::::1;::::0;;;32246:33:::1;::::0;::::1;::::0;-1:-1:-1;;32246:33:0::1;32048:239:::0;:::o;32948:149::-;32530:5;;-1:-1:-1;;;;;32530:5:0;6045:10;32530:21;32522:55;;;;-1:-1:-1;;;32522:55:0;;;;;;;:::i;:::-;33042:5:::1;::::0;33021:39:::1;::::0;33057:1:::1;::::0;-1:-1:-1;;;;;33042:5:0::1;::::0;33021:39:::1;::::0;33057:1;;33021:39:::1;33071:5;:18:::0;;-1:-1:-1;;;;;;33071:18:0::1;::::0;;32948:149::o;33665:238::-;33745:8;;-1:-1:-1;;;;;33745:8:0;6045:10;-1:-1:-1;;;;;33729:24:0;;33721:62;;;;-1:-1:-1;;;33721:62:0;;6037:2:1;33721:62:0;;;6019:21:1;6076:2;6056:18;;;6049:30;6115:27;6095:18;;;6088:55;6160:18;;33721:62:0;6009:175:1;33721:62:0;33827:8;;33820:5;;33799:37;;-1:-1:-1;;;;;33827:8:0;;;;33820:5;;;;33799:37;;33827:8;;33799:37;33855:8;;;33847:5;:16;;-1:-1:-1;;;;;;33847:16:0;;;-1:-1:-1;;;;;33855:8:0;;33847:16;;;;33874:21;;;33665:238::o;29986:128::-;-1:-1:-1;;;;;30082:14:0;;30055:7;30082:14;;;:7;:14;;;;;27482;30082:24;30075:31;29986:128;-1:-1:-1;;29986:128:0:o;8504:104::-;8560:13;8593:7;8586:14;;;;;:::i;34441:201::-;34566:7;;-1:-1:-1;;;;;34566:7:0;6045:10;-1:-1:-1;;;;;34550:23:0;;34542:59;;;;-1:-1:-1;;;34542:59:0;;9873:2:1;34542:59:0;;;9855:21:1;9912:2;9892:18;;;9885:30;-1:-1:-1;;;9931:18:1;;;9924:53;9994:18;;34542:59:0;9845:173:1;34542:59:0;34612:22;34618:7;34627:6;34612:5;:22::i;12652:377::-;6045:10;12745:4;12789:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;12789:34:0;;;;;;;;;;12842:35;;;;12834:85;;;;-1:-1:-1;;;12834:85:0;;12914:2:1;12834:85:0;;;12896:21:1;12953:2;12933:18;;;12926:30;12992:34;12972:18;;;12965:62;-1:-1:-1;;;13043:18:1;;;13036:35;13088:19;;12834:85:0;12886:227:1;12834:85:0;12930:67;6045:10;12953:7;12962:34;12981:15;12962:16;:34;:::i;12930:67::-;-1:-1:-1;13017:4:0;;12652:377;-1:-1:-1;;;12652:377:0:o;9916:175::-;10002:4;10019:42;6045:10;10043:9;10054:6;10019:9;:42::i;29149:771::-;29378:8;29359:15;:27;;29351:69;;;;-1:-1:-1;;;29351:69:0;;7550:2:1;29351:69:0;;;7532:21:1;7589:2;7569:18;;;7562:30;7628:31;7608:18;;;7601:59;7677:18;;29351:69:0;7522:179:1;29351:69:0;29433:18;29507:16;29542:5;29566:7;29592:5;29616:16;29626:5;29616:9;:16::i;:::-;29478:196;;;;;;3264:25:1;;;;-1:-1:-1;;;;;3363:15:1;;;3343:18;;;3336:43;3415:15;;;;3395:18;;;3388:43;3447:18;;;3440:34;3490:19;;;3483:35;3534:19;;;3527:35;;;3236:19;;29478:196:0;;;;;;;;;;;;29454:231;;;;;;29433:252;;29698:12;29713:28;29730:10;29713:16;:28::i;:::-;29698:43;;29754:14;29771:28;29785:4;29791:1;29794;29797;29771:13;:28::i;:::-;29754:45;;29828:5;-1:-1:-1;;;;;29818:15:0;:6;-1:-1:-1;;;;;29818:15:0;;29810:58;;;;-1:-1:-1;;;29810:58:0;;10225:2:1;29810:58:0;;;10207:21:1;10264:2;10244:18;;;10237:30;10303:32;10283:18;;;10276:60;10353:18;;29810:58:0;10197:180:1;29810:58:0;29881:31;29890:5;29897:7;29906:5;29881:8;:31::i;:::-;29149:771;;;;;;;;;;:::o;33330:252::-;32530:5;;-1:-1:-1;;;;;32530:5:0;6045:10;32530:21;32522:55;;;;-1:-1:-1;;;32522:55:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;33423:23:0;::::1;33415:57;;;::::0;-1:-1:-1;;;33415:57:0;;9523:2:1;33415:57:0::1;::::0;::::1;9505:21:1::0;9562:2;9542:18;;;9535:30;-1:-1:-1;;;9581:18:1;;;9574:51;9642:18;;33415:57:0::1;9495:171:1::0;33415:57:0::1;33504:5;::::0;-1:-1:-1;;;;;33491:18:0;;::::1;33504:5:::0;::::1;33491:18;;33483:60;;;::::0;-1:-1:-1;;;33483:60:0;;12556:2:1;33483:60:0::1;::::0;::::1;12538:21:1::0;12595:2;12575:18;;;12568:30;12634:31;12614:18;;;12607:59;12683:18;;33483:60:0::1;12528:179:1::0;33483:60:0::1;33554:8;:20:::0;;-1:-1:-1;;;;;;33554:20:0::1;-1:-1:-1::0;;;;;33554:20:0;;;::::1;::::0;;;::::1;::::0;;33330:252::o;16008:346::-;-1:-1:-1;;;;;16110:19:0;;16102:68;;;;-1:-1:-1;;;16102:68:0;;12151:2:1;16102:68:0;;;12133:21:1;12190:2;12170:18;;;12163:30;12229:34;12209:18;;;12202:62;-1:-1:-1;;;12280:18:1;;;12273:34;12324:19;;16102:68:0;12123:226:1;16102:68:0;-1:-1:-1;;;;;16189:21:0;;16181:68;;;;-1:-1:-1;;;16181:68:0;;7147:2:1;16181:68:0;;;7129:21:1;7186:2;7166:18;;;7159:30;7225:34;7205:18;;;7198:62;-1:-1:-1;;;7276:18:1;;;7269:32;7318:19;;16181:68:0;7119:224:1;16181:68:0;-1:-1:-1;;;;;16262:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;16314:32;;2941:25:1;;;16314:32:0;;2914:18:1;16314:32:0;;;;;;;;16008:346;;;:::o;13519:604::-;-1:-1:-1;;;;;13625:20:0;;13617:70;;;;-1:-1:-1;;;13617:70:0;;11745:2:1;13617:70:0;;;11727:21:1;11784:2;11764:18;;;11757:30;11823:34;11803:18;;;11796:62;-1:-1:-1;;;11874:18:1;;;11867:35;11919:19;;13617:70:0;11717:227:1;13617:70:0;-1:-1:-1;;;;;13706:23:0;;13698:71;;;;-1:-1:-1;;;13698:71:0;;5633:2:1;13698:71:0;;;5615:21:1;5672:2;5652:18;;;5645:30;5711:34;5691:18;;;5684:62;-1:-1:-1;;;5762:18:1;;;5755:33;5805:19;;13698:71:0;5605:225:1;13698:71:0;-1:-1:-1;;;;;13866:17:0;;13842:21;13866:17;;;;;;;;;;;13902:23;;;;13894:74;;;;-1:-1:-1;;;13894:74:0;;7908:2:1;13894:74:0;;;7890:21:1;7947:2;7927:18;;;7920:30;7986:34;7966:18;;;7959:62;-1:-1:-1;;;8037:18:1;;;8030:36;8083:19;;13894:74:0;7880:228:1;13894:74:0;13999:22;14015:6;13999:13;:22;:::i;:::-;-1:-1:-1;;;;;13979:17:0;;;:9;:17;;;;;;;;;;;:42;;;;14032:20;;;;;;;;:30;;14056:6;;13979:9;14032:30;;14056:6;;14032:30;:::i;:::-;;;;;;;;14097:9;-1:-1:-1;;;;;14080:35:0;14089:6;-1:-1:-1;;;;;14080:35:0;;14108:6;14080:35;;;;2941:25:1;;2929:2;2914:18;;2896:76;14080:35:0;;;;;;;;13519:604;;;;:::o;25215:281::-;25268:7;25309:16;25292:13;:33;25288:201;;;-1:-1:-1;25349:24:0;;25215:281::o;25288:201::-;-1:-1:-1;25657:165:0;;;25435:10;25657:165;;;;3832:25:1;;;;25447:12:0;3873:18:1;;;3866:34;25461:15:0;3916:18:1;;;3909:34;25762:13:0;3959:18:1;;;3952:34;25802:4:0;4002:19:1;;;;3995:61;;;;25657:165:0;;;;;;;;;;3804:19:1;;;;25657:165:0;;;25633:200;;;;;;30244:115::o;14405:338::-;-1:-1:-1;;;;;14489:21:0;;14481:65;;;;-1:-1:-1;;;14481:65:0;;13320:2:1;14481:65:0;;;13302:21:1;13359:2;13339:18;;;13332:30;13398:33;13378:18;;;13371:61;13449:18;;14481:65:0;13292:181:1;14481:65:0;14637:6;14621:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;14654:18:0;;:9;:18;;;;;;;;;;:28;;14676:6;;14654:9;:28;;14676:6;;14654:28;:::i;:::-;;;;-1:-1:-1;;14698:37:0;;2941:25:1;;;-1:-1:-1;;;;;14698:37:0;;;14715:1;;14698:37;;2929:2:1;2914:18;14698:37:0;;;;;;;14405:338;;:::o;15076:494::-;-1:-1:-1;;;;;15160:21:0;;15152:67;;;;-1:-1:-1;;;15152:67:0;;11343:2:1;15152:67:0;;;11325:21:1;11382:2;11362:18;;;11355:30;11421:34;11401:18;;;11394:62;-1:-1:-1;;;11472:18:1;;;11465:31;11513:19;;15152:67:0;11315:223:1;15152:67:0;-1:-1:-1;;;;;15319:18:0;;15294:22;15319:18;;;;;;;;;;;15356:24;;;;15348:71;;;;-1:-1:-1;;;15348:71:0;;6744:2:1;15348:71:0;;;6726:21:1;6783:2;6763:18;;;6756:30;6822:34;6802:18;;;6795:62;-1:-1:-1;;;6873:18:1;;;6866:32;6915:19;;15348:71:0;6716:224:1;15348:71:0;15451:23;15468:6;15451:14;:23;:::i;:::-;-1:-1:-1;;;;;15430:18:0;;:9;:18;;;;;;;;;;:44;;;;15485:12;:22;;15501:6;;15430:9;15485:22;;15501:6;;15485:22;:::i;:::-;;;;-1:-1:-1;;15525:37:0;;2941:25:1;;;15551:1:0;;-1:-1:-1;;;;;15525:37:0;;;;;2929:2:1;2914:18;15525:37:0;2896:76:1;30497:207:0;-1:-1:-1;;;;;30618:14:0;;30557:15;30618:14;;;:7;:14;;;;;27482;;27619:1;27601:19;;;;27482:14;30679:17;30497:207;;;;:::o;26483:167::-;26560:7;26587:55;26609:20;:18;:20::i;:::-;26631:10;22197:57;;-1:-1:-1;;;22197:57:0;;;2256:27:1;2299:11;;;2292:27;;;2335:12;;;2328:28;;;22160:7:0;;2372:12:1;;22197:57:0;;;;;;;;;;;;22187:68;;;;;;22180:75;;22067:196;;;;;19716:1432;19801:7;20726:66;20712:80;;;20704:127;;;;-1:-1:-1;;;20704:127:0;;8315:2:1;20704:127:0;;;8297:21:1;8354:2;8334:18;;;8327:30;8393:34;8373:18;;;8366:62;-1:-1:-1;;;8444:18:1;;;8437:32;8486:19;;20704:127:0;8287:224:1;20704:127:0;20850:1;:7;;20855:2;20850:7;:18;;;;20861:1;:7;;20866:2;20861:7;20850:18;20842:65;;;;-1:-1:-1;;;20842:65:0;;9120:2:1;20842:65:0;;;9102:21:1;9159:2;9139:18;;;9132:30;9198:34;9178:18;;;9171:62;-1:-1:-1;;;9249:18:1;;;9242:32;9291:19;;20842:65:0;9092:224:1;20842:65:0;21022:24;;;21005:14;21022:24;;;;;;;;;4294:25:1;;;4367:4;4355:17;;4335:18;;;4328:45;;;;4389:18;;;4382:34;;;4432:18;;;4425:34;;;21022:24:0;;4266:19:1;;21022:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;21022:24:0;;-1:-1:-1;;21022:24:0;;;-1:-1:-1;;;;;;;21065:20:0;;21057:57;;;;-1:-1:-1;;;21057:57:0;;5280:2:1;21057:57:0;;;5262:21:1;5319:2;5299:18;;;5292:30;5358:26;5338:18;;;5331:54;5402:18;;21057:57:0;5252:174:1;21057:57:0;21134:6;19716:1432;-1:-1:-1;;;;;19716:1432:0:o;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:2;;177:1;174;167:12;111:2;63:124;;;:::o;192:196::-;251:6;304:2;292:9;283:7;279:23;275:32;272:2;;;325:6;317;310:22;272:2;353:29;372:9;353:29;:::i;:::-;343:39;262:126;-1:-1:-1;;;262:126:1:o;393:270::-;461:6;469;522:2;510:9;501:7;497:23;493:32;490:2;;;543:6;535;528:22;490:2;571:29;590:9;571:29;:::i;:::-;561:39;;619:38;653:2;642:9;638:18;619:38;:::i;:::-;609:48;;480:183;;;;;:::o;668:338::-;745:6;753;761;814:2;802:9;793:7;789:23;785:32;782:2;;;835:6;827;820:22;782:2;863:29;882:9;863:29;:::i;:::-;853:39;;911:38;945:2;934:9;930:18;911:38;:::i;:::-;901:48;;996:2;985:9;981:18;968:32;958:42;;772:234;;;;;:::o;1011:713::-;1122:6;1130;1138;1146;1154;1162;1170;1223:3;1211:9;1202:7;1198:23;1194:33;1191:2;;;1245:6;1237;1230:22;1191:2;1273:29;1292:9;1273:29;:::i;:::-;1263:39;;1321:38;1355:2;1344:9;1340:18;1321:38;:::i;:::-;1311:48;;1406:2;1395:9;1391:18;1378:32;1368:42;;1457:2;1446:9;1442:18;1429:32;1419:42;;1511:3;1500:9;1496:19;1483:33;1556:4;1549:5;1545:16;1538:5;1535:27;1525:2;;1581:6;1573;1566:22;1525:2;1181:543;;;;-1:-1:-1;1181:543:1;;;;1609:5;1661:3;1646:19;;1633:33;;-1:-1:-1;1713:3:1;1698:19;;;1685:33;;1181:543;-1:-1:-1;;1181:543:1:o;1729:264::-;1797:6;1805;1858:2;1846:9;1837:7;1833:23;1829:32;1826:2;;;1879:6;1871;1864:22;1826:2;1907:29;1926:9;1907:29;:::i;:::-;1897:39;1983:2;1968:18;;;;1955:32;;-1:-1:-1;;;1816:177:1:o;4470:603::-;4582:4;4611:2;4640;4629:9;4622:21;4672:6;4666:13;4715:6;4710:2;4699:9;4695:18;4688:34;4740:4;4753:140;4767:6;4764:1;4761:13;4753:140;;;4862:14;;;4858:23;;4852:30;4828:17;;;4847:2;4824:26;4817:66;4782:10;;4753:140;;;4911:6;4908:1;4905:13;4902:2;;;4981:4;4976:2;4967:6;4956:9;4952:22;4948:31;4941:45;4902:2;-1:-1:-1;5057:2:1;5036:15;-1:-1:-1;;5032:29:1;5017:45;;;;5064:2;5013:54;;4591:482;-1:-1:-1;;;4591:482:1:o;10791:345::-;10993:2;10975:21;;;11032:2;11012:18;;;11005:30;-1:-1:-1;;;11066:2:1;11051:18;;11044:51;11127:2;11112:18;;10965:171::o;13849:128::-;13889:3;13920:1;13916:6;13913:1;13910:13;13907:2;;;13926:18;;:::i;:::-;-1:-1:-1;13962:9:1;;13897:80::o;13982:125::-;14022:4;14050:1;14047;14044:8;14041:2;;;14055:18;;:::i;:::-;-1:-1:-1;14092:9:1;;14031:76::o;14112:380::-;14191:1;14187:12;;;;14234;;;14255:2;;14309:4;14301:6;14297:17;14287:27;;14255:2;14362;14354:6;14351:14;14331:18;14328:38;14325:2;;;14408:10;14403:3;14399:20;14396:1;14389:31;14443:4;14440:1;14433:15;14471:4;14468:1;14461:15;14497:127;14558:10;14553:3;14549:20;14546:1;14539:31;14589:4;14586:1;14579:15;14613:4;14610:1;14603:15

Swarm Source

ipfs://f5b2940570b86c2e4ac608fc1b196f88660b7208053af00ee0e0f764630f5519
Loading