Token Forest Knight

 

Overview ERC-20

Price
$0.01 @ 0.010574 MATIC (-2.52%)
Fully Diluted Market Cap
Total Supply:
51,593,712.261088 KNIGHT

Holders:
2,657 addresses
 
Balance
1,632,761.679598512307564174 KNIGHT

Value
$19,043.69 ( ~17,265.3581 MATIC) [3.1647%]
0x7f7c12acec546cdceb028cc5b57f7aa2d91f0887
Loading
[ Download CSV Export  ] 
Loading
[ Download CSV Export  ] 
Loading

OVERVIEW

Forest Knight is a Play-to-Earn mobile game powered by Ethereum & Polygon Layer 2.

Market

Volume (24H):$86,006.05
Market Capitalization:$90,284.94
Circulating Supply:7,740,823.00 KNIGHT
Market Data Source: Coinmarketcap


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

Contract Source Code Verified (Exact Match)

Contract Name:
ForestKnightChild

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 2000 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 12 of 15: KnightChild.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./AccessControl.sol";
import "./Ownable.sol";

import "./ERC20Fallback.sol";
import "./ERC20Capped.sol";

contract ForestKnightChild is AccessControl, ERC20Capped, ERC20Fallback, Ownable {
    uint8 immutable private _decimals;
    bytes32 public constant DEPOSITOR_ROLE = keccak256("DEPOSITOR_ROLE");

    //address private _childChainManagerProxy = 0xb5505a6d998549090530911180f38aC5130101c6; //mumbai
    address private _childChainManagerProxy = 0xA6FA4fB5f76172d178d61B04b0ecd319C5d1C0aa; //matic mainnet

    constructor (
        string memory name_,
        string memory symbol_,
        uint8 decimals_,
        address initialAccount,
        uint256 initialBalance,
        uint256 supplyCap
    ) 
        ERC20(name_, symbol_) 
        ERC20Capped(supplyCap * (uint256(10) ** decimals_))
        ERC20Fallback()
    {
        require(initialAccount != address(0), "ForestKnight: initialAccount is a zero address");
        _decimals = decimals_;
        uint256 newSupply = initialBalance * (uint256(10) ** decimals_);
        _mint(initialAccount, newSupply);
        _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
        _setupRole(DEPOSITOR_ROLE, childChainManagerProxy());
    }

    /**
    * @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 {decimals} is
    * set in constructor.
    *
    * 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 _decimals;
    }

    //-------------------------------------------------------------------------------------------
    //Matic Child Functions 
    //-------------------------------------------------------------------------------------------

    /**
     * @notice called when token is deposited on root chain
     * @dev Should be callable only by ChildChainManager
     * Should handle deposit by minting the required amount for user
     * Make sure minting is done only by this function
     * @param user user address for whom deposit is being done
     * @param depositData abi encoded amount
     */

    function deposit(address user, bytes calldata depositData)
        external
        onlyRole(DEPOSITOR_ROLE)
    {
        uint256 amount = abi.decode(depositData, (uint256));
        _mint(user, amount);
    }

    /**
     * @notice called when user wants to withdraw tokens back to root chain
     * @dev Should burn user"s tokens. This transaction will be verified when exiting on root chain
     * @param amount amount of tokens to withdraw
     */
    function withdraw(uint256 amount) external {
        _burn(_msgSender(), amount);
    }

    /**
     * @notice Example function to handle minting tokens on matic chain
     * @dev Minting can be done as per requirement,
     * This implementation allows only admin to mint tokens but it can be changed as per requirement
     * @param user user for whom tokens are being minted
     * @param amount amount of token to mint
     */
    function mint(address user, uint256 amount) public onlyRole(DEPOSITOR_ROLE) {
        _mint(user, amount);
    }

    function childChainManagerProxy() public view returns(address) {
        return _childChainManagerProxy;
    }

    /**
    * @dev Validation of an fallback redeem. Use require statements to revert state when conditions are not met.
    * Use `super` in contracts that inherit from TokenEscrow to extend their validations.
    * Example from TokenEscrow.sol"s _prevalidateFallbackRedeem method:
    *     super._prevalidateFallbackRedeem(token, payee, amount);
    *    
    * @param token_ The token address of IERC20 token
    * @param to_ Address performing the token deposit
    * @param amount_ Number of tokens deposit
    *
    * Requirements:
    *
    * - `msg.sender` must be owner.
    * - `token` cannot be the zero address.
    * - `to` cannot be the zero address.
    * - this address must have a token balance of at least `amount`.
    * - must be admin
    */
    function _prevalidateFallbackRedeem(IERC20 token_,  address to_, uint256 amount_) 
        internal 
        virtual
        override
        view
        onlyRole(DEFAULT_ADMIN_ROLE) 
    {
      super._prevalidateFallbackRedeem(token_, to_, amount_);
    }
}

File 1 of 15: AccessControl.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v4.3.1/contracts/access/AccessControl.sol

import "./IAccessControl.sol";
import "./Context.sol";
import "./Strings.sol";
import "./ERC165.sol";

/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role, _msgSender());
        _;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     */
    function _checkRole(bytes32 role, address account) internal view {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(uint160(account), 20),
                        " is missing role ",
                        Strings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    function _grantRole(bytes32 role, address account) private {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    function _revokeRole(bytes32 role, address account) private {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}

File 2 of 15: Address.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v4.3.1/contracts/utils/Address.sol

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 3 of 15: Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v4.3.1/contracts/utils/Context.sol

/**
 * @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;
    }
}

File 4 of 15: ERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v4.3.1/contracts/utils/introspection/ERC165.sol

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

File 5 of 15: ERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v4.3.1/contracts/token/ERC20/ERC20.sol

import "./IERC20.sol";
import "./IERC20Metadata.sol";
import "./Context.sol";

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

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

        return true;
    }

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

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

        return true;
    }

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

        _beforeTokenTransfer(sender, recipient, amount);

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

        emit Transfer(sender, recipient, amount);

        _afterTokenTransfer(sender, recipient, amount);
    }

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

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

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

        _afterTokenTransfer(address(0), account, amount);
    }

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

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

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

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

        _afterTokenTransfer(account, address(0), amount);
    }

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

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

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

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

File 6 of 15: ERC20Capped.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;


import "./ERC20.sol";

/**
 * @dev Extension of {ERC20} that adds a cap to the supply of tokens.
 */
abstract contract ERC20Capped is ERC20 {
    uint256 private _cap;

    /**
     * @dev Sets the value of the `cap`. This value is immutable, it can only be
     * set once during construction.
     */
    constructor (uint256 cap_) {
        require(cap_ > 0, "ERC20Capped: cap is 0");
        _cap = cap_;
    }

    /**
     * @dev Returns the cap on the token's total supply.
     */
    function cap() public view virtual returns (uint256) {
        return _cap;
    }

    /**
     * @dev See {ERC20-_mint}.
     */
    function _mint(address account, uint256 amount) internal virtual override {
        require(ERC20.totalSupply() + amount <= cap(), "ERC20Capped: cap exceeded");
        super._mint(account, amount);
    }
}

File 7 of 15: ERC20Fallback.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./Address.sol";
import "./SafeERC20.sol";

abstract contract ERC20Fallback {
    using Address for address;
    using SafeERC20 for IERC20;

    event TokenWithdrawn(IERC20 token, address indexed to, uint256 value);

    /**
    * @dev Faalback Redeem tokens. The ability to redeem token whe okenst are accidentally sent to the contract
    * @param token_ Address of the IERC20 token
    * @param to_ address Recipient of the recovered tokens
    * @param amount_ Number of tokens to be emitted
    */
    function fallbackRedeem(IERC20 token_,  address to_, uint256 amount_) external {
      _prevalidateFallbackRedeem(token_, to_, amount_);

      _processFallbackRedeem(token_, to_, amount_);
      emit TokenWithdrawn(token_, to_, amount_);

      _updateFallbackRedeem(token_, to_, amount_);
      _postValidateFallbackRedeem(token_, to_, amount_);
    }

    /**
    * @dev Validation of an fallback redeem. Use require statements to revert state when conditions are not met.
    * Use `super` in contracts that inherit from TokenEscrow to extend their validations.
    * Example from TokenEscrow.sol's _prevalidateFallbackRedeem method:
    *     super._prevalidateFallbackRedeem(token, payee, amount);
    *    
    * @param token_ The token address of IERC20 token
    * @param to_ Address performing the token deposit
    * @param amount_ Number of tokens deposit
    *
    * Requirements:
    *
    * - `msg.sender` must be owner.
    * - `token` cannot be the zero address.
    * - `to` cannot be the zero address.
    * - this address must have a token balance of at least `amount`.
    */
    function _prevalidateFallbackRedeem(IERC20 token_,  address to_, uint256 amount_) internal virtual view {
      require(address(token_) != address(0), "ERC20Fallback: token is the zero address");
      require(to_ != address(0), "ERC20Fallback: cannot recover to zero address");
      require(amount_ != 0, "ERC20Fallback: amount is 0");
      
      uint256 amount = token_.balanceOf(address(this));
      require(amount >= amount_, "ERC20Fallback: no token to release");
      this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
    }

    /**
    * @dev Executed when fallbackRedeem has been validated and is ready to be executed. Doesn't necessarily emit/send
    * tokens.
    * @param token_ The token address of IERC20 token
    * @param to_ Address where the token sent to
    * @param amount_ Number of tokens deposit
    */
    function _processFallbackRedeem(IERC20 token_,address to_, uint256 amount_) internal virtual {
      _deliverTokens(token_, to_, amount_);
    }

    /**
    * @dev Override for extensions that require an internal state to check for validity fallback redeem,
    * etc.)
    * @param token_ The token address of IERC20 token
    * @param to_ Address where the token sent to
    * @param amount_ Number of tokens deposit
    */
    function _updateFallbackRedeem(IERC20 token_, address to_, uint256 amount_) internal virtual {
      // solhint-disable-previous-line no-empty-blocks
    }

    /**
    * @dev Validation of an executed fallback redeem. Observe state and use revert statements to undo rollback when valid
    * conditions are not met.
    * @param token_ The token address of IERC20 token
    * @param to_ Address where the token sent to
    * @param amount_ Number of tokens deposit
    */
    function _postValidateFallbackRedeem(IERC20 token_, address to_, uint256 amount_) internal virtual view {
      // solhint-disable-previous-line no-empty-blocks
    }

    /**
     * @dev Source of tokens. Override this method to modify the way in which the tokenescrow ultimately gets and sends
     * its tokens.
     * @param token_ The token address of IERC20 token
     * @param to_ Address where the token sent to
     * @param amount_ Number of tokens to be emitted
     */
    function _deliverTokens(IERC20 token_, address to_, uint256 amount_) internal virtual returns (bool) {
      token_.safeTransfer(to_, amount_);
      return true;
    }
}

File 8 of 15: IAccessControl.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v4.3.1/contracts/access/IAccessControl.sol


/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}

File 9 of 15: IERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v4.3.1/contracts/utils/introspection/IERC165.sol

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 10 of 15: IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v4.3.1/contracts/token/ERC20/IERC20.sol

/**
 * @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);
}

File 11 of 15: IERC20Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v4.3.1/contracts/token/ERC20/extensions/IERC20Metadata.sol

import "./IERC20.sol";

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

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

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

File 13 of 15: Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v4.3.1/contracts/access/Ownable.sol

import "./Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _setOwner(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

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

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 14 of 15: SafeERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC20.sol";
import "./Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        // solhint-disable-next-line max-line-length
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

File 15 of 15: Strings.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v4.3.1/contracts/utils/Strings.sol

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"uint8","name":"decimals_","type":"uint8"},{"internalType":"address","name":"initialAccount","type":"address"},{"internalType":"uint256","name":"initialBalance","type":"uint256"},{"internalType":"uint256","name":"supplyCap","type":"uint256"}],"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":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TokenWithdrawn","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":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPOSITOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"childChainManagerProxy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bytes","name":"depositData","type":"bytes"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"fallbackRedeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","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":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a0604052600880546001600160a01b03191673a6fa4fb5f76172d178d61b04b0ecd319c5d1c0aa1790553480156200003757600080fd5b5060405162002753380380620027538339810160408190526200005a9162000608565b6200006784600a6200071f565b620000739082620007eb565b8651879087906200008c906004906020850190620004af565b508051620000a2906005906020840190620004af565b50505060008111620000fb5760405162461bcd60e51b815260206004820152601560248201527f45524332304361707065643a206361702069732030000000000000000000000060448201526064015b60405180910390fd5b600655620001093362000223565b6001600160a01b038316620001785760405162461bcd60e51b815260206004820152602e60248201527f466f726573744b6e696768743a20696e697469616c4163636f756e742069732060448201526d61207a65726f206164647265737360901b6064820152608401620000f2565b7fff0000000000000000000000000000000000000000000000000000000000000060f885901b166080526000620001b185600a6200071f565b620001bd9084620007eb565b9050620001cb848262000275565b620001de60003362000305565b62000305565b620002167f8f4f2da22e8ac8f11e15f9fc141cddbb5deea8800186560abb6e68c5496619a9620001d86008546001600160a01b031690565b5050505050505062000876565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600654816200028e6200031160201b620005bc1760201c565b6200029a9190620006bb565b1115620002ea5760405162461bcd60e51b815260206004820152601960248201527f45524332304361707065643a20636170206578636565646564000000000000006044820152606401620000f2565b6200030182826200031760201b62000aa21760201c565b5050565b620003018282620003fc565b60035490565b6001600160a01b0382166200036f5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401620000f2565b8060036000828254620003839190620006bb565b90915550506001600160a01b03821660009081526001602052604081208054839290620003b2908490620006bb565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b62000408828262000484565b62000301576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620004403390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff165b92915050565b828054620004bd906200080d565b90600052602060002090601f016020900481019282620004e157600085556200052c565b82601f10620004fc57805160ff19168380011785556200052c565b828001600101855582156200052c579182015b828111156200052c5782518255916020019190600101906200050f565b506200053a9291506200053e565b5090565b5b808211156200053a57600081556001016200053f565b600082601f83011262000566578081fd5b81516001600160401b038082111562000583576200058362000860565b604051601f8301601f19908116603f01168101908282118183101715620005ae57620005ae62000860565b81604052838152602092508683858801011115620005ca578485fd5b8491505b83821015620005ed5785820183015181830184015290820190620005ce565b83821115620005fe57848385830101525b9695505050505050565b60008060008060008060c0878903121562000621578182fd5b86516001600160401b038082111562000638578384fd5b620006468a838b0162000555565b975060208901519150808211156200065c578384fd5b506200066b89828a0162000555565b955050604087015160ff8116811462000682578283fd5b60608801519094506001600160a01b03811681146200069f578283fd5b809350506080870151915060a087015190509295509295509295565b60008219821115620006d157620006d16200084a565b500190565b600181815b8085111562000717578160001904821115620006fb57620006fb6200084a565b808516156200070957918102915b93841c9390800290620006db565b509250929050565b60006200073060ff84168362000737565b9392505050565b6000826200074857506001620004a9565b816200075757506000620004a9565b81600181146200077057600281146200077b576200079b565b6001915050620004a9565b60ff8411156200078f576200078f6200084a565b50506001821b620004a9565b5060208310610133831016604e8410600b8410161715620007c0575081810a620004a9565b620007cc8383620006d6565b8060001904821115620007e357620007e36200084a565b029392505050565b60008160001904831182151516156200080857620008086200084a565b500290565b600181811c908216806200082257607f821691505b602082108114156200084457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60805160f81c611ebe6200089560003960006102900152611ebe6000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c806362f629e7116100f9578063a3b0b5a311610097578063cf2c52cb11610071578063cf2c52cb14610409578063d547741f1461041c578063dd62ed3e1461042f578063f2fde38b1461046857600080fd5b8063a3b0b5a3146103bc578063a457c2d7146103e3578063a9059cbb146103f657600080fd5b80638da5cb5b116100d35780638da5cb5b1461036457806391d148541461037557806395d89b41146103ac578063a217fddf146103b457600080fd5b806362f629e71461030e57806370a0823114610333578063715018a61461035c57600080fd5b80632f2ff15d1161016657806336568abe1161014057806336568abe146102c257806339509351146102d557806340c10f19146102e857806359e39c36146102fb57600080fd5b80632f2ff15d14610276578063313ce56714610289578063355274ea146102ba57600080fd5b806318160ddd116101a257806318160ddd1461021957806323b872dd1461022b578063248a9ca31461023e5780632e1a7d4d1461026157600080fd5b806301ffc9a7146101c957806306fdde03146101f1578063095ea7b314610206575b600080fd5b6101dc6101d7366004611c55565b61047b565b60405190151581526020015b60405180910390f35b6101f9610514565b6040516101e89190611d5e565b6101dc610214366004611bce565b6105a6565b6003545b6040519081526020016101e8565b6101dc610239366004611b0e565b6105c2565b61021d61024c366004611c19565b60009081526020819052604090206001015490565b61027461026f366004611c19565b610688565b005b610274610284366004611c31565b610695565b60405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101e8565b60065461021d565b6102746102d0366004611c31565b6106c0565b6101dc6102e3366004611bce565b61074c565b6102746102f6366004611bce565b610788565b610274610309366004611c95565b6107bd565b6008546001600160a01b03165b6040516001600160a01b0390911681526020016101e8565b61021d610341366004611aba565b6001600160a01b031660009081526001602052604090205490565b61027461081e565b6007546001600160a01b031661031b565b6101dc610383366004611c31565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b6101f9610884565b61021d600081565b61021d7f8f4f2da22e8ac8f11e15f9fc141cddbb5deea8800186560abb6e68c5496619a981565b6101dc6103f1366004611bce565b610893565b6101dc610404366004611bce565b610944565b610274610417366004611b4e565b610951565b61027461042a366004611c31565b61099d565b61021d61043d366004611ad6565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b610274610476366004611aba565b6109c3565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061050e57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60606004805461052390611e22565b80601f016020809104026020016040519081016040528092919081815260200182805461054f90611e22565b801561059c5780601f106105715761010080835404028352916020019161059c565b820191906000526020600020905b81548152906001019060200180831161057f57829003601f168201915b5050505050905090565b60006105b3338484610b81565b50600192915050565b60035490565b60006105cf848484610cd9565b6001600160a01b03841660009081526002602090815260408083203384529091529020548281101561066e5760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61067b8533858403610b81565b60019150505b9392505050565b6106923382610ef2565b50565b6000828152602081905260409020600101546106b18133611077565b6106bb83836110f5565b505050565b6001600160a01b038116331461073e5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610665565b6107488282611193565b5050565b3360008181526002602090815260408083206001600160a01b038716845290915281205490916105b3918590610783908690611d91565b610b81565b7f8f4f2da22e8ac8f11e15f9fc141cddbb5deea8800186560abb6e68c5496619a96107b38133611077565b6106bb8383611212565b6107c8838383611281565b6107d3838383611298565b604080516001600160a01b038581168252602082018490528416917f8210728e7c071f615b840ee026032693858fbcd5e5359e67e438c890f59e5620910160405180910390a2505050565b6007546001600160a01b031633146108785760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610665565b61088260006112a3565b565b60606005805461052390611e22565b3360009081526002602090815260408083206001600160a01b03861684529091528120548281101561092d5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610665565b61093a3385858403610b81565b5060019392505050565b60006105b3338484610cd9565b7f8f4f2da22e8ac8f11e15f9fc141cddbb5deea8800186560abb6e68c5496619a961097c8133611077565b600061098a83850185611c19565b90506109968582611212565b5050505050565b6000828152602081905260409020600101546109b98133611077565b6106bb8383611193565b6007546001600160a01b03163314610a1d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610665565b6001600160a01b038116610a995760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610665565b610692816112a3565b6001600160a01b038216610af85760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610665565b8060036000828254610b0a9190611d91565b90915550506001600160a01b03821660009081526001602052604081208054839290610b37908490611d91565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b038316610bfc5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610665565b6001600160a01b038216610c785760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610665565b6001600160a01b0383811660008181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b038316610d555760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610665565b6001600160a01b038216610dd15760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610665565b6001600160a01b03831660009081526001602052604090205481811015610e605760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610665565b6001600160a01b03808516600090815260016020526040808220858503905591851681529081208054849290610e97908490611d91565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610ee391815260200190565b60405180910390a35b50505050565b6001600160a01b038216610f6e5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610665565b6001600160a01b03821660009081526001602052604090205481811015610ffd5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610665565b6001600160a01b038316600090815260016020526040812083830390556003805484929061102c908490611dc8565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610748576110b3816001600160a01b0316601461130d565b6110be83602061130d565b6040516020016110cf929190611cdd565b60408051601f198184030181529082905262461bcd60e51b825261066591600401611d5e565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610748576000828152602081815260408083206001600160a01b03851684529091529020805460ff1916600117905561114f3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1615610748576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6006548161121f60035490565b6112299190611d91565b11156112775760405162461bcd60e51b815260206004820152601960248201527f45524332304361707065643a20636170206578636565646564000000000000006044820152606401610665565b6107488282610aa2565b600061128d8133611077565b610eec84848461157c565b610eec8383836117cc565b600780546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6060600061131c836002611da9565b611327906002611d91565b67ffffffffffffffff81111561134d57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611377576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106113bc57634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061142d57634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000611469846002611da9565b611474906001611d91565b90505b600181111561152d577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106114c357634e487b7160e01b600052603260045260246000fd5b1a60f81b8282815181106114e757634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c9361152681611e0b565b9050611477565b5083156106815760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610665565b6001600160a01b0383166115f85760405162461bcd60e51b815260206004820152602860248201527f455243323046616c6c6261636b3a20746f6b656e20697320746865207a65726f60448201527f20616464726573730000000000000000000000000000000000000000000000006064820152608401610665565b6001600160a01b0382166116745760405162461bcd60e51b815260206004820152602d60248201527f455243323046616c6c6261636b3a2063616e6e6f74207265636f76657220746f60448201527f207a65726f2061646472657373000000000000000000000000000000000000006064820152608401610665565b806116c15760405162461bcd60e51b815260206004820152601a60248201527f455243323046616c6c6261636b3a20616d6f756e7420697320300000000000006044820152606401610665565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000906001600160a01b038516906370a082319060240160206040518083038186803b15801561171c57600080fd5b505afa158015611730573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117549190611ca9565b905081811015610eec5760405162461bcd60e51b815260206004820152602260248201527f455243323046616c6c6261636b3a206e6f20746f6b656e20746f2072656c656160448201527f73650000000000000000000000000000000000000000000000000000000000006064820152608401610665565b600061093a6001600160a01b0385168484604080516001600160a01b03848116602483015260448083018590528351808403909101815260649092018352602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905283518085019094528084527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908401526106bb9286929160009161189b91851690849061192b565b8051909150156106bb57808060200190518101906118b99190611bf9565b6106bb5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610665565b606061193a8484600085611942565b949350505050565b6060824710156119ba5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610665565b843b611a085760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610665565b600080866001600160a01b03168587604051611a249190611cc1565b60006040518083038185875af1925050503d8060008114611a61576040519150601f19603f3d011682016040523d82523d6000602084013e611a66565b606091505b5091509150611a76828286611a81565b979650505050505050565b60608315611a90575081610681565b825115611aa05782518084602001fd5b8160405162461bcd60e51b81526004016106659190611d5e565b600060208284031215611acb578081fd5b813561068181611e73565b60008060408385031215611ae8578081fd5b8235611af381611e73565b91506020830135611b0381611e73565b809150509250929050565b600080600060608486031215611b22578081fd5b8335611b2d81611e73565b92506020840135611b3d81611e73565b929592945050506040919091013590565b600080600060408486031215611b62578283fd5b8335611b6d81611e73565b9250602084013567ffffffffffffffff80821115611b89578384fd5b818601915086601f830112611b9c578384fd5b813581811115611baa578485fd5b876020828501011115611bbb578485fd5b6020830194508093505050509250925092565b60008060408385031215611be0578182fd5b8235611beb81611e73565b946020939093013593505050565b600060208284031215611c0a578081fd5b81518015158114610681578182fd5b600060208284031215611c2a578081fd5b5035919050565b60008060408385031215611c43578182fd5b823591506020830135611b0381611e73565b600060208284031215611c66578081fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610681578182fd5b600080600060608486031215611b22578283fd5b600060208284031215611cba578081fd5b5051919050565b60008251611cd3818460208701611ddf565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611d15816017850160208801611ddf565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351611d52816028840160208801611ddf565b01602801949350505050565b6020815260008251806020840152611d7d816040850160208701611ddf565b601f01601f19169190910160400192915050565b60008219821115611da457611da4611e5d565b500190565b6000816000190483118215151615611dc357611dc3611e5d565b500290565b600082821015611dda57611dda611e5d565b500390565b60005b83811015611dfa578181015183820152602001611de2565b83811115610eec5750506000910152565b600081611e1a57611e1a611e5d565b506000190190565b600181811c90821680611e3657607f821691505b60208210811415611e5757634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b038116811461069257600080fdfea2646970667358221220fe0237223123cdfdc32fbea6ef4b44c4e3d33188e9e78c0be2d4e0548d25caf564736f6c6343000804003300000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000955613eb1ecd42b0f92e0c26602a9d1dfd1f717a0000000000000000000000000000000000000000000000000000000002faf0800000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000000000000000000d466f72657374204b6e696768740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064b4e494748540000000000000000000000000000000000000000000000000000

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000955613eb1ecd42b0f92e0c26602a9d1dfd1f717a0000000000000000000000000000000000000000000000000000000002faf0800000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000000000000000000d466f72657374204b6e696768740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064b4e494748540000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : name_ (string): Forest Knight
Arg [1] : symbol_ (string): KNIGHT
Arg [2] : decimals_ (uint8): 18
Arg [3] : initialAccount (address): 0x955613eb1ecd42b0f92e0c26602a9d1dfd1f717a
Arg [4] : initialBalance (uint256): 50000000
Arg [5] : supplyCap (uint256): 100000000

-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000012
Arg [3] : 000000000000000000000000955613eb1ecd42b0f92e0c26602a9d1dfd1f717a
Arg [4] : 0000000000000000000000000000000000000000000000000000000002faf080
Arg [5] : 0000000000000000000000000000000000000000000000000000000005f5e100
Arg [6] : 000000000000000000000000000000000000000000000000000000000000000d
Arg [7] : 466f72657374204b6e6967687400000000000000000000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [9] : 4b4e494748540000000000000000000000000000000000000000000000000000


Deployed ByteCode Sourcemap

172:4555:11:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2625:202:0;;;;;;:::i;:::-;;:::i;:::-;;;6093:14:15;;6086:22;6068:41;;6056:2;6041:18;2625:202:0;;;;;;;;2175:98:4;;;:::i;:::-;;;;;;;:::i;4272:166::-;;;;;;:::i;:::-;;:::i;3263:106::-;3350:12;;3263:106;;;6266:25:15;;;6254:2;6239:18;3263:106:4;6221:76:15;4905:478:4;;;;;;:::i;:::-;;:::i;3997:121:0:-;;;;;;:::i;:::-;4063:7;4089:12;;;;;;;;;;:22;;;;3997:121;3033:87:11;;;;;;:::i;:::-;;:::i;:::-;;4368:145:0;;;;;;:::i;:::-;;:::i;1879:98:11:-;;;16081:4:15;1961:9:11;16069:17:15;16051:36;;16039:2;16024:18;1879:98:11;16006:87:15;552:81:5;622:4;;552:81;;5385:214:0;;;;;;:::i;:::-;;:::i;5778:212:4:-;;;;;;:::i;:::-;;:::i;3469:112:11:-;;;;;;:::i;:::-;;:::i;573:353:6:-;;;;;;:::i;:::-;;:::i;3587:110:11:-;3667:23;;-1:-1:-1;;;;;3667:23:11;3587:110;;;-1:-1:-1;;;;;5559:55:15;;;5541:74;;5529:2;5514:18;3587:110:11;5496:125:15;3427::4;;;;;;:::i;:::-;-1:-1:-1;;;;;3527:18:4;3501:7;3527:18;;;:9;:18;;;;;;;3427:125;1707:92:12;;;:::i;1075:85::-;1147:6;;-1:-1:-1;;;;;1147:6:12;1075:85;;2914:137:0;;;;;;:::i;:::-;2992:4;3015:12;;;;;;;;;;;-1:-1:-1;;;;;3015:29:0;;;;;;;;;;;;;;;2914:137;2386:102:4;;;:::i;2032:49:0:-;;2077:4;2032:49;;298:68:11;;339:27;298:68;;6477:405:4;;;;;;:::i;:::-;;:::i;3755:172::-;;;;;;:::i;:::-;;:::i;2575:210:11:-;;;;;;:::i;:::-;;:::i;4747:147:0:-;;;;;;:::i;:::-;;:::i;3985:149:4:-;;;;;;:::i;:::-;-1:-1:-1;;;;;4100:18:4;;;4074:7;4100:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;3985:149;1948:189:12;;;;;;:::i;:::-;;:::i;2625:202:0:-;2710:4;2733:47;;;2748:32;2733:47;;:87;;-1:-1:-1;1007:25:3;992:40;;;;2784:36:0;2726:94;2625:202;-1:-1:-1;;2625:202:0:o;2175:98:4:-;2229:13;2261:5;2254:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2175:98;:::o;4272:166::-;4355:4;4371:39;774:10:2;4394:7:4;4403:6;4371:8;:39::i;:::-;-1:-1:-1;4427:4:4;4272:166;;;;:::o;3263:106::-;3350:12;;;3263:106::o;4905:478::-;5041:4;5057:36;5067:6;5075:9;5086:6;5057:9;:36::i;:::-;-1:-1:-1;;;;;5131:19:4;;5104:24;5131:19;;;:11;:19;;;;;;;;774:10:2;5131:33:4;;;;;;;;5182:26;;;;5174:79;;;;-1:-1:-1;;;5174:79:4;;10829:2:15;5174:79:4;;;10811:21:15;10868:2;10848:18;;;10841:30;10907:34;10887:18;;;10880:62;10978:10;10958:18;;;10951:38;11006:19;;5174:79:4;;;;;;;;;5287:57;5296:6;774:10:2;5337:6:4;5318:16;:25;5287:8;:57::i;:::-;5372:4;5365:11;;;4905:478;;;;;;:::o;3033:87:11:-;3086:27;774:10:2;3106:6:11;3086:5;:27::i;:::-;3033:87;:::o;4368:145:0:-;4063:7;4089:12;;;;;;;;;;:22;;;2510:30;2521:4;774:10:2;2510::0;:30::i;:::-;4481:25:::1;4492:4;4498:7;4481:10;:25::i;:::-;4368:145:::0;;;:::o;5385:214::-;-1:-1:-1;;;;;5480:23:0;;774:10:2;5480:23:0;5472:83;;;;-1:-1:-1;;;5472:83:0;;15153:2:15;5472:83:0;;;15135:21:15;15192:2;15172:18;;;15165:30;15231:34;15211:18;;;15204:62;15302:17;15282:18;;;15275:45;15337:19;;5472:83:0;15125:237:15;5472:83:0;5566:26;5578:4;5584:7;5566:11;:26::i;:::-;5385:214;;:::o;5778:212:4:-;774:10:2;5866:4:4;5914:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;5914:34:4;;;;;;;;;;5866:4;;5882:80;;5905:7;;5914:47;;5951:10;;5914:47;:::i;:::-;5882:8;:80::i;3469:112:11:-;339:27;2510:30:0;339:27:11;774:10:2;2510::0;:30::i;:::-;3555:19:11::1;3561:4;3567:6;3555:5;:19::i;573:353:6:-:0;660:48;687:6;695:3;700:7;660:26;:48::i;:::-;717:44;740:6;748:3;753:7;717:22;:44::i;:::-;774:36;;;-1:-1:-1;;;;;5818:55:15;;;5800:74;;5905:2;5890:18;;5883:34;;;774:36:6;;;;;5773:18:15;774:36:6;;;;;;;4368:145:0;;;:::o;1707:92:12:-;1147:6;;-1:-1:-1;;;;;1147:6:12;774:10:2;1287:23:12;1279:68;;;;-1:-1:-1;;;1279:68:12;;11238:2:15;1279:68:12;;;11220:21:15;;;11257:18;;;11250:30;11316:34;11296:18;;;11289:62;11368:18;;1279:68:12;11210:182:15;1279:68:12;1771:21:::1;1789:1;1771:9;:21::i;:::-;1707:92::o:0;2386:102:4:-;2442:13;2474:7;2467:14;;;;;:::i;6477:405::-;774:10:2;6570:4:4;6613:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;6613:34:4;;;;;;;;;;6665:35;;;;6657:85;;;;-1:-1:-1;;;6657:85:4;;14747:2:15;6657:85:4;;;14729:21:15;14786:2;14766:18;;;14759:30;14825:34;14805:18;;;14798:62;14896:7;14876:18;;;14869:35;14921:19;;6657:85:4;14719:227:15;6657:85:4;6776:67;774:10:2;6799:7:4;6827:15;6808:16;:34;6776:8;:67::i;:::-;-1:-1:-1;6871:4:4;;6477:405;-1:-1:-1;;;6477:405:4:o;3755:172::-;3841:4;3857:42;774:10:2;3881:9:4;3892:6;3857:9;:42::i;2575:210:11:-;339:27;2510:30:0;339:27:11;774:10:2;2510::0;:30::i;:::-;2698:14:11::1;2715:34;::::0;;::::1;2726:11:::0;2715:34:::1;:::i;:::-;2698:51;;2759:19;2765:4;2771:6;2759:5;:19::i;:::-;2550:1:0;2575:210:11::0;;;;:::o;4747:147:0:-;4063:7;4089:12;;;;;;;;;;:22;;;2510:30;2521:4;774:10:2;2510::0;:30::i;:::-;4861:26:::1;4873:4;4879:7;4861:11;:26::i;1948:189:12:-:0;1147:6;;-1:-1:-1;;;;;1147:6:12;774:10:2;1287:23:12;1279:68;;;;-1:-1:-1;;;1279:68:12;;11238:2:15;1279:68:12;;;11220:21:15;;;11257:18;;;11250:30;11316:34;11296:18;;;11289:62;11368:18;;1279:68:12;11210:182:15;1279:68:12;-1:-1:-1;;;;;2036:22:12;::::1;2028:73;;;::::0;-1:-1:-1;;;2028:73:12;;8436:2:15;2028:73:12::1;::::0;::::1;8418:21:15::0;8475:2;8455:18;;;8448:30;8514:34;8494:18;;;8487:62;8585:8;8565:18;;;8558:36;8611:19;;2028:73:12::1;8408:228:15::0;2028:73:12::1;2111:19;2121:8;2111:9;:19::i;8345:389:4:-:0;-1:-1:-1;;;;;8428:21:4;;8420:65;;;;-1:-1:-1;;;8420:65:4;;15569:2:15;8420:65:4;;;15551:21:15;15608:2;15588:18;;;15581:30;15647:33;15627:18;;;15620:61;15698:18;;8420:65:4;15541:181:15;8420:65:4;8572:6;8556:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;8588:18:4;;;;;;:9;:18;;;;;:28;;8610:6;;8588:18;:28;;8610:6;;8588:28;:::i;:::-;;;;-1:-1:-1;;8631:37:4;;6266:25:15;;;-1:-1:-1;;;;;8631:37:4;;;8648:1;;8631:37;;6254:2:15;6239:18;8631:37:4;;;;;;;5385:214:0;;:::o;10053:370:4:-;-1:-1:-1;;;;;10184:19:4;;10176:68;;;;-1:-1:-1;;;10176:68:4;;13170:2:15;10176:68:4;;;13152:21:15;13209:2;13189:18;;;13182:30;13248:34;13228:18;;;13221:62;13319:6;13299:18;;;13292:34;13343:19;;10176:68:4;13142:226:15;10176:68:4;-1:-1:-1;;;;;10262:21:4;;10254:68;;;;-1:-1:-1;;;10254:68:4;;8843:2:15;10254:68:4;;;8825:21:15;8882:2;8862:18;;;8855:30;8921:34;8901:18;;;8894:62;8992:4;8972:18;;;8965:32;9014:19;;10254:68:4;8815:224:15;10254:68:4;-1:-1:-1;;;;;10333:18:4;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;10384:32;;6266:25:15;;;10384:32:4;;6239:18:15;10384:32:4;;;;;;;10053:370;;;:::o;7356:713::-;-1:-1:-1;;;;;7491:20:4;;7483:70;;;;-1:-1:-1;;;7483:70:4;;12410:2:15;7483:70:4;;;12392:21:15;12449:2;12429:18;;;12422:30;12488:34;12468:18;;;12461:62;12559:7;12539:18;;;12532:35;12584:19;;7483:70:4;12382:227:15;7483:70:4;-1:-1:-1;;;;;7571:23:4;;7563:71;;;;-1:-1:-1;;;7563:71:4;;7629:2:15;7563:71:4;;;7611:21:15;7668:2;7648:18;;;7641:30;7707:34;7687:18;;;7680:62;7778:5;7758:18;;;7751:33;7801:19;;7563:71:4;7601:225:15;7563:71:4;-1:-1:-1;;;;;7727:17:4;;7703:21;7727:17;;;:9;:17;;;;;;7762:23;;;;7754:74;;;;-1:-1:-1;;;7754:74:4;;9246:2:15;7754:74:4;;;9228:21:15;9285:2;9265:18;;;9258:30;9324:34;9304:18;;;9297:62;9395:8;9375:18;;;9368:36;9421:19;;7754:74:4;9218:228:15;7754:74:4;-1:-1:-1;;;;;7862:17:4;;;;;;;:9;:17;;;;;;7882:22;;;7862:42;;7924:20;;;;;;;;:30;;7898:6;;7862:17;7924:30;;7898:6;;7924:30;:::i;:::-;;;;;;;;7987:9;-1:-1:-1;;;;;7970:35:4;7979:6;-1:-1:-1;;;;;7970:35:4;;7998:6;7970:35;;;;6266:25:15;;6254:2;6239:18;;6221:76;7970:35:4;;;;;;;;8016:46;7356:713;;;;:::o;9054:576::-;-1:-1:-1;;;;;9137:21:4;;9129:67;;;;-1:-1:-1;;;9129:67:4;;11599:2:15;9129:67:4;;;11581:21:15;11638:2;11618:18;;;11611:30;11677:34;11657:18;;;11650:62;11748:3;11728:18;;;11721:31;11769:19;;9129:67:4;11571:223:15;9129:67:4;-1:-1:-1;;;;;9292:18:4;;9267:22;9292:18;;;:9;:18;;;;;;9328:24;;;;9320:71;;;;-1:-1:-1;;;9320:71:4;;8033:2:15;9320:71:4;;;8015:21:15;8072:2;8052:18;;;8045:30;8111:34;8091:18;;;8084:62;8182:4;8162:18;;;8155:32;8204:19;;9320:71:4;8005:224:15;9320:71:4;-1:-1:-1;;;;;9425:18:4;;;;;;:9;:18;;;;;9446:23;;;9425:44;;9489:12;:22;;9463:6;;9425:18;9489:22;;9463:6;;9489:22;:::i;:::-;;;;-1:-1:-1;;9527:37:4;;6266:25:15;;;9553:1:4;;-1:-1:-1;;;;;9527:37:4;;;;;6254:2:15;6239:18;9527:37:4;;;;;;;4368:145:0;;;:::o;3332:484::-;2992:4;3015:12;;;;;;;;;;;-1:-1:-1;;;;;3015:29:0;;;;;;;;;;;;3407:403;;3595:41;3623:7;-1:-1:-1;;;;;3595:41:0;3633:2;3595:19;:41::i;:::-;3707:38;3735:4;3742:2;3707:19;:38::i;:::-;3502:265;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;3502:265:0;;;;;;;;;;-1:-1:-1;;;3450:349:0;;;;;;;:::i;6652:224::-;2992:4;3015:12;;;;;;;;;;;-1:-1:-1;;;;;3015:29:0;;;;;;;;;;;;6721:149;;6764:6;:12;;;;;;;;;;;-1:-1:-1;;;;;6764:29:0;;;;;;;;;:36;;-1:-1:-1;;6764:36:0;6796:4;6764:36;;;6846:12;774:10:2;;695:96;6846:12:0;-1:-1:-1;;;;;6819:40:0;6837:7;-1:-1:-1;;;;;6819:40:0;6831:4;6819:40;;;;;;;;;;6652:224;;:::o;6882:225::-;2992:4;3015:12;;;;;;;;;;;-1:-1:-1;;;;;3015:29:0;;;;;;;;;;;;6952:149;;;7026:5;6994:12;;;;;;;;;;;-1:-1:-1;;;;;6994:29:0;;;;;;;;;;:37;;-1:-1:-1;;6994:37:0;;;7050:40;774:10:2;;6994:12:0;;7050:40;;7026:5;7050:40;6882:225;;:::o;686:204:5:-;622:4;;800:6;778:19;3350:12:4;;;3263:106;778:19:5;:28;;;;:::i;:::-;:37;;770:75;;;;-1:-1:-1;;;770:75:5;;12816:2:15;770:75:5;;;12798:21:15;12855:2;12835:18;;;12828:30;12894:27;12874:18;;;12867:55;12939:18;;770:75:5;12788:175:15;770:75:5;855:28;867:7;876:6;855:11;:28::i;4467:258:11:-;2077:4:0;2510:30;2077:4;774:10:2;2510::0;:30::i;:::-;4664:54:11::1;4697:6;4705:3;4710:7;4664:32;:54::i;2585:144:6:-:0;2686:36;2701:6;2709:3;2714:7;2686:14;:36::i;2143:169:12:-;2217:6;;;-1:-1:-1;;;;;2233:17:12;;;;;;;;;;;2265:40;;2217:6;;;2233:17;2217:6;;2265:40;;2198:16;;2265:40;2143:169;;:::o;1643:441:14:-;1718:13;1743:19;1775:10;1779:6;1775:1;:10;:::i;:::-;:14;;1788:1;1775:14;:::i;:::-;1765:25;;;;;;-1:-1:-1;;;1765:25:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1765:25:14;;1743:47;;1800:15;:6;1807:1;1800:9;;;;;;-1:-1:-1;;;1800:9:14;;;;;;;;;;;;:15;;;;;;;;;;;1825;:6;1832:1;1825:9;;;;;;-1:-1:-1;;;1825:9:14;;;;;;;;;;;;:15;;;;;;;;;;-1:-1:-1;1855:9:14;1867:10;1871:6;1867:1;:10;:::i;:::-;:14;;1880:1;1867:14;:::i;:::-;1855:26;;1850:132;1887:1;1883;:5;1850:132;;;1921:12;1934:5;1942:3;1934:11;1921:25;;;;;-1:-1:-1;;;1921:25:14;;;;;;;;;;;;1909:6;1916:1;1909:9;;;;;;-1:-1:-1;;;1909:9:14;;;;;;;;;;;;:37;;;;;;;;;;-1:-1:-1;1970:1:14;1960:11;;;;;1890:3;;;:::i;:::-;;;1850:132;;;-1:-1:-1;1999:10:14;;1991:55;;;;-1:-1:-1;;;1991:55:14;;7268:2:15;1991:55:14;;;7250:21:15;;;7287:18;;;7280:30;7346:34;7326:18;;;7319:62;7398:18;;1991:55:14;7240:182:15;1674:609:6;-1:-1:-1;;;;;1794:29:6;;1786:82;;;;-1:-1:-1;;;1786:82:6;;12001:2:15;1786:82:6;;;11983:21:15;12040:2;12020:18;;;12013:30;12079:34;12059:18;;;12052:62;12150:10;12130:18;;;12123:38;12178:19;;1786:82:6;11973:230:15;1786:82:6;-1:-1:-1;;;;;1884:17:6;;1876:75;;;;-1:-1:-1;;;1876:75:6;;9653:2:15;1876:75:6;;;9635:21:15;9692:2;9672:18;;;9665:30;9731:34;9711:18;;;9704:62;9802:15;9782:18;;;9775:43;9835:19;;1876:75:6;9625:235:15;1876:75:6;1967:12;1959:51;;;;-1:-1:-1;;;1959:51:6;;10474:2:15;1959:51:6;;;10456:21:15;10513:2;10493:18;;;10486:30;10552:28;10532:18;;;10525:56;10598:18;;1959:51:6;10446:176:15;1959:51:6;2042:31;;;;;2067:4;2042:31;;;5541:74:15;2025:14:6;;-1:-1:-1;;;;;2042:16:6;;;;;5514:18:15;;2042:31:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2025:48;;2099:7;2089:6;:17;;2081:64;;;;-1:-1:-1;;;2081:64:6;;13933:2:15;2081:64:6;;;13915:21:15;13972:2;13952:18;;;13945:30;14011:34;13991:18;;;13984:62;14082:4;14062:18;;;14055:32;14104:19;;2081:64:6;13905:224:15;3978:168:6;4073:4;4087:33;-1:-1:-1;;;;;4087:19:6;;4107:3;4112:7;729:58:13;;;-1:-1:-1;;;;;5818:55:15;;;729:58:13;;;5800:74:15;5890:18;;;;5883:34;;;729:58:13;;;;;;;;;;5773:18:15;;;;729:58:13;;;;;;;;;;752:23;729:58;;;3453:69;;;;;;;;;;;;;;;;702:86;;722:5;;729:58;-1:-1:-1;;3453:69:13;;:27;;;729:58;;3453:27;:69::i;:::-;3536:17;;3427:95;;-1:-1:-1;3536:21:13;3532:221;;3676:10;3665:30;;;;;;;;;;;;:::i;:::-;3657:85;;;;-1:-1:-1;;;3657:85:13;;14336:2:15;3657:85:13;;;14318:21:15;14375:2;14355:18;;;14348:30;14414:34;14394:18;;;14387:62;14485:12;14465:18;;;14458:40;14515:19;;3657:85:13;14308:232:15;3569:223:1;3702:12;3733:52;3755:6;3763:4;3769:1;3772:12;3733:21;:52::i;:::-;3726:59;3569:223;-1:-1:-1;;;;3569:223:1:o;4656:499::-;4821:12;4878:5;4853:21;:30;;4845:81;;;;-1:-1:-1;;;4845:81:1;;10067:2:15;4845:81:1;;;10049:21:15;10106:2;10086:18;;;10079:30;10145:34;10125:18;;;10118:62;10216:8;10196:18;;;10189:36;10242:19;;4845:81:1;10039:228:15;4845:81:1;1142:20;;4936:60;;;;-1:-1:-1;;;4936:60:1;;13575:2:15;4936:60:1;;;13557:21:15;13614:2;13594:18;;;13587:30;13653:31;13633:18;;;13626:59;13702:18;;4936:60:1;13547:179:15;4936:60:1;5008:12;5022:23;5049:6;-1:-1:-1;;;;;5049:11:1;5068:5;5075:4;5049:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5007:73;;;;5097:51;5114:7;5123:10;5135:12;5097:16;:51::i;:::-;5090:58;4656:499;-1:-1:-1;;;;;;;4656:499:1:o;7269:692::-;7415:12;7443:7;7439:516;;;-1:-1:-1;7473:10:1;7466:17;;7439:516;7584:17;;:21;7580:365;;7778:10;7772:17;7838:15;7825:10;7821:2;7817:19;7810:44;7727:145;7917:12;7910:20;;-1:-1:-1;;;7910:20:1;;;;;;;;:::i;14:257:15:-;73:6;126:2;114:9;105:7;101:23;97:32;94:2;;;147:6;139;132:22;94:2;191:9;178:23;210:31;235:5;210:31;:::i;276:398::-;344:6;352;405:2;393:9;384:7;380:23;376:32;373:2;;;426:6;418;411:22;373:2;470:9;457:23;489:31;514:5;489:31;:::i;:::-;539:5;-1:-1:-1;596:2:15;581:18;;568:32;609:33;568:32;609:33;:::i;:::-;661:7;651:17;;;363:311;;;;;:::o;679:466::-;756:6;764;772;825:2;813:9;804:7;800:23;796:32;793:2;;;846:6;838;831:22;793:2;890:9;877:23;909:31;934:5;909:31;:::i;:::-;959:5;-1:-1:-1;1016:2:15;1001:18;;988:32;1029:33;988:32;1029:33;:::i;:::-;783:362;;1081:7;;-1:-1:-1;;;1135:2:15;1120:18;;;;1107:32;;783:362::o;1150:776::-;1229:6;1237;1245;1298:2;1286:9;1277:7;1273:23;1269:32;1266:2;;;1319:6;1311;1304:22;1266:2;1363:9;1350:23;1382:31;1407:5;1382:31;:::i;:::-;1432:5;-1:-1:-1;1488:2:15;1473:18;;1460:32;1511:18;1541:14;;;1538:2;;;1573:6;1565;1558:22;1538:2;1616:6;1605:9;1601:22;1591:32;;1661:7;1654:4;1650:2;1646:13;1642:27;1632:2;;1688:6;1680;1673:22;1632:2;1733;1720:16;1759:2;1751:6;1748:14;1745:2;;;1780:6;1772;1765:22;1745:2;1830:7;1825:2;1816:6;1812:2;1808:15;1804:24;1801:37;1798:2;;;1856:6;1848;1841:22;1798:2;1892;1888;1884:11;1874:21;;1914:6;1904:16;;;;;1256:670;;;;;:::o;1931:325::-;1999:6;2007;2060:2;2048:9;2039:7;2035:23;2031:32;2028:2;;;2081:6;2073;2066:22;2028:2;2125:9;2112:23;2144:31;2169:5;2144:31;:::i;:::-;2194:5;2246:2;2231:18;;;;2218:32;;-1:-1:-1;;;2018:238:15:o;2261:297::-;2328:6;2381:2;2369:9;2360:7;2356:23;2352:32;2349:2;;;2402:6;2394;2387:22;2349:2;2439:9;2433:16;2492:5;2485:13;2478:21;2471:5;2468:32;2458:2;;2519:6;2511;2504:22;2563:190;2622:6;2675:2;2663:9;2654:7;2650:23;2646:32;2643:2;;;2696:6;2688;2681:22;2643:2;-1:-1:-1;2724:23:15;;2633:120;-1:-1:-1;2633:120:15:o;2758:325::-;2826:6;2834;2887:2;2875:9;2866:7;2862:23;2858:32;2855:2;;;2908:6;2900;2893:22;2855:2;2949:9;2936:23;2926:33;;3009:2;2998:9;2994:18;2981:32;3022:31;3047:5;3022:31;:::i;3088:352::-;3146:6;3199:2;3187:9;3178:7;3174:23;3170:32;3167:2;;;3220:6;3212;3205:22;3167:2;3264:9;3251:23;3314:66;3307:5;3303:78;3296:5;3293:89;3283:2;;3401:6;3393;3386:22;3445:481;3537:6;3545;3553;3606:2;3594:9;3585:7;3581:23;3577:32;3574:2;;;3627:6;3619;3612:22;4126:194;4196:6;4249:2;4237:9;4228:7;4224:23;4220:32;4217:2;;;4270:6;4262;4255:22;4217:2;-1:-1:-1;4298:16:15;;4207:113;-1:-1:-1;4207:113:15:o;4325:274::-;4454:3;4492:6;4486:13;4508:53;4554:6;4549:3;4542:4;4534:6;4530:17;4508:53;:::i;:::-;4577:16;;;;;4462:137;-1:-1:-1;;4462:137:15:o;4604:786::-;5015:25;5010:3;5003:38;4985:3;5070:6;5064:13;5086:62;5141:6;5136:2;5131:3;5127:12;5120:4;5112:6;5108:17;5086:62;:::i;:::-;5212:19;5207:2;5167:16;;;5199:11;;;5192:40;5257:13;;5279:63;5257:13;5328:2;5320:11;;5313:4;5301:17;;5279:63;:::i;:::-;5362:17;5381:2;5358:26;;4993:397;-1:-1:-1;;;;4993:397:15:o;6619:442::-;6768:2;6757:9;6750:21;6731:4;6800:6;6794:13;6843:6;6838:2;6827:9;6823:18;6816:34;6859:66;6918:6;6913:2;6902:9;6898:18;6893:2;6885:6;6881:15;6859:66;:::i;:::-;6977:2;6965:15;-1:-1:-1;;6961:88:15;6946:104;;;;7052:2;6942:113;;6740:321;-1:-1:-1;;6740:321:15:o;16098:128::-;16138:3;16169:1;16165:6;16162:1;16159:13;16156:2;;;16175:18;;:::i;:::-;-1:-1:-1;16211:9:15;;16146:80::o;16231:228::-;16271:7;16397:1;-1:-1:-1;;16325:74:15;16322:1;16319:81;16314:1;16307:9;16300:17;16296:105;16293:2;;;16404:18;;:::i;:::-;-1:-1:-1;16444:9:15;;16283:176::o;16464:125::-;16504:4;16532:1;16529;16526:8;16523:2;;;16537:18;;:::i;:::-;-1:-1:-1;16574:9:15;;16513:76::o;16594:258::-;16666:1;16676:113;16690:6;16687:1;16684:13;16676:113;;;16766:11;;;16760:18;16747:11;;;16740:39;16712:2;16705:10;16676:113;;;16807:6;16804:1;16801:13;16798:2;;;-1:-1:-1;;16842:1:15;16824:16;;16817:27;16647:205::o;16857:196::-;16896:3;16924:5;16914:2;;16933:18;;:::i;:::-;-1:-1:-1;;;16969:78:15;;16904:149::o;17058:437::-;17137:1;17133:12;;;;17180;;;17201:2;;17255:4;17247:6;17243:17;17233:27;;17201:2;17308;17300:6;17297:14;17277:18;17274:38;17271:2;;;-1:-1:-1;;;17342:1:15;17335:88;17446:4;17443:1;17436:15;17474:4;17471:1;17464:15;17271:2;;17113:382;;;:::o;17500:184::-;-1:-1:-1;;;17549:1:15;17542:88;17649:4;17646:1;17639:15;17673:4;17670:1;17663:15;17689:154;-1:-1:-1;;;;;17768:5:15;17764:54;17757:5;17754:65;17744:2;;17833:1;17830;17823:12

Swarm Source

ipfs://fe0237223123cdfdc32fbea6ef4b44c4e3d33188e9e78c0be2d4e0548d25caf5
Loading