账户
0x90...8a80
PogCoin

PogCoin

$500
此合同的源代码已经过验证!
合同元数据
编译器
0.8.27+commit.40a35a09
语言
Solidity
合同源代码
文件 1 的 1:pogs_escaped.sol
// SPDX-License-Identifier: BSL-1.1 Business Software License
pragma solidity 0.8.27;

//
// )))))))))))))))))))))))))))))))))))       (((((((((((((((((((((((((((((((((((
// )))))))))))))))))))))))))))))))))))       (((((((((((((((((((((((((((((((((((
// )))))))))))))))))))))))))))))))))))       (((((((((((((((((((((((((((((((((((
// )))))))))))))))))))))))))))))))))))       (((((((((((((((((((((((((((((((((((
//
//
//
// )))))))))))))))))))))))))))                       (((((((((((((((((((((((((((
// )))))))))))))))))))))))))))))))               (((((((((((((((((((((((((((((((
// )))))))))))))))))))))))))))))))))           (((((((((((((((((((((((((((((((((
// ))))))))))))))))))))))))))))))))))         ((((((((((((((((((((((((((((((((((
//                     )))))))))))))))       (((((((((((((((
//                        ))))))))))))       ((((((((((((
//                         )))))))))))       (((((((((((
//                         )))))))))))       (((((((((((
//                         )))))))))))       (((((((((((
//                         )))))))))))       (((((((((((
//                         )))))))))))       (((((((((((
//
// FUEL-20 POGS Token Contract
// Generated by: FuelFoundry, LLC, a Belize corporation, all rights reserved.
// More info at: https://fuelfoundry.io
// Code Release: FUEL20v3.1-POGS-PUBLIC
// Published Date: Sept 15th, 2024
// Change License: AGPL-3.0 GNU Affero General Public License v3.0
// Change Date: Sept 15th, 2028
//
// DISCLAIMER: This smart contract is provided "as is", with no warranties whatsoever, including any warranty of
// merchantability, fitness for any particular purpose, or any warranty otherwise arising out of any proposal,
// specification, or sample. By using this smart contract, you agree to take full responsibility for your use of the
// contract, including but not limited to the loss of data or funds. No representation or warranty is provided for the
// safety, security, accuracy, or performance of this contract.
//
// This contract is intended to be used as described in the documentation and in the context of Ethereum based
// blockchain environments. Use of this contract in a manner inconsistent with its intended purpose or design, or
// modification of the contract code, is done at your own risk and may expose you to legal or financial penalties.
//
// This software is provided by the copyright holders and contributors "as is" and any express or implied warranties,
// including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are
// disclaimed. In no event shall FuelFoundry, LLC or contributors be liable for any direct, indirect, incidental,
// special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or
// services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability,
// whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use
// of this software, even if advised of the possibility of such damage.
//
// NOTE: This smart contract is under continuous development and internal audits, and undergone two external audits.
//
// -----------------------------------------------------------------------------
//
// PREMISE: The FUEL-20 Token Contract is the core component of the reward framework for FuelFoundry applications and
// FuelFoundry VIP partners on EVM-compliant chains. Its functions and features, which may be fine-tuned over time, are
// governed through the multi-signature `ExecutiveSession` process, inspired by Robert's Rules of Order.
//
// Governance (2/3 Majority Required):
// - Custodial, Guardian, and Executor are designated roles within the FuelFoundry and/or partner ecosystem.
// - While Custodial and Guardian have unique roles in other FF contracts (e.g., FUEL-721),
//   they operate as equal roles for FUEL-20 governance.
// - A 2/3 majority multi-signature is required to enter Executive Session for updating core values.
//
// During Executive Session:
// - **Executor** may:
//   - Update global settings
//   - Adjust staking reward percentages and block rewards
//   - Add/Remove Mint Controllers
//   - Enable/Disable Shield Settings
// - **Custodial and Guardian** may:
//   - Enable/Disable Mint Controllers
// - **All roles (excluding Oracle)** may:
//   - Propose and elect new role handlers
//   - Update per block subchain validator staker rewards
//   - Close Executive Session
//
// Operations:
// - **L1 Roles (Custodial, Guardian, Executor):** Core executives of the fabric.
// - **L2 Role (Oracle):** Read-only access to fabric variables, may issue claims on behalf of stakers,
//   utilize tools, and update limited configuration data.
// - **Minting:** mintControllers may call the `mintCtrl` function to mint new tokens up to `maxSupply`
//   and claimMetrix will be incremented per use.
// - **Minting:** bridgeOperators may call the `mint` function to mint new tokens up to `maxSupply`
//   and claimMetrix will not be incremented per use.
// - **Initial Distribution:** Refer to project roadmap.
//
// Fabric Roles (G1):
// - **Custodial:** Open/Close ExecutiveSession, query session code, propose new role handlers,
//   enable/disable mint controllers.
// - **Guardian:** Open/Close ExecutiveSession, query session code, propose new role handlers,
//   enable/disable mint controllers.
// - **Executor:** Open/Close ExecutiveSession, add/remove mint controllers, update fabric variables,
//   enable/disable shield settings.
//
// Fabric Roles (G2):
// - **Oracle:** Read-only access to governance settings; may perform auto-claim operations on behalf of FUEL20 stakers.
//
// FuelSig Multi-Signature Execution:
// - Executive Session initiation requires two (2) out of three (3) L1 governance wallets.
// - Custodial and Guardian wallets act as board members and can retrieve the executive session code.
// - The Executor needs the commit code from the Custodial or Guardian wallet to apply updates.
// - The Executor commits proposals as enacted during Executive Session.
// - If any governance actor performs improper actions, the other two members can vote to remove the actor.
//
// -----------------------------------------------------------------------------
//
// "A chain is never stronger than it's weakest link" -T. Reid
//
// -----------------------------------------------------------------------------
//
// Compiler Settings: 
// Version: 0.8.27
// {"language":"Solidity","settings":{"optimizer":{"enabled":true,"runs":420},"evmVersion":"cancun","outputSelection":{"*":{"":["ast"],"*":["abi","metadata","devdoc","userdoc","storageLayout","evm.legacyAssembly","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","evm.gasEstimates","evm.assembly"]}}}}
//

// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)

// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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


// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)





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

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

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


// OpenZeppelin Contracts (last updated v5.0.1) (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;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}


// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)


/**
 * @dev Standard ERC20 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.
 */
interface IERC20Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC20InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC20InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     * @param allowance Amount of tokens a `spender` is allowed to operate with.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC20InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC20InvalidSpender(address spender);
}

/**
 * @dev Standard ERC721 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.
 */
interface IERC721Errors {
    /**
     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.
     * Used in balance queries.
     * @param owner Address of the current owner of a token.
     */
    error ERC721InvalidOwner(address owner);

    /**
     * @dev Indicates a `tokenId` whose `owner` is the zero address.
     * @param tokenId Identifier number of a token.
     */
    error ERC721NonexistentToken(uint256 tokenId);

    /**
     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param tokenId Identifier number of a token.
     * @param owner Address of the current owner of a token.
     */
    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC721InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC721InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param tokenId Identifier number of a token.
     */
    error ERC721InsufficientApproval(address operator, uint256 tokenId);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC721InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC721InvalidOperator(address operator);
}

/**
 * @dev Standard ERC1155 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.
 */
interface IERC1155Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     * @param tokenId Identifier number of a token.
     */
    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC1155InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC1155InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param owner Address of the current owner of a token.
     */
    error ERC1155MissingApprovalForAll(address operator, address owner);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC1155InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC1155InvalidOperator(address operator);

    /**
     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
     * Used in batch transfers.
     * @param idsLength Length of the array of token identifiers
     * @param valuesLength Length of the array of token amounts
     */
    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}


/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * The default value of {decimals} is 18. To change this, you should override
 * this function so it returns a different value.
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of 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.
 */
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
    mapping(address account => uint256) private _balances;

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

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

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

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

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

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

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

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

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 value) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, value);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `value`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `value`.
     */
    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, value);
        _transfer(from, to, value);
        return true;
    }

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _transfer(address from, address to, uint256 value) internal {
        if (from == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        if (to == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(from, to, value);
    }

    /**
     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
     * this function.
     *
     * Emits a {Transfer} event.
     */
    function _update(address from, address to, uint256 value) internal virtual {
        if (from == address(0)) {
            // Overflow check required: The rest of the code assumes that totalSupply never overflows
            _totalSupply += value;
        } else {
            uint256 fromBalance = _balances[from];
            if (fromBalance < value) {
                revert ERC20InsufficientBalance(from, fromBalance, value);
            }
            unchecked {
                // Overflow not possible: value <= fromBalance <= totalSupply.
                _balances[from] = fromBalance - value;
            }
        }

        if (to == address(0)) {
            unchecked {
                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
                _totalSupply -= value;
            }
        } else {
            unchecked {
                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
                _balances[to] += value;
            }
        }

        emit Transfer(from, to, value);
    }

    /**
     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
     * Relies on the `_update` mechanism
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _mint(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(address(0), account, value);
    }

    /**
     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
     * Relies on the `_update` mechanism.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead
     */
    function _burn(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        _update(account, address(0), value);
    }

    /**
     * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     *
     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
     */
    function _approve(address owner, address spender, uint256 value) internal {
        _approve(owner, spender, value, true);
    }

    /**
     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
     *
     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
     * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
     * `Approval` event during `transferFrom` operations.
     *
     * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
     * true using the following override:
     * ```
     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
     *     super._approve(owner, spender, value, true);
     * }
     * ```
     *
     * Requirements are the same as {_approve}.
     */
    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
        if (owner == address(0)) {
            revert ERC20InvalidApprover(address(0));
        }
        if (spender == address(0)) {
            revert ERC20InvalidSpender(address(0));
        }
        _allowances[owner][spender] = value;
        if (emitEvent) {
            emit Approval(owner, spender, value);
        }
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `value`.
     *
     * Does not update the allowance value in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Does not emit an {Approval} event.
     */
    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            if (currentAllowance < value) {
                revert ERC20InsufficientAllowance(spender, currentAllowance, value);
            }
            unchecked {
                _approve(owner, spender, currentAllowance - value, false);
            }
        }
    }
}


// OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol)



/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant NOT_ENTERED = 1;
    uint256 private constant ENTERED = 2;

    uint256 private _status;

    /**
     * @dev Unauthorized reentrant call.
     */
    error ReentrancyGuardReentrantCall();

    constructor() {
        _status = NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be NOT_ENTERED
        if (_status == ENTERED) {
            revert ReentrancyGuardReentrantCall();
        }

        // Any calls to nonReentrant after this point will fail
        _status = ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = NOT_ENTERED;
    }

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == ENTERED;
    }
}



//
// CONTRACT
//

contract PogToken is ERC20, ReentrancyGuard {


    //
    // CONSTS
    //

    string private constant TOKEN_NAME = "PogCoin"; 
    string private constant TOKEN_SYMBOL = "POGS"; 

    uint private constant MILLION = 1e6;
    uint private constant INTERMEDIATE_TOKEN_ESCROW_AMOUNT_IN_ETHER = 0; //60 * MILLION;
    uint private constant MAX_MINT_CONTROLLERS = 1000;
    uint private constant MAX_SUPPLY_IN_ETHER  = 2000 * MILLION; //2 BILLION
    uint private constant REWARD_PER_BLOCK_DIVISOR_FAILSAFE = 10 * MILLION;
    uint private constant GOV_SESSION_MAX = 4 hours;
    uint private constant GOV_SESSION_COOLDOWN = 30 seconds;

    string private constant MSG_SUCCESS = "Success";
    string private constant MSG_FAILED  = "Failed";
    

    //
    // ENUMS
    //

    // SHIELD: Various operational states and security mechanisms within the contract providing
    // FuelShield identifiers for management access and actions based on current contract state.
    enum SHIELD {

        CLAIM,       // When enabled, claiming is disabled.
        MINT,        // When enabled, minting is disabled.
        BURN,        // When enabled, burning is disabled.
        STAKE,       // When enabled, staking is disabled.
        MAINTENANCE  // Indicates the contract is in maintenance mode, restricting all non-standard erc20 operations.
    }

    // Severity: Defines levels of importance for logging and monitoring, allowing for prioritized
    // attention and response based on the criticality of the information or event.
    enum Severity {

        Alert,        // Immediate action and/or attention required, though system is functional.
        Critical,     // Critical conditions, require attention to prevent escalation.
        Warning,      // Warning conditions, not immediately harmful but indicative of potential issues.
        Notice,       // Normal but significant conditions worth noting.
        Informational,// Informational messages, non-critical, useful information.
        Debug         // Debug-level messages, intended for development and troubleshooting.
    }

    // Facility: Categorizes areas of the contract or ecosystem to which logs, alerts, or operational
    // events are related, facilitating targeted diagnostics and management.
    enum Facility {

        Protocol,      // Related to the core protocol operations and mechanics.
        Governance,    // Pertains to governance actions and mechanisms.
        Executive,     // Involves executive decision-making and actions.
        Operations,    // Operational aspects of the contract.
        Oracle,        // Related to oracle services and actions taken by Oracle.
        External       // External systems or interactions outside fuelfabric ecosystems.
    }


    //
    // STRUCTS
    //

    // Allowance structure for managing token allowances as they're created.
    struct Allowance {

        address owner;    // address of the token owner who is giving the allowance.
        address spender;  // address of the account that is allowed to spend the tokens.
        uint amount;      // amount of tokens that are allowed to be spent.
    }

    // ExecutiveSession structure holds configuration details for executive sessions within the FuelFoundry governance framework.
    struct ExecutiveSession {

        uint code;        // Unique code generated for authenticating access into executive session.
        uint seed;        // Seed value used in generating the session code, may be reset by the guardian.
        uint startedAt;   // Timestamp when the current or last executive session was entered.
        uint expiresAt;   // Timestamp when the current session expires, after which a new session must be initiated.
        uint sessionMax;  // The maximum duration (in seconds) an executive session can remain active.
        uint sessionCooldown; // The cooldown period (in seconds) for re-initiating an executive session.
    }

    // GovernanceKey structure represents a governance key, detailing roles within the executive board and their respective permissions.
    struct GovernanceKey {

        address wallet;    // The primary wallet address associated with a governance role.
        address custodial; // Declared address of the custodial (secretary) address.
        address guardian;  // Declared address of the guardian (vice president) address.
        address executor;  // Declared address of the executor (president) address, responsible for executing decisions.
        address oracle;    // Declared address of the oracle (non-executive), responsible for managing non-erc20 related functions, data and validations.
        uint code;         // Code (aka es-code), set by governance member to initiate executive session; two of the three governance members must lock in the same code to initialize executive session.
    }

    /**
     * MintController structure represents an external mint controller permitted to mint FUEL-20 tokens.
     *
     * This struct is part of a mechanism allowing specific external contracts to interact with the
     * FUEL-20 contract for the purpose of minting tokens. Each MintController is identified by a
     * unique contract address, and its ability to mint tokens may be toggled on and off. This design
     * enables decentralized governance over minting operations by allowing the addition or removal of
     * minting permissions to specific contracts, future-proofing reward mechanics of the token minting process.
     *
     * @param contractAddress address of the external contract permitted to mint FUEL-20 tokens.
     * @param enabled boolean flag indicating whether the MintController is currently authorized to mint tokens.
     */
    struct MintController {

        address contractAddress; // address of the controller contract.
        bool enabled;            // True if minting by this controller is enabled, false otherwise.
    }

    /**
     * Fuel20BaseContract structure defines the foundational structure for managing the FUEL-20 token ecosystem within the FuelFoundry environment.
     *
     * The Fuel20BaseContract struct is central to the FUEL-20 governance, staking, and token dynamics. It contains
     * variables for tracking various token metrics, such as staked amounts, claims, and burns. This struct also incorporates
     * several safeguards through 'shield' toggles that help manage the minting, staking, claiming, and burning processes,
     * enhancing the security and flexibility of token operations. Additionally, it provides global and real-time analytics
     * for detailed oversight of token interactions over time. Key functionalities include the management of token supply caps,
     * staking rewards, and holder allowances, making it a critical component for the token's lifecycle and governance.
     *
     * @param fuelId Identifier linking to FuelFoundry MetaForge Analytics for detailed tracking.
     * @param initAt Timestamp indicating when this contract was initialized.
     * @param topOffSupply Specifies a threshold for token supply above which only fractional tokens can be minted to the contract owner.
     * @param maxSupply The maximum allowable number of tokens that can exist within the ecosystem.
     * @param maxAllowances Maximum number of allowances that can be tracked per user, enhancing transparency.
     * @param stakeAnnualPercentRewardRate Annual percentage rate for FUEL-20 staking rewards.
     * @param stakeMin Minimum amount of FUEL required for participating in staking.
     * @param claimCooldown Minimum cooldown period in seconds between consecutive claims.
     * @param _allowancesByOwner Mapping to manage allowances assigned to each owner.
     * @param staked, claimed, burned Track the total amount of FUEL-20 staked, claimed, and burned by address, respectively.
     * @param stakedAt, unstakedAt, stakeClaimedAt Track the timestamps for staking activities and claims by address.
     * @param claimedAt Mapping to track the timestamps of claims by address for each epoch.
     * @param totalStakedAt, totalUnstakedAt, totalClaimedAt, totalBurnedAt Track the total amount of tokens staked, unstaked, claimed, and burned at each timestamp.
     * @param totalStaked, totalClaimed, totalBurned Track the real-time total amount of tokens staked, claimed, and burned, respectively.
     * @param mintshield, stakeshield, claimshield, burnshield Toggles for activating respective security features to protect token operations.
     * @param maintenance Toggle for activating maintenance mode, disabling all non-standard functionalities during migrations or updates.
     * @param nonce A unique identifier used for event tracking and integration with the MetaForge dashboard.
     */
    struct Fuel20BaseContract {


        //
        // FUEL GLOBAL
        //

        // vars
        uint80 fuelId;      // ID number for tying back to FuelFoundry MetaForge Analytics
        uint initAt;        // This contract's initialization timestamp
        uint topOffSupply;  // By default this is maxSupply - 1 ether, when totalSupply is above topOffSupply, topOffSupply may be utilized to mint the remaining fraction of a token to the contract owner Address and enables mintsheild + stakeshield.
        uint maxSupply;     // Production value to be set at ten (10) billion ether - Maximum number of tokens allowed in circulation.
        uint maxAllowances; // Production value to be set at one-hundred (100) - Max allowances tracked per user, keeping holders more informed about outstanding allowances.

        // staking
        uint stakeAnnualPercentRewardRate; // Production value to be set to 5%. FUEL-20 self-stake earning APR, set to % for earning.
        uint stakeMin;      // Production value to be set to 1 ether. Minimum required FUEL for virtual staking FUEL20.
        uint claimCooldown; // Production value to be set to 30 seconds. Number of seconds required between claims (minimum 30 seconds).

        // minting
        uint mintLimiter;   // Virtual mint cap to mitigate abuse in case of a controller/bridge hijack; 0 = no limit (disabled).


        //
        // HOLDER TRACKING
        //

        // allowance
        mapping(address => Allowance[]) _allowancesByOwner; // mapping utilized to track allowances by owner

        // analytics
        mapping(address => uint) staked;         // total fuel20 staked by address
        mapping(address => uint) claimed;        // total fuel-20 claimed by address
        mapping(address => uint) burned;         // total fuel-20 burned by address

        // stake
        mapping(address => uint) stakedAt;       // tracks timestamp when holder staked, also tracks when holder last claimed or updates stake amount
        mapping(address => uint) unstakedAt;     // tracks timestamp when holder last unstaked
        mapping(address => uint) stakeClaimedAt; // tracks timestamp when holder last claimed

        // claim
        mapping(address => mapping(uint => uint)) claimedAt; // total fuel-20 claimed by address at specified epoch

        // burn
        mapping(address => mapping(uint => uint)) burnedAt; // total fuel-20 claimed by address at specified epoch


        //
        // GLOBAL ANALYTICS
        //

        // totals - time tracking
        mapping(uint => uint) totalStakedAt;   // total FUEL20 tokens staked at timestamp
        mapping(uint => uint) totalUnstakedAt; // total FUEL20 tokens unstaked at timestamp
        mapping(uint => uint) totalClaimedAt;  // total FUEL20 tokens claimed at timestamp
        mapping(uint => uint) totalBurnedAt;   // total FUEL20 tokens burned at timestamp

        // totals - realtime tracking
        uint totalStaked;  // Current amount of FUEL20 staked in wei.
        uint totalClaimed; // Total number of FUEL20 tokens that have been created / claimed in wei.
        uint totalBurned;  // Total number of FUEL20 tokens that can be burned in wei.


        //
        // FUELSHIELD
        //

        // toggles
        bool mintshield;  // toggle variable for mintshield
        bool stakeshield; // toggle variable for stakeshield
        bool claimshield; // toggle variable for claimshield
        bool burnshield;  // toggle variable for burnshield
        bool maintenance; // toggle variable for maintenance mode is reserved for future migrations, disabling all bonus features, standard ERC functions remain operations.

        // event tracking
        uint nonce;       // ties back to metaforge dashboard
    }

    /**
     * Subchain structure manages staking rewards configurations for a FuelFoundry subchain.
     *
     * This struct supports managing validator rewards within a subchain, ensuring incentive alignment and controlled reward distribution. It allows for setting both maximum and actual reward rates per block to balance sustainability with validators' contributions.
     *
     * @param stakerRewardPerBlockMax Cap on rewards per block to maintain economic stability.
     * @param stakerRewardPerBlock Current rewards per block based on subchain policies and validator performance.
     */
    struct Subchain {

        uint stakerRewardPerBlock;    // Current staker reward per block.
        uint stakerRewardPerBlockMax; // Maximum allowable staker reward per block.
    }


    //
    // MODIFIERS
    //

    /**
     * onlyGovernance modifier ensures that only accounts with governance permissions can execute the modified function.
     *
     * This modifier restricts the execution of the function to which it's applied to only those
     * addresses that are recognized as part of the governance structure. It checks if the caller
     * is authorized as governance by calling `_isGov`, which internally verifies the caller's
     * governance status. If the caller is not authorized, the transaction is reverted with a
     * "!gov" error message, indicating lack of governance permissions.
     */
    modifier onlyGovernance() { require(_isGov(msg.sender), "!gov"); _; }

    /**
     * onlyExecutor modifier restricts function execution to the designated executor.
     *
     * This modifier ensures that only the executor, whose address is stored in the `executor.wallet`,
     * can call the modified function. It is used to protect sensitive operations that should be
     * carried out under the strict oversight of the contract's executor role. If the caller's address
     * does not match the executor's address, the transaction is reverted with a "!exe" error message.
     */
    modifier onlyExecutor() { require(msg.sender == executor.wallet, "!exe"); _; }

    /**
     * onlyCustodialGuardian modifier allows access only to the custodial or guardian role.
     *
     * Functions modified with this check can be executed by either the custodial or guardian roles,
     * ensuring that operations requiring higher-level oversight or dual-control security mechanisms
     * are adequately protected. The modifier checks if the caller matches either the `custodial.wallet`
     * or `guardian.wallet` addresses. If not, it reverts the transaction with a "!cgn" message, indicating
     * unauthorized access attempt by non-custodial or guardian entities.
     */
    modifier onlyCustodialGuardian() { require(msg.sender == custodial.wallet || msg.sender == guardian.wallet, "!cgn"); _; }

    /**
     * onlyOracle modifier confines the execution of the attached function to the oracle role.
     *
     * This modifier is designed to ensure that only the oracle, as determined by the `_oracle()`
     * function, can perform the operation it guards. It's essential for actions that depend on
     * external data verification or specific insights that the oracle provides. If the caller is
     * not the oracle, the transaction will revert with a "!ora" error message, safeguarding the
     * function against unauthorized access.
     */
    modifier onlyOracle() { require(msg.sender == _oracle(), "!ora"); _; }

    /**
     * onlyController modifier ensures that only approved mint controllers can execute the function.
     *
     * To safeguard minting operations and maintain controlled access to minting capabilities,
     * this modifier restricts function execution to addresses that have been designated as mint
     * controllers. It leverages the `_isMintController` function to verify if the caller is an
     * authorized mint controller. Unauthorized callers trigger a transaction revert with a "!con"
     * message, preventing execution by entities outside the approved controller list.
     */
    modifier onlyEnabledController() { require(_isMintControllerEnabled(msg.sender), "mintctrl role required to mint"); _; }

    /**
     * onlyController modifier ensures that only approved mint controllers can execute the function.
     *
     * To safeguard minting operations and maintain controlled access to minting capabilities,
     * this modifier restricts function execution to addresses that have been designated as mint
     * controllers. It leverages the `_isMintController` function to verify if the caller is an
     * authorized mint controller. Unauthorized callers trigger a transaction revert with a "!con"
     * message, preventing execution by entities outside the approved controller list.
     */
    modifier onlyValidator() { require(isValidator[msg.sender] == true, "validator role required to mint"); _; }

    /**
     * onlyExecutiveSession modifier ensures that function execution only occurs within a valid executive session under specific quorum conditions.
     *
     * This modifier is designed to enforce governance protocol by limiting function execution to the context of
     * an established executive session. It first checks that an executive session is currently active using the
     * `executiveSession()` function. It then verifies that the session's quorum conditions are met by checking the
     * current executor's code with `_quorumCodeVerify()`. If either condition fails, the transaction is reverted
     * with an appropriate error message to indicate the nature of the failure.
     */
    modifier onlyExecutiveSession() {

        // check if the executive session is established
        require(_inSession(), "quorm!estab");

        // verify executor quorum code synchronization
        require(_quorumCodeVerify(executor.code), "qcvfail");
        _;
    }


    //
    // GLOBALS
    //

    // ExecutiveSession declaration holds the current state of an executive session, including details like session codes, timestamps, and session limits.
    // Stored privately to ensure that session management is internally controlled and protected from unauthorized external access.
    ExecutiveSession private exsess;

    // GovernanceKey struct declarations for the custodial (secretary), guardian (vice president), and executor (president) roles.
    // These keys define the wallet addresses associated with each governance role, enabling role-based access control and actions.
    GovernanceKey private custodial;
    GovernanceKey private guardian;
    GovernanceKey private executor;

    // The base configuration and operational data for the FUEL-20 token contract.
    // Encapsulates essential tokenomics parameters, staking configurations, and operational metrics.
    Fuel20BaseContract private fuel20;

    // Represents the configuration and operational parameters of a subchain within the ecosystem.
    // This includes variables for managing staker rewards, aligning with subchain-specific policies and incentives.
    Subchain public subchain;

    // An array of MintController structs, listing external contracts permitted to mint FUEL-20 tokens.
    // This array supports enablement governance over designating mint controllers, allowing for the addition or removal of minting capabilities.
    MintController[] mintControllers;

    // MintController Extention
    mapping(address => bool) public isValidator;


    //
    // EVENT
    //

    event Trap(
        uint nonce,                // nonce
        uint timestamp,            // block timestamp
        address  indexed origin,   // address that initiated event
        Facility indexed facility, // source that produced the event
        Severity indexed severity, // urgency of event
        string  application,       // function name or identified
        uint value,                // relative data
        string  message            // info about the event
    );


    //
    // CONSTRUCTOR
    //

    /**
     * Initializes the contract with necessary governance roles and system parameters.
     *
     * Sets initial token properties, reserves amounts for escrow, sets maximum supply, and initializes governance roles.
     * Allows dynamic setting of the executive session seed used for 2FA in governance activities.
     *
     * @param __fuelId Initial fuel ID for analytics and tracking.
	 */
    constructor(uint80 __fuelId)
    ERC20(TOKEN_NAME, TOKEN_SYMBOL) {

        // all roles to sender on init
        address __root = msg.sender;
        address __guardian = __root;
        address __executor = __root;
        address __oracle   = __root;              

        // init - executive session
        exsess.seed        = (block.timestamp * 1e9) + block.number; // this variable seeds the handshake for governance members entering executive session
        exsess.sessionMax  = GOV_SESSION_MAX;                        // amt specified is in seconds; i.e. 14400 = 4 hours
        exsess.sessionCooldown = GOV_SESSION_COOLDOWN;               // 30 seconds
        exsess.startedAt   = block.timestamp;                        // for setup convenience, executive session is initiated when the contract is constructed
        exsess.expiresAt   = exsess.startedAt + exsess.sessionMax;   // initial executive session length set to sessionMax time
        exsess.code        = uint(keccak256(abi.encodePacked(block.number + block.number + block.timestamp + block.gaslimit + exsess.seed))) % 10 ** 9; // this intentionally pseudorandom variable is used by governance members only for entering executive session

        // init - executive governance enabled - two (2) of the three (3) executive codes must be in-sync to enable executive session
        custodial.code = exsess.code;
        guardian.code  = exsess.code;
        executor.code  = exsess.code;

        // init - fuelvars
        fuel20.fuelId        = __fuelId;                     // for analytics tracking in FuelFoundry MetaForge, internally used to tie contract back to fuelfoundry metaforge
        fuel20.stakeMin      = 1 ether;                      // minimum stake size when virtual staking fuel20
        fuel20.claimCooldown = 60 seconds;                   // cooldown between claims set to sixty (60) seconds
        fuel20.maxSupply     = MAX_SUPPLY_IN_ETHER * 10**18; // note: 10^18 at construction
        fuel20.topOffSupply  = fuel20.maxSupply - 10**18;    // topOffSupply is used for validator reward easing
        fuel20.maxAllowances = 10;                           // tracking first 10 approved allowances per holder
        fuel20.stakeAnnualPercentRewardRate = 5;             // 5% APR for self virtual staking

        // init - governance
        custodial.wallet    = msg.sender;
        guardian.wallet     = __guardian;
        executor.wallet     = __executor;

        custodial.custodial = custodial.wallet;
        custodial.guardian  = guardian.wallet;
        custodial.executor  = executor.wallet;
        custodial.oracle    = __oracle;

        guardian.custodial  = custodial.wallet;
        guardian.guardian   = guardian.wallet;
        guardian.executor   = executor.wallet;
        guardian.oracle     = __oracle;

        executor.custodial  = custodial.wallet;
        executor.guardian   = guardian.wallet;
        executor.executor   = executor.wallet;
        executor.oracle     = __oracle;

        // if initial payout specified, send to escrow wallet / smart contract (based on roadmap defined terms) / etc...
        if (INTERMEDIATE_TOKEN_ESCROW_AMOUNT_IN_ETHER > 0) {

            // accounting initial distribution as a claim
            fuel20.totalClaimed = INTERMEDIATE_TOKEN_ESCROW_AMOUNT_IN_ETHER * 10**18;
            _mint(__root, fuel20.totalClaimed);
        }

        // fuel20 contract variable global defaults //

        // fuelshield optional init configuration
        /*
        fuel20.maintenance   = true;
        fuel20.verbose       = true;
        fuel20.mintshield    = true;
        fuel20.burnshield    = true;
        fuel20.stakeshield   = true;
        fuel20.claimshield   = true;
        */

        // subchain validator staking
        subchain.stakerRewardPerBlock    = 10**9;                                                // default reward (in wei) per block validated
        subchain.stakerRewardPerBlockMax = fuel20.maxSupply / REWARD_PER_BLOCK_DIVISOR_FAILSAFE; // default max reward per block in wei

        // contract initlization
        fuel20.initAt = block.timestamp;
    }


    //
    // OVERRIDES (ERC20) AND OVERRIDE WRAPPERS
    //

    /**
     * _balanceOf calculates the adjusted balance for an account.
     * This private function participates in the override of "balanceOf" taking into account virtual stakes.
     *
     * @param __account The account address to query the balance of.
     * @return balance_ The calculated balance after subtracting the virtual stake.
     */
    function _balanceOf(address __account) private view returns (uint balance_) {

        // total balance of fuel20 in account (virtually staked and unstaked)
        uint ledgerBalance = super.balanceOf(__account);

        // virtually staked balance total (self-stake)
        uint virtuallyStakedBalance = fuel20.staked[__account];

        // subtract staked fuel20 from balance before reporting w/ safeguard adjustment
        if (ledgerBalance >= virtuallyStakedBalance) { return ledgerBalance - virtuallyStakedBalance; }
        else { return 0; }
    }


    /**
     * balanceOf retrieves the balance of a given account.
     * This public function overrides the standard "balanceOf" and internally calls `_balanceOf` to reflect subtraction of virtual stakes.
     *
     * ABI FORMATTED TO ERC20v5
     *
     * @param account The account address whose balance is being queried.
     * @return The balance of the account.
     */
    function balanceOf(address account) public view override returns (uint) {

        return _balanceOf(account);
    }


    /**
     * transfer executes a transfer of the specified amount from the sender's account to the specified recipient.
     * This public function overrides the standard "transfer", accounts for virtual stakes and ensures the operation is non-reentrant.
     *
     * ABI FORMATTED TO ERC20v5
     *
     * @param  to address to transfer funds to.
     * @param  value The amount of funds to transfer.
     * @return returns true if the transfer is successful.
     */
    function transfer(address to, uint value) public override nonReentrant returns (bool)  {

        // virtual balance supersedes ledger balance
        // require(_balanceOf(msg.sender) >= value, "value > account balance");
        require(_balanceOf(msg.sender) >= value, ERC20InsufficientBalance(msg.sender, _balanceOf(msg.sender), value));

        return super.transfer(to, value);
    }


    /**
     * transferFrom executes a transfer from a specified sender to a specified recipient.
     * This public function overrides the standard "transferFrom", with added non-reentrant protection.
     * This function does not purge tracked allowances (see: purgeAllowances).
     *
     * ABI FORMATTED TO ERC20v5
     *
     * @param from address to transfer funds from.
     * @param to address to transfer funds to.
     * @param value amount of funds to transfer.
     * @return returns true if the transfer is successful.
    */
    function transferFrom(address from, address to, uint value) public override nonReentrant returns (bool)  {

        // ensure the sender is not address(0)
        // require(from != address(0), "sender may != addr(0)");

        // ensure the recipient is not address(0)
        // require(to != address(0), "destination may != addr(0)");

        // virtual balance supersedes ledger
        require(_balanceOf(from) >= value, ERC20InsufficientBalance(from, _balanceOf(from), value));

        // update allowance tracking if enabled
        if (fuel20.maxAllowances > 0 && !_allowanceDecrease(from, msg.sender, value)) {

            // alert if update fails
            emit Trap(_nonce(), block.timestamp,msg.sender, Facility.Protocol, Severity.Critical, "transferFrom",  value, "failed to decrease tracked allowance");
        }

        // initiate request
        return super.transferFrom(from, to, value);
    }


    /**
     * burn burns a specified amount of tokens from the caller's balance.
     * This public function overrides the standard "burn", accounts for virtual stakes and includes non-reentrant protection.
     *
     * ERC20 OVERRIDE FORMATTED TO ERC20 STANDARD
     *
     * @param value the amount of tokens to be burned.
     */
    function burn(uint value) public nonReentrant {

        // burnshield
        _fuelShield(SHIELD.BURN);

        // ensure sender doesn't burn more tokens than they have available un-staked
        //require(_balanceOf(msg.sender) >= value, "value < account balance");
        require(_balanceOf(msg.sender) >= value, ERC20InsufficientBalance(msg.sender, _balanceOf(msg.sender), value));

        // update global metrix
        _burnMetrixAdd(msg.sender, value);

        // call the original burn logic
        _burn(msg.sender, value);
    }


    /**
     * burnFrom allows for the burning (destruction) of tokens from a specified account.
     * This public function extends "burnFrom", accounts for virtual stakes and includes non-reentrant protection.
     *
     * FORMATTED TO ERC20v5 STANDARD
     *
     * @param account The account from which tokens will be burned.
     * @param value The amount of tokens to burn.
     */
    function burnFrom(address account, uint value) public nonReentrant {

        // burnshield
        _fuelShield(SHIELD.BURN);

        // ensure the owner of the tokens doesn't burn more tokens than they have unstaked
        // require(_balanceOf(account) >= value, "value < account balance");
        require(_balanceOf(account) >= value, ERC20InsufficientBalance(account, _balanceOf(account), value));

        // update allowance tracking if enabled
        if (fuel20.maxAllowances > 0 && !_allowanceDecrease(account, msg.sender, value)) {

            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Protocol, Severity.Critical, "burnFrom",  value, "failed to decrease tracked allowance value");
        }

        // call OZ internal function to safely spend the allowance, if fails, tx will revert
        _spendAllowance(account, msg.sender, value);

        // update global metrix
        _burnMetrixAdd( account, value);

        // call OZ burn logic
        _burn(account, value);
    }


    /**
     * _isGov checks if the specified address is recognized as a government address.
     * This private function validates the government status of an address.
     *
     * @param  __address address to verify as a government address.
     * @return  Returns true if the address is a government address.
     */
    function _isGov(address __address) private view returns (bool) {

        return (__address == custodial.wallet || __address == guardian.wallet || __address == executor.wallet);
    }


    //
    // ALLOWANCES
    //

    /**
     * Approves the specified amount to be spent by another address.
     * This public function overrides the standard "approve".
     *
     * ABI CONFORMS TO ERC20v5
     *
     * @param spender address authorized to spend the funds.
     * @param value amount of funds approved for spending.
     * @return Returns true if the approval is successful.
     */
    function approve(address spender, uint256 value) public override nonReentrant returns (bool) {

        uint senderAllowanceCount = fuel20._allowancesByOwner[msg.sender].length;

        // holder may perform as many allowances as they wish, the contract will only track upto the max allowances as defined
        if (senderAllowanceCount < fuel20.maxAllowances) {

            // find or add the allowance for this spender
            bool found = false;

            for (uint i = 0; i < fuel20._allowancesByOwner[msg.sender].length && i <= fuel20.maxAllowances; i++) {

                if (fuel20._allowancesByOwner[msg.sender][i].spender == spender) {

                    fuel20._allowancesByOwner[msg.sender][i].amount = value;
                    found = true;
                    break;
                }
            }

            if (!found) {

                Allowance memory newAllowance = Allowance({ owner: msg.sender, spender: spender, amount: value });
                fuel20._allowancesByOwner[msg.sender].push(newAllowance);
            }

            // 90% alert notice
            if (senderAllowanceCount * 10 > fuel20.maxAllowances * 9) {

                emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Protocol, Severity.Warning, "approval", senderAllowanceCount, "90% capacity warning");
            }
        }

        return super.approve(spender, value);
    }


    /**
     * _allowancesByOwner retrieves the history of allowances for a specified owner.
     * This private function allows viewing of all allowances set by a specific owner, this function does not track spends.
     *
     * @param __owner address of the owner whose allowances are being queried.
     * @return allowances_ The array of Allowance structs representing the owner's current allowances.
     */
    function _allowancesByOwner(address __owner) private view returns (Allowance[] memory allowances_) {

        // cache allowancesByOwner length (total count of tracked allowances) for gas optimization
        uint _allowancesByOwnerLength = fuel20._allowancesByOwner[__owner].length;

        Allowance[] memory _ownerAllowances = new Allowance[](_allowancesByOwnerLength);

        for (uint i = 0; i < _allowancesByOwnerLength; i++) {

            _ownerAllowances[i] = Allowance(fuel20._allowancesByOwner[__owner][i].owner, fuel20._allowancesByOwner[__owner][i].spender, fuel20._allowancesByOwner[__owner][i].amount);
        }

        return _ownerAllowances;
    }


    /**
     * allowancesByOwner retrieves the history of allowances for a specified owner.
     * This external function allows viewing of all allowances set by a specific owner, this function does not track spends.
     *
     * @param __owner address of the owner whose allowances are being queried.
     * @return allowances_ The array of Allowance structs representing the owner's current allowances.
     */
    function allowancesByOwner(address __owner) external view returns (Allowance[] memory allowances_) {

        return _allowancesByOwner(__owner);
    }


    /**
     * allowances retrieves the history of allowances set by the owner.
     * This external function provides a view of all allowances created and most recent value specified, this function does not track spends.
     *
     * When an approve is committed is is recorded in the allowances array.
     *
     * @return allowances_ The array of Allowance structs representing all current allowances.
     */
    function allowances() external view returns (Allowance[] memory allowances_) {

        return _allowancesByOwner(msg.sender);
    }


    /**
     * _allowanceDecrease safely decreases the allowance for a spender.
     *
     * @param __owner The owner of the tokens.
     * @param __spender The spender of the tokens.
     * @param __amount The amount by which to decrease the allowance.
     * @return success_ True if the operation was successful, False otherwise.
     */
    function _allowanceDecrease(address __owner, address __spender, uint __amount) private returns (bool success_) {

        // when fuel20.maxAllowances is set to 0, allowance tracking functionality is fully disabled
        if (fuel20.maxAllowances < 1) { return false; }

        Allowance[] storage _ownerAllowances = fuel20._allowancesByOwner[__owner];

        for (uint i = 0; i < _ownerAllowances.length; i++) {

            if (_ownerAllowances[i].spender == __spender) {

                if (_ownerAllowances[i].amount < __amount) {

                    // not enough allowance to decrease
                    // return failure w/o reverting
                    return false;
                }

                // decrease allowance amount
                _ownerAllowances[i].amount -= __amount;

                // optionally remove allowance if it hits zero and max allowances are exceeded
                if (_ownerAllowances[i].amount == 0 && _ownerAllowances.length > fuel20.maxAllowances) {

                    // swap & pop
                    if (i != _ownerAllowances.length - 1) {

                        _ownerAllowances[i] = _ownerAllowances[_ownerAllowances.length - 1];
                    }

                    _ownerAllowances.pop();
                }

                // successfully decreased
                return true;
            }
        }

        // no matching allowance found
        // indicate failure w/o revert
        return false;
    }


    /**
     * purgeAllowances purges all tracked allowances.
     * This external function purges both the history of allowances and sets all tracked allowance values to zero (0)
     * preventing the potential loss of funds due to approved allowance abuse.
     *
     * @return allowancesPurgedCount_ The total count of allowances that were purged.
     * @return allowancesClearedTotal_ The total aggregate of FUEL in allowances cleared.
     */
    function purgeAllowances() external nonReentrant returns (uint allowancesPurgedCount_, uint allowancesClearedTotal_) {

        // definitions
        allowancesPurgedCount_ = fuel20._allowancesByOwner[msg.sender].length;

        // zero out known allowances
        for (uint i = 0; i < allowancesPurgedCount_; i++) {

            // sum of all tokens zeroed out
            allowancesClearedTotal_ += fuel20._allowancesByOwner[msg.sender][i].amount;

            // zero out ERC20 storage allowance
            super.approve(fuel20._allowancesByOwner[msg.sender][i].spender, 0);

            // remove allowance record
            delete fuel20._allowancesByOwner[msg.sender][i];
        }

        // reset custom allowance storage for owner
        fuel20._allowancesByOwner[msg.sender] = new Allowance[](0);

        // return total number of allowances purged
        return (allowancesPurgedCount_, allowancesClearedTotal_);
    }


    //
    // INTERNALS
    //

    /**
     * _oracle returns the address of the fabric oracle.
     * This private function provides a view method to access the stored oracle address.
     *
     * @return  oracle_ address of the oracle.
     */
    function _oracle() private view returns (address oracle_) {

        if (custodial.oracle == guardian.oracle || custodial.oracle == executor.oracle) { return custodial.oracle; }
        else if (guardian.oracle == executor.oracle) { return guardian.oracle; }

        return address(0);
    }


    /**
     * _claimMetrixAdd adds fuel20 reward claims for a sender in the FuelFoundry Metrix system.
     * This private function updates the necessary metrics and logs for reward claims.
     *
     * @param  __sender address of the claimant.
     * @param  __reward amount of reward claimed.
     * @return  success_ Returns true upon successful addition of the reward claim.
     */
    function _claimMetrixAdd(address __sender, uint __reward) private returns (bool success_) {

        // if no reward, skip unnecessary writes
        if (__reward > 0) {

            // wallet analytics //

            // total claimed
            fuel20.claimed[__sender] += __reward;

            // claim amount by sender at specific time
            fuel20.claimedAt[__sender][block.timestamp] += __reward;

            // global analytics //

            // total claimed
            fuel20.totalClaimed += __reward;

            // claimed at
            fuel20.totalClaimedAt[block.timestamp] += __reward;
        }

        // callback handling
        return true;
    }


    /**
     * _burnMetrixAdd adds fuel20 burns for a sender in the FuelFoundry Metrix system.
     * This private function updates the necessary metrics and logs for burn accounting.
     *
     * @param  __owner address of the wallet tokens burned from.
     * @param  __amount amount of token burned.
     * @return  success_ Returns true upon successful addition of the burn.
     */
    function _burnMetrixAdd(address __owner, uint __amount) private returns (bool success_) {

        // wallet analytics //

        // total burned
        fuel20.burned[__owner] += __amount;

        // claim amount by sender at specific time
        fuel20.burnedAt[__owner][block.timestamp] += __amount;

        // global analytics //

        // total claimed
        fuel20.totalBurned += __amount;

        // claimed at
        fuel20.totalBurnedAt[block.timestamp] += __amount;

        // callback handling
        return true;
    }


    /**
     * _fuelShield evaluates and applies specific security protocols based on the defined SHIELD.
     * This private function checks the state of various security measures and enforces them accordingly.
     *
     * @param __SHIELD The specific security shield to check and enforce.
     * @return success_ Returns true if the security checks pass without triggering any shields.
     */
    function _fuelShield(SHIELD __SHIELD) private view returns (bool success_) {

        // in order of usage //

        // claimshield - claim disabled
        if (__SHIELD == SHIELD.CLAIM) { require(!fuel20.claimshield, "FFCS"); }

            // mintshield - mint disabled
        else if (__SHIELD == SHIELD.MINT) { require(!fuel20.mintshield, "FFMS"); }

            // stakeshield - stake disabled
        else if (__SHIELD == SHIELD.STAKE) { require(!fuel20.stakeshield, "FFSC"); }

            // burnshield - burn shield
        else if (__SHIELD == SHIELD.BURN) { require(!fuel20.burnshield, "FFBS"); }

        // maintenance mode - independent saftey check for all _fuelShield function calls
        if (fuel20.maintenance) {

            revert("FFMAINT"); // Maintenance mode enabled - Extra features disabled
        }

        // callback handling
        return true;
    }


    //
    // MINTING
    //

    /**
     * _mintCtrl private function to control the minting process of tokens, ensuring compliance with defined security protocols, minting controls, and maximum supply
     * limits. This function is private and can only be called within the contract. It adjusts mint amounts to respect the maximum supply, verifies
     * authorized mint controllers, and enforces minting restrictions.
     *
     * @param __to The address to which tokens will be minted.
     * @param __amount The amount of tokens to be minted, which may be adjusted to not exceed the maximum supply.
     * @return success_ Returns true if the minting operation is successful, or false if any security checks fail or if the caller is not authorized.
     */
    function _mintCtrl(address __to, uint __amount, bool __claim) private returns (bool success_) {
            
        if (fuel20.mintLimiter != 0) { 
        
            // emit an alert if totalsupply exceeds 80% of the mintlimiter
            if (totalSupply() > (fuel20.mintLimiter * 80) / 100) {

                emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Protocol, Severity.Warning, "_mintCtrl", __amount, "80% capacity warning");
            }

            // ensure totalsupply after minting does not exceed mintLimiter
            require(fuel20.mintLimiter >= totalSupply() + __amount, "halt by mintimiter");
        }

        // prohibit if mintshield enabled
        _fuelShield(SHIELD.MINT);

        // top off check
        __amount = _adjustForMaxSupply(__amount);

        // secondary validation firewall
        require (totalSupply() + __amount <= fuel20.maxSupply, "totalsupply+amount>maxsupply");
        require (__to != address(0), "addr0mint!allowed");

        // if not a controller, report
        if(!_isMintControllerEnabled(msg.sender)) {

            // record attempt
            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Protocol, Severity.Alert, "mint", __amount, MSG_FAILED);

            return false;
        } else {
            // is indeed a mint controller...

            // mntdat
            _mint(__to, __amount);

            // reflect reward up in contract
            if (__claim) { _claimMetrixAdd(__to, __amount); }
            
            // emit handled by _mint function
            return true;
        }
    }


    /**
     * mintCtrl external function serves as a controlled entry point for minting tokens.
     * This function may only be called by an authorized controller and is protected against
     * reentrancy attacks. It forwards the minting request to the internal `_mintCtrl` function
     * to execute the minting process with the necessary checks and balances.
     *
     * @param __to The address to which tokens will be minted.
     * @param __amount The amount of tokens to be minted, subject to internal controls and maximum supply limits.
     * @return success_ Returns true if the minting operation is successful, otherwise false.
     */
    function mintCtrl(address __to, uint __amount) external onlyEnabledController nonReentrant returns (bool success_) {

        // mint with claim
        return _mintCtrl(__to, __amount, true);
    }


    /**
     * mint public function for compatibility with ERC20PresetMinterPauser, callable by an authorized controller.
     * This function is protected against reentrancy attacks and delegates the minting process to the internal
     * `_mintCtrl` function, which enforces all necessary controls, security measures, and supply limits.
     * 
     * NOTE: This function format has been intentionally preserved to ensure maximum ABI Compatibility
     * and does not adhere to FuelFoundry design guidelines. 
     * 
     * @param to The address to which tokens will be minted.
     * @param amount The amount of tokens to be minted, subject to internal controls and maximum supply limits.
     */
    function mint(address to, uint256 amount) public onlyEnabledController nonReentrant {

        // mint w/o claim 
        _mintCtrl(to, amount, false);
    }


    //
    // VIRTUALSTAKING
    //

    /**
     * balance retrieves various fuel metrics for the sender's account.
     * This external view function provides comprehensive fuel balance and staking information for the caller.
     *
     * @return balanceUnstakedInEther_ balance (in Ether) of fuel tokens owned by sender.
     * @return balanceUnstaked_ balance in wei of fuel tokens owned by sender.
     * @return balanceStakedInEther_ balance in ether of fuel tokens owned by sender.
     * @return balanceStaked_ amount of fuel tokens staked by sender.
     * @return balanceInTotalInEther_ balance of combined staked and unstaked in ether by sender.
     * @return balanceInTotal_ balance of combined staked and unstaked by sender.

     * @return balanceClaimed_ total amount of fuel claimed in contract.
     * @return balanceBurned_ total amount of fuel burned in contract.
     * @return globalTotalStaked_ total amount of fuel staked in contract.
     * @return globalTotalClaimed_ total amount of fuel claimed from contract.
     * @return globalTotalSupply_ total supply of tokens in circulation.
     * @return globalTotalBurned_ total amount of fuel burned from contract.
     * @return epochTime_ returns the current epoch time.
     */
    function balance() external view returns (
        uint balanceUnstakedInEther_, uint balanceUnstaked_, uint balanceStakedInEther_, uint balanceStaked_, uint balanceInTotalInEther_, uint balanceInTotal_,
        uint balanceClaimed_, uint balanceBurned_, uint globalTotalStaked_, uint globalTotalClaimed_, uint globalTotalSupply_, uint globalTotalBurned_, uint epochTime_) {

        if (super.balanceOf(msg.sender) >= 1 ether) {

            balanceInTotalInEther_ = super.balanceOf(msg.sender) / 1 ether;
        }

        if (balanceOf(msg.sender) >= 1 ether) {

            balanceUnstakedInEther_ = balanceOf(msg.sender) / 1 ether;
        }

        if (fuel20.staked[msg.sender] >= 1 ether) {

            balanceStakedInEther_ = fuel20.staked[msg.sender] / 1 ether;
        }

        return (
            balanceUnstakedInEther_,
            balanceOf(msg.sender),
            balanceStakedInEther_,
            uint(fuel20.staked[msg.sender]),
            balanceInTotalInEther_,
            super.balanceOf(msg.sender),
            uint(fuel20.claimed[msg.sender]),
            uint(fuel20.burned[msg.sender]),
            uint(fuel20.totalStaked),
            uint(fuel20.totalClaimed),
            uint(totalSupply()),
            uint(fuel20.totalBurned),
            block.timestamp
        );
    }


    //
    // FUELMETRIX
    //

    /**
     * totalAt retrieves total stake, claim and burn data for a specific epoch time.
     * This external view function returns the total amounts of claims, stakes, and unstakes at a given epoch time.
     *
     * @param __epochTime epoch time for which to retrieve the data.
     * @return totalClaimedAtEpoch_ total fuel claimed at the specified epoch.
     * @return totalStakedAtEpoch_ total fuel staked at the specified epoch.
     * @return totalUnstakedAtEpoch_ total fuel unstaked at the specified epoch.
     */
    function totalAt(uint __epochTime) external view returns (uint totalClaimedAtEpoch_, uint totalStakedAtEpoch_, uint totalUnstakedAtEpoch_, uint totalBurnedAtEpoch_) {

        return (fuel20.totalClaimedAt[__epochTime],fuel20.totalStakedAt[__epochTime],fuel20.totalUnstakedAt[__epochTime], fuel20.totalBurnedAt[__epochTime]);
    }


    //
    // STAKE | UNSTAKE | CLAIM
    //

    /**
     * _stake handles the logic for virtual staking of tokens.
     * This function manages staking of tokens and calculates rewards.
     *
     * @param  __amount The amount of tokens to stake.
     * @return  reward_ The calculated reward for staking.
     */
    function _stake(uint __amount) private returns (uint reward_) {

        require(__amount >= fuel20.stakeMin, "amt<stakemin");
        require(__amount <= _balanceOf(msg.sender), "amt>balance");
        require(fuel20.stakeClaimedAt[msg.sender] + fuel20.claimCooldown < block.timestamp, "reward cooling");

        // claim any existing rewards
        if (fuel20.stakeClaimedAt[msg.sender] >= fuel20.initAt) {

            reward_ = _claim(msg.sender);
        }

        // update balances and timestamps
        fuel20.staked[msg.sender] += __amount;
        fuel20.stakedAt[msg.sender] = block.timestamp;
        fuel20.stakeClaimedAt[msg.sender] = block.timestamp;

        // Global analytics update
        fuel20.totalStakedAt[block.timestamp] += __amount;
        fuel20.totalStaked += __amount;

        // emit event
        emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Operations, Severity.Informational, "stake", __amount, MSG_SUCCESS); // updating total and balances

        return reward_;
    }


    /**
     * stake allows staking or unstaking of FUEL-20 tokens.
     * This public function enables users to either stake or unstake the specified amount of FUEL-20 tokens, protected against re-entrance.
     *
     * @param __amount amount of FUEL-20 tokens to stake or unstake.
     * @return reward_ reward obtained as a result of staking or unstaking.
     */
    function stake(uint __amount) external nonReentrant returns (uint reward_) {

        // stakeshield
        _fuelShield(SHIELD.STAKE);

        return _stake(__amount);
    }


    /**
     * _unstake handles the logic for virtual unstaking of tokens.
     * This function manages unstaking of all tokens and calculates rewards.
     *
     * @return reward_ The calculated reward for unstaking.
     */
    function _unstake() private returns (uint reward_) {

        uint __amount = fuel20.staked[msg.sender];
        require(__amount > 0, "no tokens to unstake");

        // claim any existing rewards
        if (fuel20.stakeClaimedAt[msg.sender] >= fuel20.initAt) {
            reward_ = _claim(msg.sender);
        }

        // reset account balances
        fuel20.staked[msg.sender] = 0;
        fuel20.stakedAt[msg.sender] = 0;
        fuel20.stakeClaimedAt[msg.sender] = 0;
        fuel20.unstakedAt[msg.sender] = block.timestamp;

        // update global balances
        if (fuel20.totalStaked >= __amount) {

            fuel20.totalStaked -= __amount;
        } else {

            fuel20.totalStaked = 0;
        }

        // global analytics update
        fuel20.totalUnstakedAt[block.timestamp] += __amount;

        // emit event
        emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Operations, Severity.Informational, "unstake", __amount, MSG_SUCCESS);

        return reward_;
    }


    /**
     * unstake allows unstaking of all staked FUEL-20 tokens.
     * This public function enables users to unstake all their previously staked FUEL-20 tokens, protected against re-entrance.
     * The unstaking process uses the _stake function with an amount of zero, indicating a complete unstake of the user's holdings.
     *
     * @return reward_ reward obtained as a result of unstaking.
     */
    function unstake() external nonReentrant returns (uint reward_) {

        return _unstake();
    }


    /**
     * _claim processes a claim or returns the potential reward for the calling user.
     * This private function manages the reward claims within the FUEL-20 system. If cooling from a previous claim, it returns zero but does not block other claims.
     * if claim set to true, process claim, if claim set to false, return reward.
     *
     * @return reward_ reward amount for the claim or zero if still in the cooling period.
     */
    function _claim(address __stakerAddress) private returns (uint reward_) {

        // return 0 if cooling down from previous fuelstake claim as an abort would impede claims partaking in loop operations
        if (fuel20.stakeClaimedAt[__stakerAddress] > block.timestamp - fuel20.claimCooldown) { return 0; }

        // top off or payout
        reward_ = _adjustForMaxSupply(_reward(__stakerAddress));

        // last stake claimed updated ahead of payout
        fuel20.stakeClaimedAt[__stakerAddress] = block.timestamp;

        // mint tokens to sender
        _mint(__stakerAddress, reward_);

        // global analytics
        _claimMetrixAdd(__stakerAddress, reward_);

        return reward_;
    }


    /**
     * claim processes a claim for the calling user and returns the reward.
     *
     * @return reward_ amount of reward claimed.
     */
    function claim() external nonReentrant returns (uint reward_) {

        // claimshield
        _fuelShield(SHIELD.CLAIM);

        // if still cooling down from previous claim
        require(fuel20.stakeClaimedAt[msg.sender] + fuel20.claimCooldown < block.timestamp, "reward cooling");

        // do not attempt claims on 0% APR.
        require(fuel20.stakeAnnualPercentRewardRate >= 1, "APR=0%");

        // temporarily disable claim if totalsupply == maxsupply
        require (totalSupply() < fuel20.maxSupply, "maxsupply in circulation");

        return _claim(msg.sender);
    }


    /**
     * orClaim allows oracle to claim rewards on behalf of a staker.  Minted tokens are sent directly to the staker's address.
     *
     * @param __stakerAddress address of the staker.
     * @return reward_ amount of rewards claimed.
     */
    function orClaim(address __stakerAddress) external onlyOracle nonReentrant returns (uint reward_) {

        // claimshield
        _fuelShield(SHIELD.CLAIM);

        // claim rewards
        reward_ = _claim(__stakerAddress);

        // trap claims
        if (reward_ > 0) {
            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Oracle, Severity.Informational, "orClaim", reward_, "claimed");
        }

        return reward_;
    }


    /**
     * claimedAt retrieves the claimed amount at a specific timestamp for a given sender.
     *
     * @param __owner address of the sender.
     * @param __epochTime timestamp for which to retrieve the claimed amount.
     * @return reward_ claimed amount at the specified timestamp.
     */
    function claimedAt(address __owner, uint __epochTime) public view returns (uint reward_) {

        return (fuel20.claimedAt[__owner][__epochTime]);
    }


    /**
     * burnedAt retrieves total burned tokens by owner at a specific epoch time.
     * This external view function returns the total amounts of burned tokens by owner at a given epoch time.
     *
     * @param __epochTime epoch time for which to retrieve the data.
     * @return burned_ total fuel claimed at the specified epoch.
     */
    function burnedAt(address __owner, uint __epochTime) external view returns (uint burned_) {

        return (fuel20.burnedAt[__owner][__epochTime]);
    }


    //
    // REWARD FUNCTIONS
    //

    /**
     * _reward calculates the self-stake rewards for a given address within the FUEL-20 system.
     * This private view function computes the reward amount based on the staking history of the provided address.
     *
     * @param __address address for which to calculate the staking rewards.
     * @return reward_ calculated reward for the address based on its staking activities.
     */
    function _reward(address __address) private view returns (uint reward_) {

        // failsafe
        if (fuel20.stakeClaimedAt[__address] <= fuel20.initAt) { return 0; }

        uint _timeStakedInSeconds = block.timestamp - fuel20.stakeClaimedAt[__address];

        // ANNUAL_REWARD_RATE = 5 = 5%
        // SECONDS_IN_A_YEAR = 365 * 24 * 60 * 60 == 31536000
        return (fuel20.staked[__address] * fuel20.stakeAnnualPercentRewardRate * _timeStakedInSeconds) / (100 * 31536000);
    }


    /**
     * reward retrieves the current potential reward for the caller based on their staking activities.
     * This external view function returns the reward amount that would be claimed by the calling user.
     *
     * @return reward_ potential reward amount for the calling user based on their staking.
     */
    function reward() external view returns (uint reward_) {

        return _reward(msg.sender);
    }


    /**
     * rewardByOwner calculates and retrieves the potential reward for a specified owner based on their staking activities.
     * This external view function returns the reward amount that would be claimed by the specified owner if they were to initiate a claim.
     * It allows query of rewards for any user, not just the caller, making it useful for interfaces displaying user-specific staking rewards.
     *
     * @param __owner The address of the owner for whom the reward is being calculated.
	 * @return reward_ The potential staking reward amount for the provided owner.
	 */
    function rewardByOwner(address __owner) external view returns (uint reward_) {

        return(_reward(__owner));
    }


    //
    // SUBCHAIN
    //

    /**
     * mintStakerReward mints new tokens to reward subchain validator stakers.
     * This external method is accessible only by controllers and is designed to reward validators with new tokens,
     * ensuring minting operations do not exceed the maximum supply of the token.
     *
     * Precondition checks ensure that:
     * - The account is not the zero address.
     * - The total supply hasn't already reached or exceeded the maximum limit.
     * - The minting amount does not cause the total supply to exceed the maximum limit.
     * Each check is accompanied by a corresponding Trap event for monitoring and logging.
     *
     * @param account The address of the validator staker to receive the reward.
	 * @param amount The amount of tokens to be minted as a reward.
	 * @return True if the tokens are successfully minted, false otherwise.
     */
    function mintStakerReward(address account, uint256 amount) external onlyEnabledController onlyValidator nonReentrant returns (bool) {

        // do not trap and return true if amount = 0
        if (amount == 0) { return true; }

        // deny rewards to zero address
        if (account == address(0x0)) {

            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Protocol, Severity.Alert, "mintStakerReward", 0, "attempt to mint to addr(0)");
            return false;
        }

        // deny if totalsupply has reached or exceeded maxsupply
        if (totalSupply() >= fuel20.maxSupply) {

            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Protocol, Severity.Critical, "mintStakerReward", totalSupply(), "totalsupply reached maxsupply");
            return false;
        }

        // deny if minting amount exceeds maximum supply
        if (totalSupply() + amount > fuel20.maxSupply) {

            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Protocol, Severity.Warning, "mintStakerReward", amount, "mint exceeds maxsupply");
            return false;
        }

        // mint the tokens
        _mint(account, amount);

        // emit handled by _mint function
        return true;
    }


    /**
     * stakerRewardPerBlock returns staker rewards per mainnet block for subchain validators.
     *
     * @return The number of new tokens minted per Main Chain block for the Subchain validator stakers.
     */
    function stakerRewardPerBlock() external view returns (uint) {

        // dynamically disable validator earning slightly ahead of maxSupply
        if (totalSupply() > fuel20.topOffSupply) { return 0; }
        else { return subchain.stakerRewardPerBlock; }
    }


    /**
     * updateStakerRewardPerBlock updates the reward amount per block for Subchain validator stakers.
     *
     * This function allows any governance member during executive session to update the number of new tokens minted
     * per main chain block for Subchain validators. It ensures that the system can adapt to changing conditions
     * or policy updates regarding staking rewards. This function calls `exSubchainStakerRewardPerBlockSet` to
     * apply the new settings.  This function exists to support subchain governance token onboarding with ChainSmith.
     *
     * NOTE: This function is specifically formatted to match the Theta Network Subchain requirements and does not conform
     * to existing FuelFoundry design guidelines.  The format was preserved solely for maximum capability with Subchain operations.
     *
     * @param stakerRewardPerBlock_ The new reward rate to be set per Main Chain block for Subchain validator stakers.
     */
    function updateStakerRewardPerBlock(uint256 stakerRewardPerBlock_) external onlyExecutiveSession onlyGovernance nonReentrant {

        // validate that the proposed reward does not exceed the maximum allowed.
        require(stakerRewardPerBlock_ <= subchain.stakerRewardPerBlockMax, "val>rewardMax");

        // if valid, update the staker reward per block to the new value.
        if (stakerRewardPerBlock_ <= subchain.stakerRewardPerBlockMax) {

            subchain.stakerRewardPerBlock = stakerRewardPerBlock_;
        }

        // emit event
        emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Operations, Severity.Informational, "updateStakerRewardPerBlock", stakerRewardPerBlock_, "new validator staker reward per block set");
    }


    /**
     * _quorumCodeVerify compares provided code with session code for validity.
     *
     * Checks if `__code` matches the session code and hasn't expired. Essential for time-sensitive code verification.
     *
     * @param __code Code for verification.
     * @return verified_ True if code matches and session is active, false if expired or mismatched.
     */
    function _quorumCodeVerify(uint __code) private view returns (bool verified_) {

        if (block.timestamp > exsess.expiresAt) { return false; } // code expired
        else if (_isCodeWithinVariance(__code, exsess.code)) { return true; } //__code == exsess.code) { return true; }

        return false;
    }


    //
    // EXECUTIVE SESSION GOVERNANCE FUNCTIONS
    //

    /**
     * _govAddressUpdate updates the governance addresses for a specific target.
     * This private function updates the custodial, guardian, executor, and oracle addresses in the GovernanceKey struct.
     *
     * @param  target The target governance structure to update.
     * @param  __custodial The new custodial address.
     * @param  __guardian The new guardian address.
     * @param  __executor The new executor address.
     * @param  __oracle The new oracle address.
     */
    function _govAddressUpdate(GovernanceKey storage target, address __custodial, address __guardian, address __executor, address __oracle) private {

        // caller holds a governance role
        if (msg.sender == target.wallet)  {

            // governance role update notification - custodial
            if (target.custodial != __custodial) {

                emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Governance, Severity.Notice, "_govAddressUpdate", uint160(__custodial), string(abi.encodePacked("custodial vote updated to: ", addressToString(__custodial))));
                target.custodial = __custodial;
            }

            // governance role update notification - guardian
            if (target.guardian != __guardian) {

                emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Governance, Severity.Notice, "_govAddressUpdate", uint160(__guardian), string(abi.encodePacked("guardian vote updated to: ", addressToString(__guardian))));
                target.guardian  = __guardian;
            }

            // governance role update notification - executor
            if (target.executor != __executor) {

                emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Governance, Severity.Notice, "_govAddressUpdate", uint160(__executor), string(abi.encodePacked("executor vote updated to: ", addressToString(__executor))));
                target.executor  = __executor;
            }

            // governance role update notification - oracle
            if (target.oracle != __oracle) {

                emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Governance, Severity.Notice, "_govAddressUpdate", uint160(target.wallet), string(abi.encodePacked("oracle vote updated to: ", addressToString(__oracle))));
                target.oracle  = __oracle;
            }
        }
    }


    /**
     * goVoteCast casts vote on behalf of the governance role(s) calling the function, validating non-zero conditions for key roles.
     * This external function updates governance addresses if executed by an authorized role and ensures non-reentrancy.
     * Oracle can be set to zero, indicating disabled state, unlike other addresses.
     *
     * @param  __custodial The new custodial address to be set.
     * @param  __guardian The new guardian address to be set.
     * @param  __executor The new executor address to be set.
     * @param  __oracle The new oracle address to be set; can be zero.
     * @return  success_ Returns true if the operation was successful.
     */
    function goVoteCast(address __custodial, address __guardian, address __executor, address __oracle) external onlyGovernance nonReentrant returns (bool success_) {

        require (__custodial != address(0) && __guardian != address(0) && __executor != address(0), "only oracle may equal address(0) (disabled)");

        if (msg.sender == custodial.wallet) { _govAddressUpdate(custodial, __custodial, __guardian, __executor, __oracle); }
        if (msg.sender == guardian.wallet)  { _govAddressUpdate(guardian,  __custodial, __guardian, __executor, __oracle); }
        if (msg.sender == executor.wallet)  { _govAddressUpdate(executor,  __custodial, __guardian, __executor, __oracle); }

        emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Governance, Severity.Informational, "govSet", 1, "update complete");

        return true;
    }


    /**
     * goMembers retrieves the current active set of governance addresses.
     * This external view function can only be called by an account with governance permissions.
     *
     * @return custodial_ address currently set as the custodial.
     * @return guardian_ address currently set as the guardian.
     * @return executor_ address currently set as the executor.
     * @return oracle_ address currently set as the oracle.
     */
    function goMembers() external view onlyGovernance returns (address custodial_, address guardian_, address executor_, address oracle_) {

        return (custodial.wallet, guardian.wallet, executor.wallet, _oracle());
    }


    /**
     * goElect handles governance role elections.
     *
     * Facilitates election of custodial, guardian, and executor based on governance consensus.
     * The oracle role, determined dynamically, isn't elected.
     * Restricted to execution by the governance contract and protected against reentrancy for security.
     *
     * @return custodial_ Elected custodial address.
     * @return guardian_ Elected guardian address.
     * @return executor_ Elected executor address.
     * @return oracle_ Dynamically determined oracle address.
     */
    function goElect() external onlyGovernance nonReentrant returns (address custodial_, address guardian_, address executor_, address oracle_) {

        address _legacyCustodial = custodial.wallet;
        address _legacyGuardian = guardian.wallet;
        address _legacyExecutor = executor.wallet;

        // elect new custodial
        custodial.wallet = (guardian.custodial == executor.custodial) ? guardian.custodial : custodial.wallet;

        if (_legacyCustodial != custodial.wallet) {

            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Governance, Severity.Informational, "goElect", uint160(custodial.wallet), "Custodial elected");
        }

        // elect new guardian
        guardian.wallet = (custodial.guardian == executor.guardian) ? custodial.guardian : guardian.wallet;

        if (_legacyGuardian != guardian.wallet) {

            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Governance, Severity.Informational, "goElect", uint160(guardian.wallet), "Guardian elected");
        }

        // elect new executor
        executor.wallet = (custodial.executor == guardian.executor) ? custodial.executor : executor.wallet;

        if (_legacyExecutor != executor.wallet) {
            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Governance, Severity.Informational, "goElect", uint160(executor.wallet), "Executor elected");
        }

        // oracle is not executive, is returned dynamically
        return (custodial.wallet, guardian.wallet, executor.wallet, _oracle());
    }


    //
    // EXECUTIVE SESSION CUSTODIAL|GUARDIAN FUNCTIONS
    //

    /**
     * exSessionInit initializes new session code or will provide existing session code if not yet expired.
     *
     * If within session plus cooldown, returns existing code. Otherwise, generates a secure code using blockchain
     * attributes and a seed. Access restricted to specific roles and safeguarded against reentrancy.
     *
     * @return code_ Current or new session code.
     */
    function cgSessionInit() external onlyCustodialGuardian nonReentrant returns (uint code_) {

        // check if the session is still within its cooldown period and return the existing code if true
        if (block.timestamp < exsess.expiresAt + exsess.sessionCooldown) { return (exsess.code); }
        else {

            // last session has expired or closed,
            //generate a new exsess window and code
            exsess.startedAt = block.timestamp;
            exsess.expiresAt = block.timestamp + exsess.sessionMax;

            exsess.code = uint(keccak256(abi.encodePacked(exsess.code + block.number + block.timestamp + block.gaslimit + exsess.seed))) % 10 ** 9;

            return (exsess.code);
        }
    }


    /**
     * cgCodeVerify verifies code against the current executive session code, restricted to custodial/guardian roles only.
     *
     * Calls `_quorumCodeVerify` for code verification under custodial or guardian permissions, does not alter state.
     *
     * @param __code Code for session validation.
     * @return verified_ Outcome of session code comparison.
     */
    function cgCodeVerify(uint __code) external view onlyCustodialGuardian returns (bool verified_) {

        if (exsess.expiresAt < block.timestamp) { return false; }
        else { return (_quorumCodeVerify(__code)); }
    }


    //
    // EXECUTIVE SESSION EXECUTOR FUNCTIONS
    //

    /**
     * goSessionEnter initiates the next executive session by setting its expiration to the current block timestamp + fuel20.sessionMax value.
     * This action effectively activates the session, allowing subsequent actions that depend on the session being active.
     *
     * Access is restricted to ensure only authorized roles, typically custodial, guardian, or executor roles, can enter the session.
     * This is a critical governance function that needs to be protected from reentrancy to maintain state integrity.
     *
     * @param __code The unique session code provided by the actor attempting to initiate the session.
     * @return success_ Boolean indicating whether the session was successfully entered.
     */
    function goSessionEnter(uint __code) external onlyGovernance nonReentrant returns (bool success_) {

        bool custodialVerified = false;
        bool guardianVerified = false;
        bool executorVerified = false;

        // update role code and verify
        if (msg.sender == custodial.wallet) {

            custodial.code = __code;
        }

        if (msg.sender == guardian.wallet) {

            guardian.code = __code;
        }

        if (msg.sender == executor.wallet) {

            executor.code = __code;
        }

        custodialVerified = _quorumCodeVerify(custodial.code);
        guardianVerified = _quorumCodeVerify(guardian.code);
        executorVerified = _quorumCodeVerify(executor.code);

        uint quormCount = (custodialVerified ? 1 : 0) + (guardianVerified ? 1 : 0) + (executorVerified ? 1 : 0);

        // check if two of the three roles verify the code correctly to establish a quorum
        if (quormCount >= 2) {

            // enter executive session
            exsess.expiresAt = block.timestamp + exsess.sessionMax;

            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Governance, Severity.Informational, "exSessionEnter", 1, MSG_SUCCESS);
            return true;
        } else {

            // if no quorum is met, log a failed attempt and record in emit who requested action
            if (quormCount == 0) {

                emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Governance, Severity.Warning, "exSessionEnter", 0, MSG_FAILED); // Failed to enter executive session, verification failed or insufficient quorum
            } else if (quormCount == 1) {

                emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Governance, Severity.Notice, "exSessionEnter", 0, "code accepted, awaiting one other member to enter code");
                return false;
            }
        }
    }


    /**
     * goSessionClose closes the current executive session by setting its expiration to the current block timestamp.
     * This action effectively ends the session, preventing any further actions that depend on the session being active.
     *
     * Access is restricted to ensure only authorized roles (custodial, guardian, executor) may close the session.
     *
     * @return success_ Boolean indicating whether the session was successfully closed.
     */
    function goSessionClose() external onlyExecutiveSession onlyGovernance nonReentrant returns (bool success_) {

        if (msg.sender == custodial.wallet && _quorumCodeVerify(custodial.code)) {

            // close executive session
            exsess.expiresAt = block.timestamp;

            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Governance, Severity.Informational, "exSessionClose", 1, "Closed by custodial");
            return true;
        }

        if (msg.sender == guardian.wallet && _quorumCodeVerify(guardian.code)) {

            // close executive session
            exsess.expiresAt = block.timestamp;

            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Governance, Severity.Informational, "exSessionClose", 1, "Closed by guardian");
            return true;
        }

        if (msg.sender == executor.wallet && _quorumCodeVerify(executor.code)) {

            // close executive session
            exsess.expiresAt = block.timestamp;

            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Governance, Severity.Informational, "exSessionClose", 1, "Closed by executor");
            return true;
        }

        // if no conditions met, log failed attempt and record in emit who requested action
        emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Governance, Severity.Warning, "exSessionClose", 0, MSG_FAILED); // to close executive session, verification failed

        return false;
    }


    /**
     * goSessionExp returns current executive session expiration time and seconds remaining.
     *
     * Externally accessible by all, provides the session's end timestamp and time left in seconds; useful for tracking session activity.
     *
     * @return exsessSecondsRemaining_ Seconds until session ends, negative if expired.
     * @return exsessExpiresAt_ Session end UNIX timestamp.
     */
    function goSessionExp() external view onlyGovernance returns (int256 exsessSecondsRemaining_, uint exsessExpiresAt_) {

        // a positive number of seconds indicates session is open
        // a negative number of seconds indicates the length of time since executive session was last closed
        return (int(exsess.expiresAt) - int(block.timestamp), exsess.expiresAt);
    }


    /**
     * goCurrentState retrieves the current state and session parameters of the governance.
     *
     * This function provides a snapshot of the current blockchain state relevant to the contract,
     * along with the active executive session's details. It is designed to be called by governance
     * roles to obtain real-time data for making informed decisions and tracking session status.
     * Access is restricted to ensure that only authorized governance participants can fetch this sensitive information.
     *
     * @notice Must be called by an authorized governance role due to the `onlyGovernance` modifier.
     *
     * @return currentBlockNumber_ The number of the most recent block.
     * @return currentBlockTime_ The timestamp of the most recent block, equivalent to the current block time.
     * @return currentGasLimit_ The gas limit of the most recent block, which indicates the maximum amount of gas that can be spent on transactions in the block.
     * @return exsessStartedAt_ The start time of the current executive session, indicating when the session was activated.
     * @return exsessExpiresAt_ The expiration time of the current executive session, indicating when the session will automatically end.
     * @return exsessSessionMax_ The maximum number of actions or changes allowed within the current executive session.
     * @return exsessSessionCooldown_ The cooldown period required before a new session can commence after the current session ends.
     */
    function goCurrentState() external onlyGovernance view returns (
        uint currentBlockNumber_,uint currentBlockTime_,uint currentGasLimit_, uint exsessStartedAt_, uint exsessExpiresAt_, uint exsessSessionMax_, uint exsessSessionCooldown_) {

        return (block.number, block.timestamp, block.gaslimit, exsess.startedAt, exsess.expiresAt, exsess.sessionMax, exsess.sessionCooldown);
    }


    /**
     * goGovElects retrieves the addresses of governance positions across custodial, guardian, and executor categories.
     *
     * This function provides a comprehensive view of the governance structure, listing the addresses associated with
     * key roles within custodial, guardian, and executor groups. Each group includes specific roles such as wallet, custodial,
     * guardian, executor, and oracle. This detailed mapping is vital for ensuring transparency and accountability in governance
     * actions, allowing for a clear understanding of role distributions and responsibilities.
     *
     * Access to this function is restricted to accounts with governance permissions, ensuring that the sensitive structure
     * of governance roles is protected from unauthorized access. As a `view` function, it does not modify the blockchain state,
     * maintaining the integrity of the governance framework while providing essential insights.
     *
     * The data returned is crucial for overseeing the governance landscape, enabling effective monitoring and strategic
     * decision-making within the governance framework.
     *
     * @return custodial_wallet_ Address of the wallet role of the custodial.
     * @return custodial_custodial_ Address of the custodial role of the custodial.
     * @return custodial_guardian_ Address of the guardian role of the custodial.
     * @return custodial_executor_ Address of the executor role of the custodial.
     * @return custodial_oracle_ Address of the oracle role of the custodial.
     * @return guardian_wallet_ Address of the wallet role of the guardian.
     * @return guardian_custodial_ Address of the custodial role of the guardian.
     * @return guardian_guardian_ Address of the guardian role of the guardian.
     * @return guardian_executor_ Address of the executor role of the guardian.
     * @return guardian_oracle_ Address of the oracle role of the guardian.
     * @return executor_wallet_ Address of the wallet role of the executor.
     * @return executor_custodial_ Address of the custodial role of the executor.
     * @return executor_guardian_ Address of the guardian role of the executor.
     * @return executor_executor_ Address of the executor role of the executor.
     * @return executor_oracle_ Address of the oracle role of the executor.
     */
    function goGovElects() external onlyGovernance view returns (
        address custodial_wallet_, address custodial_custodial_, address custodial_guardian_, address custodial_executor_, address custodial_oracle_,
        address  guardian_wallet_, address  guardian_custodial_, address  guardian_guardian_, address  guardian_executor_, address  guardian_oracle_,
        address  executor_wallet_, address  executor_custodial_, address  executor_guardian_, address  executor_executor_, address  executor_oracle_) {

        return (custodial.wallet, custodial.custodial, custodial.guardian, custodial.executor, custodial.oracle,
            guardian.wallet,  guardian.custodial,  guardian.guardian,  guardian.executor,  guardian.oracle,
            executor.wallet,  executor.custodial,  executor.guardian,  executor.executor,  executor.oracle);
    }


    /**
     * _isCodeWithinVariance checks if two codes are within a specified variance.
     *
     * This function evaluates whether the difference between `code1` and `code2` is within a tolerance of 100 units.
     * It is useful for scenarios where exact matches are not required, but close approximations are acceptable, enhancing
     * the flexibility and robustness of code comparison operations.
     *
     * @param code1 The first code for comparison.
	 * @param code2 The second code for comparison.
	 * @return True if the codes are within 100 units of each other, otherwise false.
	 */
    function _isCodeWithinVariance(uint code1, uint code2) private pure returns (bool) {

        return (code1 <= code2 + 100) && (code1 >= code2 - 100);
    }


    /**
     * _inSession returns active status of executive session based on expiry and code consensus.
     *
     * Active if not expired and two of three roles (custodial, guardian, executor) agree on session code within a variance of 100.
     * This allows for minor discrepancies in the codes, enhancing robustness.
     * Called by onlyExecutiveSession modifier, may also be called upon by other functions.
     * @return inSession_ True if active, false if expired or no quorum.
	 */
    function _inSession() private view returns (bool inSession_) {

        // check if the session is not expired
        if (exsess.expiresAt > block.timestamp) {

            // determine if a quorum is established based on code agreement within a variance of 100
            uint agreeCount = 0;

            if (_isCodeWithinVariance(custodial.code, exsess.code)) { agreeCount++; }
            if (_isCodeWithinVariance(guardian.code,  exsess.code)) { agreeCount++; }
            if (_isCodeWithinVariance(executor.code,  exsess.code)) { agreeCount++; }

            return (agreeCount >= 2);
        }

        // return false if the session has expired or if there's no quorum
        return false;
    }


    /**
     * inSession returns active status of executive session based on expiry and code consensus.
     *
     * Active if not expired and two of three roles (custodial, guardian, executor) agree on session code. Public and state-unaltering.
     * Called by onlyExecutiveSession modifier, may also be called upon by
     * @return inSession_ True if active, false if expired or no quorum.
     */
    function inSession() public view returns (bool inSession_) {

        return _inSession();
    }


    /**
     * exGlobalSet updates key system parameters, restricted to the executor.
     *
     * Adjusts staking rewards, fuel ID, minimum stake, claim cooldown, and max allowances with safety caps. Ensures parameters stay within safe limits. Protected against reentrancy.
     *
     * @param _fuelId Fuel resource identifier.
     * @param _stakeMin Minimum staking amount.
     * @param _claimCooldownInSeconds Cooldown for reward claims.
     * @param _stakeAnnualPercentRewardRate Annual staking reward rate.
     * @param _maxAllowances Maximum allowances, capped at 1000 for gas efficiency.
     * @return fuelId_ Updated fuel ID, reflecting the new or unchanged value.
     * @return stakeMin_ Updated minimum stake amount, reflecting the new or unchanged value.
     * @return claimCooldownInSeconds_ Updated claim cooldown in seconds, reflecting the new or unchanged value.
     * @return stakeAnnualPercentRewardRate_ Updated annual staking reward rate, reflecting the new or unchanged value.
     * @return maxAllowances_ Updated maximum allowances per address, reflecting the new or unchanged value.
     */
    function exGlobalSet(uint80 _fuelId, uint _stakeMin, uint _claimCooldownInSeconds, uint _stakeAnnualPercentRewardRate, uint _maxAllowances) external onlyExecutiveSession onlyExecutor nonReentrant returns (
        uint80 fuelId_, uint stakeMin_, uint claimCooldownInSeconds_, uint stakeAnnualPercentRewardRate_, uint maxAllowances_) {

        // fuelId must be greater than 0, update fuel ID if different from the current value and log change.
        if (_fuelId > 0 && fuel20.fuelId != _fuelId) {

            fuel20.fuelId = _fuelId;
            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Executive, Severity.Informational, "exGlobalSet", _fuelId, "fuelId updated");
        }

        // stakeMin must be greater than 0, failsafe: update minimum stake (in wei) if different from the current value and log change.
        if (_stakeMin > 0 && fuel20.stakeMin != _stakeMin) {

            fuel20.stakeMin = _stakeMin < 1 ether ? 1 ether : _stakeMin;
            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Executive, Severity.Informational, "exGlobalSet", _stakeMin, "minimum stake amount updated");
        }

        // failsafe: update and log changes to claim cooldown, if claim cooldown is set greater than 1-hour, lower to 1-hour.
        if (fuel20.claimCooldown != _claimCooldownInSeconds) {

            fuel20.claimCooldown = _claimCooldownInSeconds > 3600 ? 3600 : _claimCooldownInSeconds;
            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Executive, Severity.Informational, "exGlobalSet", fuel20.claimCooldown, "claim cooldown updated");
        }

        // failsafe: update annual percent reward rate if different from the current value and log change, if stakeAPR is set greater than 10000, lower to 10000.
        if (fuel20.stakeAnnualPercentRewardRate != _stakeAnnualPercentRewardRate) {

            fuel20.stakeAnnualPercentRewardRate = _stakeAnnualPercentRewardRate > 10000 ? 10000 : _stakeAnnualPercentRewardRate;
            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Executive, Severity.Informational, "exGlobalSet", _stakeAnnualPercentRewardRate, "stake annual percent reward rate updated");
        }

        // failsafe: update and log max allowances, if maxAllowances is set greater than 1000, lower to 1000 to keep gas operations reasonable.
        if (fuel20.maxAllowances != _maxAllowances) {

            fuel20.maxAllowances = _maxAllowances > 1000 ? 1000 : _maxAllowances;
            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Executive, Severity.Informational, "exGlobalSet", _maxAllowances, "maximum allowances per address update");
        }

        return (fuel20.fuelId, fuel20.stakeMin, fuel20.claimCooldown, fuel20.stakeAnnualPercentRewardRate, fuel20.maxAllowances);
    }


    /**
     * exShieldSet toggles system shields and maintenance mode.
     *
     * Executor-controlled function to adjust operation shields (mint, burn, stake, claim) and maintenance status. Ensures system responsiveness to security needs or operational updates. Guarded for executor-only access and against reentrancy.
     *
     * @param _maintenance Toggles maintenance mode.
     * @param _mintshield Toggles minting operations.
     * @param _burnshield Toggles burning operations.
     * @param _stakeshield Toggles staking operations.
     * @param _claimshield Toggles claiming operations.
     */
    function exShieldSet(bool _claimshield, bool _mintshield, bool _stakeshield, bool _burnshield, bool _maintenance) external onlyExecutiveSession onlyExecutor nonReentrant returns (bool success_) {

        if (fuel20.claimshield != _claimshield) {

            fuel20.claimshield = _claimshield;
            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Operations, Severity.Notice, "exShieldSet", _claimshield ? 1 : 0, "claimshield updated");
        }

        if (fuel20.mintshield != _mintshield) {

            fuel20.mintshield = _mintshield;
            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Operations, Severity.Notice, "exShieldSet", _mintshield ? 1 : 0, "mintsshield updated");
        }

        if (fuel20.stakeshield != _stakeshield) {

            fuel20.stakeshield = _stakeshield;
            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Operations, Severity.Notice, "exShieldSet", _stakeshield ? 1 : 0, "stakeshield updated");
        }

        if (fuel20.burnshield != _burnshield) {

            fuel20.burnshield = _burnshield;
            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Operations, Severity.Notice, "exShieldSet", _burnshield ? 1 : 0, "burnshield updated");
        }

        if (fuel20.maintenance != _maintenance) {

            fuel20.maintenance = _maintenance;
            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Operations, Severity.Notice, "exShieldSet", _maintenance ? 1 : 0, "maintenance mode updated");
        }

        return true;
    }


    /**
     * _isMintController checks if address is authorized for minting.
     *
     * Scans mint controller addresses to confirm if given address has mint permissions, used to validate minting actions within the contract.
     *
     * @param __controller Address to verify.
     * @return True if authorized as a mint controller, false otherwise.
     */
    function _isMintController(address __controller) private view returns (bool) {

        // cache mint controller length for gas optimization
        uint _mintControllersLength = mintControllers.length;

        // iterate over all registered mint controllers
        for (uint i = 0; i < _mintControllersLength; i++) {

            // check if the current controller matches the specified address and is enabled if found
            if (mintControllers[i].contractAddress == __controller) {

                // return true if a match is found
                return true;
            }
        }

        // return false if no match is found
        return false;
    }


    /**
     * _isMintControllerEnabled checks if a controller is authorized and enabled for minting.
     *
     * Iterates mint controllers to verify if an address is authorized and enabled, supporting dynamic control of minting permissions.
     *
     * @param __controller Address to check.
     * @return True if the address is an enabled mint controller, false otherwise.
     */
    function _isMintControllerEnabled(address __controller) private view returns (bool) {

        // cache mint controller length for gas optimization
        uint _mintControllersLength = mintControllers.length;

        // iterate through the list of mint controllers
        for (uint i = 0; i < _mintControllersLength; i++) {

            // check if the controller matches the address and is enabled
            if (mintControllers[i].contractAddress == __controller && mintControllers[i].enabled) {

                // return true if both conditions are met
                return true;
            }
        }

        // return false if no matching, enabled controller is found
        return false;
    }


    /**
     * exMintCtrlGet retrieves the status of a specified controller as a mint controller.
     *
     * This external view function is accessible only by the executor and is designed to check if a given
     * address is recognized as a mint controller within the system, and if so, whether it is currently enabled.
     * It leverages private functions `_isMintController` and `_isMintControllerEnabled` to ascertain the
     * controller's status. This method of querying controller status enables the executor to make informed
     * decisions regarding minting permissions and to manage the list of controllers effectively. The function
     * returns two boolean values indicating whether the controller exists and whether it is enabled, providing
     * clear, actionable information.
     *
     * @param __controller The address of the controller to query.
     * @return exists_ True if the controller is a mint controller, false otherwise.
     * @return enabled_ True if the controller is enabled, false otherwise.
     */
    function exMintCtrlGet(address __controller) external view onlyExecutiveSession onlyExecutor returns (bool exists_, bool enabled_) {

        // check if address is a mint controller
        if (_isMintController(__controller)) {

            // if so, return true and check if it's enabled
            return (true, _isMintControllerEnabled(__controller));
        } else {

            // if not a controller, return false for both exists_ and enabled_
            return (false, false);
        }
    }


    /**
     * exMintCtrlAdd adds a new controller to the list of mint controllers.
     *
     * This function allows the executor to add a new minting controller to the system, enhancing the
     * flexibility and scalability of minting operations. Before adding a new controller, it performs
     * several validations: it checks the controller is not already listed, and verifies the executor's
     * code through `_quorumCodeVerify` to ensure the action is authorized and legitimate. The new controller
     * is initially added in a disabled state, allowing for subsequent activation in a controlled manner.
     * This process is protected by the `onlyExecutor` modifier to restrict this capability to the executor
     * role, and the `nonReentrant` modifier to prevent reentrancy vulnerabilities.
     *
     * Emits a Trap event with details of the action taken.
     *
     * @param __controller The address of the new controller to be added.
     */
    function exMintCtrlAdd(address __controller) external onlyExecutiveSession onlyExecutor nonReentrant returns (bool success_) {

        // confirm the operation is authorized
        require(_quorumCodeVerify(executor.code), "quorm code invalid");

        // validate that the controller does not already exist
        require(!_isMintController(__controller), "ctrl exists");

        // cap max controllers to MAX_MINT_CONTROLLERS (default: 1000)
        require(mintControllers.length < MAX_MINT_CONTROLLERS, "maxctrls reached");

        // define and add new controller in disabled state
        MintController memory _newController = MintController({
            enabled: false,
            contractAddress: __controller
        });

        emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Executive, Severity.Notice, "exMintCtrlAdd", uint160(__controller), MSG_SUCCESS); // controller added

        mintControllers.push(_newController);

        return true;
    }


    /**
     * exMintCtrlSet assigns a new controller or updates existing controller state.
     *
     * This function manages access control of controllers within the contract,
     * enabling or disabling a controller's privileges. The changes are recorded
     * on the blockchain for transparency. It can only be called by members of
     * the 'fabric' (as indicated by the onlyFabric modifier). The function
     * checks if the specified controller is in the array of controllers before
     * updating its state.
     *
     * Emits a Trap event with details of the action taken.
     *
     * @param __controller The address of the controller to be updated.
     * @param __enabled A boolean indicating whether to enable (true) or disable (false) the controller.
     */
    function exMintCtrlSet(address __controller, bool __isValidator, bool __enabled) external onlyExecutiveSession onlyCustodialGuardian nonReentrant returns (address controller_, bool isValidator_, bool enabled_) {

        // cache mint controller length for gas optimization
        uint _mintControllersLength = mintControllers.length;

        //bool _isControllerPresent = false;

        for (uint i = 0; i < _mintControllersLength; i++) {

            // if matching controller found
            if (__controller == mintControllers[i].contractAddress) {

               // _isControllerPresent = true;

                if (!mintControllers[i].enabled && __enabled) {

                    emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Governance, Severity.Notice, "exMintCtrlSet", uint160(mintControllers[i].contractAddress), "controller enabled");
                } else if (mintControllers[i].enabled && !__enabled) {

                    emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Governance, Severity.Notice, "exMintCtrlSet", uint160(mintControllers[i].contractAddress), "controller disabled");
                }

                mintControllers[i].enabled = __enabled;

                if (__isValidator == true && isValidator[__controller] == false) {

                    isValidator[__controller] = __isValidator;

                    emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Governance, Severity.Notice, "exMintCtrlSet", uint160(mintControllers[i].contractAddress), "validator enabled");
                } else if (__isValidator == false && isValidator[__controller] == true) {

                    isValidator[__controller] = __isValidator;

                    emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Governance, Severity.Notice, "exMintCtrlSet", uint160(mintControllers[i].contractAddress), "validator enabled");
                } 

                return (mintControllers[i].contractAddress, isValidator[__controller], mintControllers[i].enabled);
            }
        }

        revert("ctrl not found, add ctrl first");
    }


    /**
     * exMintCtrlDel removes a specified controller from the list of authorized mint controllers.
     *
     * This function enables Executor to remove an existing mint controller from the system. It checks for the existence of the controller address in the list of mint controllers
     * and validates the operation through `_quorumCodeVerify` to confirm removal is authorized. The specified controller
     * is then located in the array of controllers and removed by replacing it with the last controller in the list
     * and then popping the last element, efficiently maintaining the integrity of the list. This action is safeguarded
     * by the `onlyExecutor` modifier to ensure that only the executor can execute this function, and `nonReentrant` to
     * protect against reentrancy attacks. If the controller is not found, the function reverts the transaction.
     *
     * Emits a Trap event with details of the action taken.
     *
     * @param __controller The address of the controller to be removed.
     */
    function exMintCtrlDel(address __controller) external onlyExecutiveSession onlyExecutor nonReentrant returns (bool success_) {

        // confirm the operation is authorized
        require(_quorumCodeVerify(executor.code),  "quorm code invalue");

        // verify the controller exists before attempting removal
        require(_isMintController(__controller), "ctrl does not exist");

        // cache mint controller length for gas optimization
        uint _mintControllersLength = mintControllers.length;

        // iterate through the mint controllers to find and remove the specified controller
        for (uint i = 0; i < _mintControllersLength; i++) {

            if (mintControllers[i].contractAddress == __controller) {

                // emit controller deletion
                emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Governance, Severity.Notice, "exMintCtrlDel", uint160(mintControllers[i].contractAddress), MSG_SUCCESS); // controller deleted

                // replace the controller to be removed with the last controller in the list
                mintControllers[i] = mintControllers[_mintControllersLength - 1];

                // remove the last controller from the list
                mintControllers.pop();

                // deregister validator if set
                if (isValidator[__controller] == true) { isValidator[__controller] = false; }
                
                return true;
            }
        }

        // if the specified controller is not found, revert the transaction
        revert("ctrl not found");
    }


    /**
     * exMintLimiterSet Sets the maximum cap for total supply in Wei, enforcing a mint limit for the contract.
     * @dev This function can only be called by an executor in an executive session and is non-reentrant.
     * It assigns a new mint limiter using the provided cap (in Wei).
     * @param __mintLimiterInWei The maximum supply cap in Wei.
     * @return mintLimiterInWei_ The updated mint limiter in Wei.
     */
    function exMintLimiterSet(uint __mintLimiterInWei) external onlyExecutiveSession onlyExecutor nonReentrant returns (uint mintLimiterInWei_) {

        // Assign mintLimiter
        fuel20.mintLimiter = __mintLimiterInWei;

        // Return the updated mint limiter
        return fuel20.mintLimiter;
    }


    //
    // GETS (PUBLIC) | DMPS (FABRIC GETS)
    //

    /**
     * cgSessionState retrieves detailed information about the current executive session.
     *
     * This function provides a comprehensive view of the executive session's current state,
     * including its unique code, seed value, start time, expiry time, maximum session limit, and cooldown period.
     * This snapshot is essential for governance operations to ensure decisions are made within the context
     * of active session parameters, enhancing the control and execution of governance protocols.
     *
     * Only accounts with governance permissions can access this data, safeguarding sensitive session
     * information from unauthorized access. As a `view` function, it does not modify the blockchain state,
     * ensuring its execution is safe and non-disruptive.
     *
     * The data returned is crucial for monitoring and managing the dynamics of executive sessions within
     * the governance framework, facilitating informed decision-making and effective governance oversight.
     *
     * @return code_ The unique code identifier for the session.
     * @return seed_ The seed value associated with the session for generating deterministic outcomes.
     * @return startedAt_ The blockchain timestamp when the session started.
     * @return expiresAt_ The blockchain timestamp when the session is set to expire.
     * @return sessionMax_ The maximum allowed number of actions or changes within this session.
     * @return sessionCooldown_ The required cooldown period before a new session can commence after this one ends.
     */
    function cgSessionState() external onlyCustodialGuardian view returns (
        uint code_, uint seed_, uint startedAt_, uint expiresAt_, uint sessionMax_, uint sessionCooldown_) {

        return(exsess.code, exsess.seed, exsess.startedAt, exsess.expiresAt, exsess.sessionMax, exsess.sessionCooldown);
    }


    /**
     * lsFabric returns the current configuration and statistical variables of the fuel20 contract for transparency.
     *
     * This function is designed to provide a comprehensive view of the fabric's operational variables,
     * offering insights into both configuration settings and real-time statistics of the contract. By
     * exposing these variables, it supports transparency and allows for informed interactions with the
     * contract. This is especially useful for understanding the contract's state, including staking
     * mechanics, supply metrics, and security features.
     *
     * The function is marked as `external` and `view`, indicating that it is intended to be called from
     * outside the contract and does not modify the contract state. This ensures that it can be freely
     * called (in most cases) to obtain information without incurring gas fees.
     *
     * @return fuelId_ FuelFoundry MetaForge unique identifier for tying data back into FuelMetrix.
     * @return initAt_ Initialization timestamp of the contract.
     * @return maxAllowances_ The maximum number of allowances per owner.
     * @return stakeMinInWei_ The minimum stake required (in wei).
     * @return claimCooldownInSeconds_ The cooldown period for claiming rewards.
     * @return stakeAnnualPercentRewardRate_ The annual percentage rate for staking rewards.
     * @return totalSupply_ The total supply of existing tokens in circulation.
     * @return maxSupply_ The maximum supply of tokens.
     * @return topOffSupply_ The supply top-off value.
     * @return mintLimiter_ Virtual totalsupply mint cap for regulating mint controllers.
     * @return maintenance_ Indicates if the contract is in maintenance mode.
     * @return mintshield_ Indicates if the minting shield is active.
     * @return burnshield_ Indicates if the burning shield is active.
     * @return stakeshield_ Indicates if the staking shield is active.
     * @return claimshield_ Indicates if the claiming shield is active.
     */
    function lsFabric() external view returns (
        uint80 fuelId_, uint initAt_, uint maxAllowances_, uint stakeMinInWei_, uint claimCooldownInSeconds_,
        uint stakeAnnualPercentRewardRate_, uint totalSupply_, uint maxSupply_, uint topOffSupply_, uint mintLimiter_,
        bool maintenance_, bool mintshield_, bool burnshield_, bool stakeshield_, bool claimshield_
    ) {

        return (
            fuel20.fuelId, fuel20.initAt, fuel20.maxAllowances, fuel20.stakeMin, fuel20.claimCooldown,
            fuel20.stakeAnnualPercentRewardRate, totalSupply(), fuel20.maxSupply, fuel20.topOffSupply, fuel20.mintLimiter,
            fuel20.maintenance, fuel20.mintshield, fuel20.burnshield, fuel20.stakeshield, fuel20.claimshield
        );
    }


    /**
     * lsMintCtrls retrieves the current list of mint controllers within the contract.
     *
     * This external view function provides access to the complete array of MintController structs,
     * allowing calling entities to view the active controllers and their statuses.
     *
     * @return mintControllers_ An array representing all the controllers currently configured in the contract.
	 */
    function lsMintCtrls() external view returns (MintController[] memory mintControllers_) {

        return (mintControllers);
    }


    /**
     * _nonce generates a nonce for transaction or operation identification.
     *
     * This private function is responsible for generating a unique identifier (nonce) for use in
     * various contract operations that require a unique or sequential value. The nonce is managed
     * within the fuel20 contract's state, ensuring that each call to this function returns a unique
     * value by incrementing the current nonce.
     *
     * To prevent the nonce from exceeding the maximum value for a uint type, this function checks if
     * the nonce has reached the maximum value. If it has not, the function increments and returns the
     * nonce. If the maximum value is reached, the function resets the nonce to 0, starting the cycle
     * over. This reset mechanism ensures continuous operation without interruption.
     *
     * @return nonce_ The newly generated nonce value.
     */
    function _nonce() private returns (uint nonce_) {

        if   (fuel20.nonce < type(uint).max) {

            fuel20.nonce++;
            return fuel20.nonce;
        } else {

            fuel20.nonce=0;
            return 0;
        }
    }


    /**
     * nonce is a publicly accessible function that generates a nonce.
     *
     * This function serves as an external interface to the private `_nonce` function, allowing
     * external callers to generate a nonce. The generated nonce can be used for various purposes,
     * including but not limited to, transaction identification, operation ordering, or as part of a
     * security mechanism to prevent replay attacks.
     *
     * @return nonce_ The generated nonce value, obtained by invoking the private `_nonce` function.
     */
    function nonce() public onlyGovernance nonReentrant returns (uint nonce_) {

        return (_nonce());
    }


    /**
     * nonceLast returns the latest nonce used in the fuel20 contract.
     *
     * This function provides external access to the current nonce value, facilitating
     * tracking and validation of unique operations or transactions within the contract.
     *
     * @return nonce_ The current nonce value in the fuel20 contract.
     */
    function nonceLast() external view returns (uint nonce_) {

        return (fuel20.nonce);
    }


    /**
     * maxSupply externally accessible function that returns the maximum supply of tokens.
     *
     * This function provides public access to the `maxSupply` variable of the fuel20 contract,
     * enabling external entities and contracts to query the maximum number of tokens that can
     * be minted or generated within the ecosystem.
     *
     * @return maxSupply_ The maximum supply of tokens defined in the fuel20 contract.
     */
    function maxSupply() external view returns (uint maxSupply_) {

        return fuel20.maxSupply;
    }


    /**
     * _adjustForMaxSupply adjusts the minting amount to ensure that the total token supply does not exceed the predefined maximum supply limit.
     *
     * This private function is designed to prevent the total token supply from surpassing the maximum allowable supply (fuel20.maxSupply).
     * It calculates the available room left to reach the max supply by subtracting the current total supply from the maximum supply limit.
     *
     * If the requested mint amount exceeds the available room, the function adjusts the mint amount down to exactly fill to the max supply.
     * This prevents any overflow beyond the max supply. Alternatively, if the requested amount is within the available room,
     * it permits minting of the original requested amount.
     *
     * @param __amount The intended mint amount proposed for addition to the total supply.
     * @return adjustedAmount_ Returns the adjusted mint amount that conforms to the maximum supply constraints. If no adjustment is needed,
     * it returns the original __amount proposed.
     */
    function _adjustForMaxSupply(uint __amount) private returns (uint adjustedAmount_) {

        // calculate remaining room until maxSupply is reached
        uint availableAmount = fuel20.maxSupply - totalSupply();

        if (__amount > availableAmount) {

            // amount to mint would overflow maxSupply, adjust it to fill to maxSupply exactly
            adjustedAmount_ = availableAmount;

            // emit notification about the adjustment
            emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Protocol, Severity.Notice, "_adjustForMaxSupply", adjustedAmount_, "invoked");
        } else {

            // no adjustment needed, use the original amount
            adjustedAmount_ = __amount;
        }

        // return the possibly adjusted mint amount
        return adjustedAmount_;
    }

    //
    // FUELTOOLS
    //

    /**
     * addressToString converts an Ethereum address to its string representation.
     * This function takes an address and converts it into a human-readable hexadecimal string prefixed with "0x".
     * It is useful for encoding addresses for events or logging purposes where a string format is more readable or required.
     *
     * @param _addr The Ethereum address to be converted to a string.
     * @return The string representation of the address, including leading "0x" followed by the 40 hexadecimal characters.
     */
    function addressToString(address _addr) internal pure returns (string memory) {

        bytes32 value = bytes32(uint256(uint160(_addr)));
        bytes memory alphabet = "0123456789abcdef";
        bytes memory str = new bytes(42);

        str[0] = '0';
        str[1] = 'x';

        for (uint i = 0; i < 20; i++) {

            str[2+i*2] = alphabet[uint8(value[i + 12] >> 4)];
            str[3+i*2] = alphabet[uint8(value[i + 12] & 0x0f)];
        }

        return string(str);
    }


    /**
     * orWithdrawERC20 withdraws ERC-20 tokens sent to this contract, to the oracle address.
     *
     * The function directly transfers the specified amount of ERC-20 tokens to the oracle's address. This function is
     * specifically for ERC-20 tokens, not for native tokens or other types of assets that may be held by the contract.
     *
     * *** Use with extreme caution *** If the token contract is not published, do NOT use this tool. ***
     *
     * @param tokenAddress The address of the ERC-20 token contract.
     * @param amount The amount of tokens to be withdrawn.
     */
    function orWithdrawERC20(address tokenAddress, uint256 amount) external onlyOracle nonReentrant {

        require(IERC20(tokenAddress).transfer(_oracle(), amount), "tx failed");
    }

    //
    // NATIVE TOKEN HANDLING
    //

    /**
     * orWithdrawEther withdraws native tokens sent to this contract, to a oracle address.
     *
     * The function directly transfers the specified amount of native token to the caller's address. This is strictly for native token,
     * not for ERC-20 tokens or other types of assets that might be held by the contract.
     *
     * @param amount The amount of native token (in wei) to be withdrawn from the contract.
     */
    function orWithdrawEther(uint256 amount) external onlyOracle nonReentrant {

        payable(_oracle()).transfer(amount);
    }


    /**
     * receive permits receiving native tokens with no data, with the addition of nonReentrant and emit.
     *
     * This external payable function is designed to accept native token transfers without additional data.
     */
    receive() external payable nonReentrant {

        emit Trap(_nonce(), block.timestamp, msg.sender, Facility.Operations, Severity.Alert, "receive", msg.value, "native token received");
    }


    /**
     * fallback reverts unexpected transactions and data sent to the contract.
     *
     * This external payable fallback function is triggered when a call to the contract does not match any functions
     * or when Ether is sent with data. It logs such interactions using the `revert` below.
     *
     * This function is intentionally made non-reentrant for security reasons,
     * even though it always reverts. This is to maintain a high standard of security
     * practices across all contract functions that might be sensitive.
     */
    fallback() external payable {

        revert("Close, but no cigar...");
    }
}
设置
{
  "compilationTarget": {
    "pogs_escaped.sol": "PogToken"
  },
  "evmVersion": "cancun",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 420
  },
  "remappings": [],
  "viaIR": true
}
ABI
[{"inputs":[{"internalType":"uint80","name":"__fuelId","type":"uint80"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":true,"internalType":"address","name":"origin","type":"address"},{"indexed":true,"internalType":"enum PogToken.Facility","name":"facility","type":"uint8"},{"indexed":true,"internalType":"enum PogToken.Severity","name":"severity","type":"uint8"},{"indexed":false,"internalType":"string","name":"application","type":"string"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"string","name":"message","type":"string"}],"name":"Trap","type":"event"},{"stateMutability":"payable","type":"fallback"},{"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":[],"name":"allowances","outputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct PogToken.Allowance[]","name":"allowances_","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"__owner","type":"address"}],"name":"allowancesByOwner","outputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct PogToken.Allowance[]","name":"allowances_","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"balance","outputs":[{"internalType":"uint256","name":"balanceUnstakedInEther_","type":"uint256"},{"internalType":"uint256","name":"balanceUnstaked_","type":"uint256"},{"internalType":"uint256","name":"balanceStakedInEther_","type":"uint256"},{"internalType":"uint256","name":"balanceStaked_","type":"uint256"},{"internalType":"uint256","name":"balanceInTotalInEther_","type":"uint256"},{"internalType":"uint256","name":"balanceInTotal_","type":"uint256"},{"internalType":"uint256","name":"balanceClaimed_","type":"uint256"},{"internalType":"uint256","name":"balanceBurned_","type":"uint256"},{"internalType":"uint256","name":"globalTotalStaked_","type":"uint256"},{"internalType":"uint256","name":"globalTotalClaimed_","type":"uint256"},{"internalType":"uint256","name":"globalTotalSupply_","type":"uint256"},{"internalType":"uint256","name":"globalTotalBurned_","type":"uint256"},{"internalType":"uint256","name":"epochTime_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"__owner","type":"address"},{"internalType":"uint256","name":"__epochTime","type":"uint256"}],"name":"burnedAt","outputs":[{"internalType":"uint256","name":"burned_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"__code","type":"uint256"}],"name":"cgCodeVerify","outputs":[{"internalType":"bool","name":"verified_","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cgSessionInit","outputs":[{"internalType":"uint256","name":"code_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cgSessionState","outputs":[{"internalType":"uint256","name":"code_","type":"uint256"},{"internalType":"uint256","name":"seed_","type":"uint256"},{"internalType":"uint256","name":"startedAt_","type":"uint256"},{"internalType":"uint256","name":"expiresAt_","type":"uint256"},{"internalType":"uint256","name":"sessionMax_","type":"uint256"},{"internalType":"uint256","name":"sessionCooldown_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claim","outputs":[{"internalType":"uint256","name":"reward_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"__owner","type":"address"},{"internalType":"uint256","name":"__epochTime","type":"uint256"}],"name":"claimedAt","outputs":[{"internalType":"uint256","name":"reward_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint80","name":"_fuelId","type":"uint80"},{"internalType":"uint256","name":"_stakeMin","type":"uint256"},{"internalType":"uint256","name":"_claimCooldownInSeconds","type":"uint256"},{"internalType":"uint256","name":"_stakeAnnualPercentRewardRate","type":"uint256"},{"internalType":"uint256","name":"_maxAllowances","type":"uint256"}],"name":"exGlobalSet","outputs":[{"internalType":"uint80","name":"fuelId_","type":"uint80"},{"internalType":"uint256","name":"stakeMin_","type":"uint256"},{"internalType":"uint256","name":"claimCooldownInSeconds_","type":"uint256"},{"internalType":"uint256","name":"stakeAnnualPercentRewardRate_","type":"uint256"},{"internalType":"uint256","name":"maxAllowances_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"__controller","type":"address"}],"name":"exMintCtrlAdd","outputs":[{"internalType":"bool","name":"success_","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"__controller","type":"address"}],"name":"exMintCtrlDel","outputs":[{"internalType":"bool","name":"success_","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"__controller","type":"address"}],"name":"exMintCtrlGet","outputs":[{"internalType":"bool","name":"exists_","type":"bool"},{"internalType":"bool","name":"enabled_","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"__controller","type":"address"},{"internalType":"bool","name":"__isValidator","type":"bool"},{"internalType":"bool","name":"__enabled","type":"bool"}],"name":"exMintCtrlSet","outputs":[{"internalType":"address","name":"controller_","type":"address"},{"internalType":"bool","name":"isValidator_","type":"bool"},{"internalType":"bool","name":"enabled_","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"__mintLimiterInWei","type":"uint256"}],"name":"exMintLimiterSet","outputs":[{"internalType":"uint256","name":"mintLimiterInWei_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_claimshield","type":"bool"},{"internalType":"bool","name":"_mintshield","type":"bool"},{"internalType":"bool","name":"_stakeshield","type":"bool"},{"internalType":"bool","name":"_burnshield","type":"bool"},{"internalType":"bool","name":"_maintenance","type":"bool"}],"name":"exShieldSet","outputs":[{"internalType":"bool","name":"success_","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"goCurrentState","outputs":[{"internalType":"uint256","name":"currentBlockNumber_","type":"uint256"},{"internalType":"uint256","name":"currentBlockTime_","type":"uint256"},{"internalType":"uint256","name":"currentGasLimit_","type":"uint256"},{"internalType":"uint256","name":"exsessStartedAt_","type":"uint256"},{"internalType":"uint256","name":"exsessExpiresAt_","type":"uint256"},{"internalType":"uint256","name":"exsessSessionMax_","type":"uint256"},{"internalType":"uint256","name":"exsessSessionCooldown_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"goElect","outputs":[{"internalType":"address","name":"custodial_","type":"address"},{"internalType":"address","name":"guardian_","type":"address"},{"internalType":"address","name":"executor_","type":"address"},{"internalType":"address","name":"oracle_","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"goGovElects","outputs":[{"internalType":"address","name":"custodial_wallet_","type":"address"},{"internalType":"address","name":"custodial_custodial_","type":"address"},{"internalType":"address","name":"custodial_guardian_","type":"address"},{"internalType":"address","name":"custodial_executor_","type":"address"},{"internalType":"address","name":"custodial_oracle_","type":"address"},{"internalType":"address","name":"guardian_wallet_","type":"address"},{"internalType":"address","name":"guardian_custodial_","type":"address"},{"internalType":"address","name":"guardian_guardian_","type":"address"},{"internalType":"address","name":"guardian_executor_","type":"address"},{"internalType":"address","name":"guardian_oracle_","type":"address"},{"internalType":"address","name":"executor_wallet_","type":"address"},{"internalType":"address","name":"executor_custodial_","type":"address"},{"internalType":"address","name":"executor_guardian_","type":"address"},{"internalType":"address","name":"executor_executor_","type":"address"},{"internalType":"address","name":"executor_oracle_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"goMembers","outputs":[{"internalType":"address","name":"custodial_","type":"address"},{"internalType":"address","name":"guardian_","type":"address"},{"internalType":"address","name":"executor_","type":"address"},{"internalType":"address","name":"oracle_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"goSessionClose","outputs":[{"internalType":"bool","name":"success_","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"__code","type":"uint256"}],"name":"goSessionEnter","outputs":[{"internalType":"bool","name":"success_","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"goSessionExp","outputs":[{"internalType":"int256","name":"exsessSecondsRemaining_","type":"int256"},{"internalType":"uint256","name":"exsessExpiresAt_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"__custodial","type":"address"},{"internalType":"address","name":"__guardian","type":"address"},{"internalType":"address","name":"__executor","type":"address"},{"internalType":"address","name":"__oracle","type":"address"}],"name":"goVoteCast","outputs":[{"internalType":"bool","name":"success_","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"inSession","outputs":[{"internalType":"bool","name":"inSession_","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lsFabric","outputs":[{"internalType":"uint80","name":"fuelId_","type":"uint80"},{"internalType":"uint256","name":"initAt_","type":"uint256"},{"internalType":"uint256","name":"maxAllowances_","type":"uint256"},{"internalType":"uint256","name":"stakeMinInWei_","type":"uint256"},{"internalType":"uint256","name":"claimCooldownInSeconds_","type":"uint256"},{"internalType":"uint256","name":"stakeAnnualPercentRewardRate_","type":"uint256"},{"internalType":"uint256","name":"totalSupply_","type":"uint256"},{"internalType":"uint256","name":"maxSupply_","type":"uint256"},{"internalType":"uint256","name":"topOffSupply_","type":"uint256"},{"internalType":"uint256","name":"mintLimiter_","type":"uint256"},{"internalType":"bool","name":"maintenance_","type":"bool"},{"internalType":"bool","name":"mintshield_","type":"bool"},{"internalType":"bool","name":"burnshield_","type":"bool"},{"internalType":"bool","name":"stakeshield_","type":"bool"},{"internalType":"bool","name":"claimshield_","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lsMintCtrls","outputs":[{"components":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bool","name":"enabled","type":"bool"}],"internalType":"struct PogToken.MintController[]","name":"mintControllers_","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"maxSupply_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"__to","type":"address"},{"internalType":"uint256","name":"__amount","type":"uint256"}],"name":"mintCtrl","outputs":[{"internalType":"bool","name":"success_","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mintStakerReward","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nonce","outputs":[{"internalType":"uint256","name":"nonce_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nonceLast","outputs":[{"internalType":"uint256","name":"nonce_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"__stakerAddress","type":"address"}],"name":"orClaim","outputs":[{"internalType":"uint256","name":"reward_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"orWithdrawERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"orWithdrawEther","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"purgeAllowances","outputs":[{"internalType":"uint256","name":"allowancesPurgedCount_","type":"uint256"},{"internalType":"uint256","name":"allowancesClearedTotal_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reward","outputs":[{"internalType":"uint256","name":"reward_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"__owner","type":"address"}],"name":"rewardByOwner","outputs":[{"internalType":"uint256","name":"reward_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"__amount","type":"uint256"}],"name":"stake","outputs":[{"internalType":"uint256","name":"reward_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakerRewardPerBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"subchain","outputs":[{"internalType":"uint256","name":"stakerRewardPerBlock","type":"uint256"},{"internalType":"uint256","name":"stakerRewardPerBlockMax","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"__epochTime","type":"uint256"}],"name":"totalAt","outputs":[{"internalType":"uint256","name":"totalClaimedAtEpoch_","type":"uint256"},{"internalType":"uint256","name":"totalStakedAtEpoch_","type":"uint256"},{"internalType":"uint256","name":"totalUnstakedAtEpoch_","type":"uint256"},{"internalType":"uint256","name":"totalBurnedAtEpoch_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unstake","outputs":[{"internalType":"uint256","name":"reward_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakerRewardPerBlock_","type":"uint256"}],"name":"updateStakerRewardPerBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]