ERC-20
Overview
Max Total Supply
126,840,882.240853883546463153 POGS
Holders
171
Total Transfers
-
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Source Code Verified (Exact Match)
Contract Name:
PogToken
Compiler Version
v0.8.27+commit.40a35a09
Contract Source Code (Solidity Standard Json-Input format)
// 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..."); } }
{ "optimizer": { "enabled": true, "runs": 420 }, "viaIR": true, "evmVersion": "cancun", "metadata": { "useLiteralContent": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"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"}]
Contract Creation Code
608080604052346104ed5760208161622c803803809161001f82856104f1565b8339810103126104ed57516001600160501b038116908190036104ed576040519061004b6040836104f1565b60078252662837b3a1b7b4b760c91b60208301526040519061006e6040836104f1565b6004825263504f475360e01b602083015282516001600160401b0381116103fe57600354600181811c911680156104e3575b60208210146103e057601f8111610480575b506020601f821160011461041d57819293945f92610412575b50508160011b915f199060031b1c1916176003555b81516001600160401b0381116103fe57600454600181811c911680156103f4575b60208210146103e057601f811161037d575b50602092601f821160011461031c57928192935f92610311575b50508160011b915f199060031b1c1916176004555b6001600555633b9aca004202428104633b9aca0014421517156102fd5761016a904390610514565b80600755613840600a55601e600b554260085561384042018042116102fd57633b9aca00916101b3916009556101a76101ac426101a74343610514565b610514565b4590610514565b60405160208101918252602081526101cc6040826104f1565b51902006600681905560118190556017819055601d55601e80546001600160501b031916919091179055670de0b6b3a7640000602455603c6025556b06765c793fa10079d00000006021556b06765c7931c049c6289c0000602055600a6022556005602355600c8054336001600160a01b031991821681179092556012805482168317905560188054821683179055600d8054821683179055600e8054821683179055600f8054821683179055601080548216831790556013805482168317905560148054821683179055601580548216831790556016805482168317905560198054821683179055601a8054821683179055601b8054821683179055601c80549091169091179055633b9aca00603955680ad78ebc5ac6200000603a5542601f55604051615d0a90816105228239f35b634e487b7160e01b5f52601160045260245ffd5b015190505f8061012d565b601f1982169360045f52805f20915f5b868110610365575083600195961061034d575b505050811b01600455610142565b01515f1960f88460031b161c191690555f808061033f565b9192602060018192868501518155019401920161032c565b60045f527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b601f830160051c810191602084106103d6575b601f0160051c01905b8181106103cb5750610113565b5f81556001016103be565b90915081906103b5565b634e487b7160e01b5f52602260045260245ffd5b90607f1690610101565b634e487b7160e01b5f52604160045260245ffd5b015190505f806100cb565b601f1982169060035f52805f20915f5b81811061046857509583600195969710610450575b505050811b016003556100e0565b01515f1960f88460031b161c191690555f8080610442565b9192602060018192868b01518155019401920161042d565b60035f527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b601f830160051c810191602084106104d9575b601f0160051c01905b8181106104ce57506100b2565b5f81556001016104c1565b90915081906104b8565b90607f16906100a0565b5f80fd5b601f909101601f19168101906001600160401b038211908210176103fe57604052565b919082018092116102fd5756fe608060405260043610156100ec575b36156100595760405162461bcd60e51b815260206004820152601660248201527f436c6f73652c20627574206e6f2063696761722e2e2e000000000000000000006044820152606490fd5b610061614c86565b5f600361006c614d40565b60405190815242602082015260a06040820152600760a0820152667265636569766560c81b60c082015234606082015260e06080820152601560e08201527f6e617469766520746f6b656e20726563656976656400000000000000000000006101008201525f516020615cb55f395f51905f526101203392a46001600555005b5f3560e01c806302169792146137065780630435e393146136a857806306fdde03146135ed578063095ea7b31461336857806310e408a914612e4e578063158ea43d14612e1c57806318160ddd14612dff5780631a968f7814612d9d578063228cb73314612d8257806323b872dd14612c7657806324e770d014612c5c57806326cb131014612c3857806329fb7ef614612af25780632def6620146129755780632eaeb0fd14612728578063313ce5671461270d5780633ed10b92146126f157806340c10f19146126b05780634220b0ff1461266957806342966c681461262257806346205ec9146126055780634b8367ca146125c15780634e71d92d146124f05780636150aad1146123f957806368efcb50146123a15780636bc6c5a91461233f57806370337b331461228e57806370a082311461226b578063725264f7146121335780637364f0e5146120df57806379cc679014611fac5780638c40bbf814611f7c57806395d89b4114611e74578063a694fc3a14611cac578063a9059cbb14611c4d578063aae9261114611449578063ab8e786f146113af578063aeba297c14610f0b578063affed0e014610edd578063b69ef8a814610d85578063b7b2d03614610d6b578063b87b601614610ced578063bacd99ff14610c6c578063bb0ccf1214610c2c578063bc9b60a414610b61578063c199498514610aa2578063cda64d9414610a2f578063d5abeb0114610a12578063d60ed7fa146109ce578063d77c587f146109a3578063d98da96a14610944578063dd62ed3e146108f0578063df705e0714610897578063eff8e69514610831578063f1640e981461072a578063facd743b146106ed5763fda1a04e0361000e57346106e9575f3660031901126106e95761038461037f33614d65565b613baf565b61038c614c86565b600c546001600160a01b038116906001600160a01b0360125416906001600160a01b0360185416926001600160a01b03601354166001600160a01b036019541681145f146106da576001600160a01b03905b1680926001600160a01b03191617600c5503610639575b6001600160a01b03600e54166001600160a01b03601a541681145f14610626576001600160a01b03905b1690816001600160a01b0319601254161760125503610592575b6001600160a01b03600f54166001600160a01b036015541681145f1461057f576001600160a01b03905b1690816001600160a01b03196018541617601855036104eb575b6001600160a01b03600c54166001600160a01b0360125416906104e76001600160a01b03601854166104ad6157cf565b9060016005556040519485948592936001600160a01b03809296958160609581608089019a16885216602087015216604085015216910152565b0390f35b600460016104f7614d40565b5f516020615cb55f395f51905f526001600160a01b03601854169160405190815242602082015260a0604082015261054760a08201604090600781526619dbd15b1958dd60ca1b60208201520190565b9260608201526f115e1958dd5d1bdc88195b1958dd195960821b602082850394856080850152601081520152604033930190a461047d565b506001600160a01b038060185416610463565b6004600161059e614d40565b5f516020615cb55f395f51905f526001600160a01b03601254169160405190815242602082015260a060408201526105ee60a08201604090600781526619dbd15b1958dd60ca1b60208201520190565b9260608201526f11dd585c991a585b88195b1958dd195960821b602082850394856080850152601081520152604033930190a4610439565b506001600160a01b03806012541661041f565b60046001610645614d40565b5f516020615cb55f395f51905f526001600160a01b03600c54169160405190815242602082015260a0604082015261069560a08201604090600781526619dbd15b1958dd60ca1b60208201520190565b9260608201527f437573746f6469616c20656c6563746564000000000000000000000000000000602082850394856080850152601181520152604033930190a46103f5565b506001600160a01b03816103de565b5f80fd5b346106e95760203660031901126106e9576001600160a01b0361070e613929565b165f52603c602052602060ff60405f2054166040519015158152f35b346106e95760403660031901126106e957610743613929565b61075e6001600160a01b036107566157cf565b1633146142a7565b610766614c86565b60206001600160a01b03604461077a6157cf565b5f83604051968795869463a9059cbb60e01b86521660048501526024356024850152165af1908115610826575f916107eb575b50156107ba576001600555005b60405162461bcd60e51b81526020600482015260096024820152681d1e0819985a5b195960ba1b6044820152606490fd5b90506020813d60201161081e575b8161080660209383613a5e565b810103126106e9575180151581036106e957816107ad565b3d91506107f9565b6040513d5f823e3d90fd5b346106e9575f3660031901126106e9576001600160a01b03600c54163314801561087e575b61085f906142d9565b610867614c86565b6020610871614c01565b6001600555604051908152f35b5061085f6001600160a01b036012541633149050610856565b346106e9575f3660031901126106e9576108b361037f33614d65565b6009544281035f4212828212811690838313901516176108dc5760409182519182526020820152f35b634e487b7160e01b5f52601160045260245ffd5b346106e95760403660031901126106e957610909613929565b6001600160a01b0361091961393f565b91165f5260016020526001600160a01b0360405f2091165f52602052602060405f2054604051908152f35b346106e95760203660031901126106e9576001600160a01b03600c54163314801561098a575b610973906142d9565b6020610980600435614be6565b6040519015158152f35b506109736001600160a01b03601254163314905061096a565b346106e95760203660031901126106e95760206109c66109c1613929565b614e53565b604051908152f35b346106e95760403660031901126106e9576001600160a01b036109ef613929565b165f52602f60205260405f206024355f52602052602060405f2054604051908152f35b346106e9575f3660031901126106e9576020602154604051908152f35b346106e95760203660031901126106e9576020610a93610a4d613929565b610a5d610a58614ca6565b613aff565b610a70610a6b601d54614d1d565b613b39565b610a866001600160a01b03601854163314613b6f565b610a8e614c86565b614960565b60016005556040519015158152f35b346106e9575f3660031901126106e9576101e069ffffffffffffffffffff601e541660ff601f5460225460245460255460235460025490602154926020549460265496603754986040519b8c5260208c015260408b015260608a0152608089015260a088015260c087015260e0860152610100850152610120840152818160201c1615156101408401528181161515610160840152818160181c161515610180840152818160081c1615156101a084015260101c1615156101c0820152f35b346106e95760203660031901126106e9576020610ba8610b7f613929565b610b926001600160a01b036107566157cf565b610b9a614c86565b610ba2615591565b50615774565b80610bba576001600555604051908152f35b600480610bc5614d40565b604051908152428582015260a06040820152600760a0820152666f72436c61696d60c81b60c082015283606082015260e06080820152600760e08201526618db185a5b595960ca1b6101008201525f516020615cb55f395f51905f526101203392a4610871565b346106e95760403660031901126106e9576020610a93610c4a613929565b610c5b610c5633614df7565b613f59565b610c63614c86565b602435906153e2565b346106e9575f3660031901126106e957610c8861037f33614d65565b6001600160a01b03600c54166001600160a01b0360125416906104e76001600160a01b0360185416610cb86157cf565b906040519485948592936001600160a01b03809296958160609581608089019a16885216602087015216604085015216910152565b346106e9575f3660031901126106e9576001600160a01b03600c541633148015610d52575b610d1b906142d9565b60c0600654600754600854600954600a5491600b5493604051958652602086015260408501526060840152608083015260a0820152f35b50610d1b6001600160a01b036012541633149050610d12565b346106e9575f3660031901126106e9576020610980614ca6565b346106e9575f3660031901126106e9576101a05f5f5f90335f525f602052670de0b6b3a764000060405f20541015610ebf575b670de0b6b3a7640000610dca33614eb8565b1015610ea4575b335f526028602052670de0b6b3a764000060405f20541015610e87575b610df733614eb8565b91335f52602860205260405f205490335f525f60205260405f2054335f52602960205260405f2054335f52602a60205260405f205491603454936035549560025497603654996040519b8c5260208c015260408b015260608a0152608089015260a088015260c087015260e086015261010085015261012084015261014083015261016082015242610180820152f35b50335f526028602052670de0b6b3a764000060405f205404610dee565b9150670de0b6b3a7640000610eb833614eb8565b0491610dd1565b9050335f525f602052670de0b6b3a764000060405f20540490610db8565b346106e9575f3660031901126106e957610ef961037f33614d65565b610f01614c86565b6020610871614d40565b346106e95760a03660031901126106e95760043569ffffffffffffffffffff81168091036106e9576024356044356064359160843593610f4c610a58614ca6565b610f5a610a6b601d54614d1d565b610f706001600160a01b03601854163314613b6f565b610f78614c86565b80151580611397575b6112f7575b50801515806112eb575b61122d575b508060255403611179575b5080602354036110b6575b508060225403610ff6575b60a069ffffffffffffffffffff601e5416602454602554602354906022549260016005556040519485526020850152604084015260608301526080820152f35b60026004916103e881115f146110b0576103e85b6022555f516020615cb55f395f51905f52611023614d40565b60405190815242602082015260a0604082015261105c60a08201604090600b81526a195e11db1bd8985b14d95d60aa1b60208201520190565b92606082015264706461746560d81b604082850394856080850152602581527f6d6178696d756d20616c6c6f77616e636573207065722061646472657373207560208201520152606033930190a480610fb6565b8061100a565b600260049161271081115f14611173576127105b6023555f516020615cb55f395f51905f526110e3614d40565b60405190815242602082015260a0604082015261111c60a08201604090600b81526a195e11db1bd8985b14d95d60aa1b60208201520190565b92606082015267081d5c19185d195960c21b604082850394856080850152602881527f7374616b6520616e6e75616c2070657263656e7420726577617264207261746560208201520152606033930190a481610fab565b806110ca565b610e108111156112285750610e105b60255560046002611197614d40565b5f516020615cb55f395f51905f526025549160405190815242602082015260a060408201526111e260a08201604090600b81526a195e11db1bd8985b14d95d60aa1b60208201520190565b9260608201527f636c61696d20636f6f6c646f776e207570646174656400000000000000000000602082850394856080850152601681520152604033930190a482610fa0565b611188565b6002600491670de0b6b3a764000081105f146112e557670de0b6b3a76400005b6024555f516020615cb55f395f51905f52611266614d40565b60405190815242602082015260a0604082015261129f60a08201604090600b81526a195e11db1bd8985b14d95d60aa1b60208201520190565b9260608201527f6d696e696d756d207374616b6520616d6f756e74207570646174656400000000602082850394856080850152601c81520152604033930190a483610f95565b8061124d565b50806024541415610f90565b60028160049269ffffffffffffffffffff19601e541617601e555f516020615cb55f395f51905f52611327614d40565b60405190815242602082015260a0604082015261136060a08201604090600b81526a195e11db1bd8985b14d95d60aa1b60208201520190565b9260608201526d199d595b1259081d5c19185d195960921b602082850394856080850152600e81520152604033930190a484610f86565b508069ffffffffffffffffffff601e54161415610f81565b346106e95760403660031901126106e9576113c8613929565b6113d4610c5633614df7565b335f52603c602052600160ff60405f20541615150361140457610a936020916113fb614c86565b6024359061472d565b60405162461bcd60e51b815260206004820152601f60248201527f76616c696461746f7220726f6c6520726571756972656420746f206d696e74006044820152606490fd5b346106e95760803660031901126106e957611462613929565b61146a61393f565b6044356001600160a01b038116908181036106e957606435926001600160a01b038416948585036106e9576114a161037f33614d65565b6114a9614c86565b6001600160a01b0381169081151580611c3b575b80611c32575b15611bd9576001600160a01b03600c54163314611a37575b6001600160a01b03601254163314611873575b6001600160a01b03601854163314611587575b6004600161150d614d40565b60405190815242602082015260a06040820152600660a08201526519dbdd94d95d60d21b60c082015281606082015260e06080820152600f60e08201526e75706461746520636f6d706c65746560881b6101008201525f516020615cb55f395f51905f526101203392a46001600555602060405160018152f35b6001600160a01b0360185416330361150157816001600160a01b0360195416036117e5575b50506001600160a01b03601a5416906001600160a01b038116809203611757575b5050816001600160a01b03601b5416036116b2575b5050816001600160a01b03601c541603611601575b8080808080611501565b60016003915f516020615cb55f395f51905f52602061161e614d40565b9261168460386116396001600160a01b036018541693615b9a565b6040519485917f6f7261636c6520766f7465207570646174656420746f3a200000000000000000828401528051918291018484015e81015f838201520301601f198101845283613a5e565b61169760405192839233964290856158d0565b0390a46001600160a01b0319601c541617601c5580806115f7565b60016003915f516020615cb55f395f51905f5261173c602061172b603a6116e06116da614d40565b96615b9a565b6040519384917f6578656375746f7220766f7465207570646174656420746f3a20000000000000828401528051918291018484015e81015f838201520301601f198101835282613a5e565b6040519182918833964290856158d0565b0390a46001600160a01b0319601b541617601b5582806115e2565b60016003915f516020615cb55f395f51905f526117ca602061172b603a61177f6116da614d40565b6040519384917f677561726469616e20766f7465207570646174656420746f3a20000000000000828401528051918291018484015e81015f838201520301601f198101835282613a5e565b0390a46001600160a01b0319601a541617601a5584806115cd565b60016003915f516020615cb55f395f51905f52611858602061172b603b61180d6116da614d40565b6040519384917f637573746f6469616c20766f7465207570646174656420746f3a200000000000828401528051918291018484015e81015f838201520301601f198101835282613a5e565b0390a46001600160a01b0319601954161760195585806115ac565b6001600160a01b036012541633036114ee57816001600160a01b0360135416036119df575b6001600160a01b03601454166001600160a01b038416809103611998575b50846001600160a01b036015541603611940575b6016546001600160a01b031687146114ee57600360016118e8614d40565b5f516020615cb55f395f51905f5260208a61191360386116396001600160a01b036012541693615b9a565b61192660405192839233964290856158d0565b0390a4866001600160a01b031960165416176016556114ee565b6003600161194c614d40565b5f516020615cb55f395f51905f5261197e602061196d603a6116e08c615b9a565b6040519182918c33964290856158d0565b0390a4846001600160a01b031960155416176015556118ca565b600360016119a4614d40565b5f516020615cb55f395f51905f526119c5602061172b603a61177f8c615b9a565b0390a46001600160a01b03196014541617601455876118b6565b600360016119eb614d40565b5f516020615cb55f395f51905f52611a1d6020611a0c603b61180d89615b9a565b6040519182918933964290856158d0565b0390a4816001600160a01b03196013541617601355611898565b6001600160a01b03600c541633036114db57816001600160a01b03600d541603611b92575b6001600160a01b03600e54166001600160a01b038416809103611b4b575b50846001600160a01b03600f541603611b04575b6010546001600160a01b031687146114db5760036001611aac614d40565b5f516020615cb55f395f51905f5260208a611ad760386116396001600160a01b03600c541693615b9a565b611aea60405192839233964290856158d0565b0390a4866001600160a01b031960105416176010556114db565b60036001611b10614d40565b5f516020615cb55f395f51905f52611b31602061196d603a6116e08c615b9a565b0390a4846001600160a01b0319600f541617600f55611a8e565b60036001611b57614d40565b5f516020615cb55f395f51905f52611b78602061172b603a61177f8c615b9a565b0390a46001600160a01b0319600e541617600e5587611a7a565b60036001611b9e614d40565b5f516020615cb55f395f51905f52611bbf6020611a0c603b61180d89615b9a565b0390a4816001600160a01b0319600d541617600d55611a5c565b60405162461bcd60e51b815260206004820152602b60248201527f6f6e6c79206f7261636c65206d617920657175616c206164647265737328302960448201526a202864697361626c65642960a81b6064820152608490fd5b508415156114c3565b506001600160a01b03831615156114bd565b346106e95760403660031901126106e957611c9c611c69613929565b60243590611c75614c86565b611c968280611c8333614eb8565b1015611c8e33614eb8565b903390613eff565b336159cd565b6001600555602060405160018152f35b346106e95760203660031901126106e957600435611cc8614c86565b611cd06155db565b505f6024548210611e4057611ce433614eb8565b8211611e0d57602091335f52602d8352611d0f611d0860405f205460255490613a03565b421161426a565b335f52602d835260405f2054601f541115611df5575b6003600491335f526028855260405f20611d40828254613a03565b9055335f52602b85524260405f2055335f52602d85524260405f2055425f526030855260405f20611d72828254613a03565b9055611d8081603454613a03565b6034555f516020615cb55f395f51905f52611d99614d40565b611da1613c19565b92604051918252428883015260a06040830152600560a0830152647374616b6560d81b60c0830152606082015260e0608082015280611de5339460e0830190613905565b0390a46001600555604051908152f35b905060046003611e0433615774565b92915050611d25565b60405162461bcd60e51b815260206004820152600b60248201526a616d743e62616c616e636560a81b6044820152606490fd5b60405162461bcd60e51b815260206004820152600c60248201526b30b6ba1e39ba30b5b2b6b4b760a11b6044820152606490fd5b346106e9575f3660031901126106e9576040515f6004548060011c90600181168015611f72575b602083108114611f5e57828552908115611f3a5750600114611edc575b6104e783611ec881850382613a5e565b604051918291602083526020830190613905565b91905060045f527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b915f905b808210611f2057509091508101602001611ec8611eb8565b919260018160209254838588010152019101909291611f08565b60ff191660208086019190915291151560051b84019091019150611ec89050611eb8565b634e487b7160e01b5f52602260045260245ffd5b91607f1691611e9b565b346106e95760203660031901126106e9576104e7611fa0611f9b613929565b615080565b60405191829182613973565b346106e95760403660031901126106e957612028611fc8613929565b60243590611fd4614c86565b611fdc615518565b50611ffd8280611feb84614eb8565b101583611ff781614eb8565b91613eff565b6022541515806120cd575b61202f575b612018823383615827565b612022828261566c565b506156dd565b6001600555005b60015f61203a614d40565b60405190815242602082015260a06040820152600860a0820152676275726e46726f6d60c01b60c082015284606082015260e06080820152602a60e08201527f6661696c656420746f20646563726561736520747261636b656420616c6c6f7761010082015269616e63652076616c756560b01b6101208201525f516020615cb55f395f51905f526101403392a461200d565b506120d9823383614eef565b15612008565b346106e9575f3660031901126106e9576120fb61037f33614d65565b60e0600854600954600a54600b5491604051934385524260208601524560408601526060850152608084015260a083015260c0820152f35b346106e9575f3660031901126106e95761214c33614d65565b61215590613baf565b600c546001600160a01b0316600d546001600160a01b031690600e546001600160a01b0316600f546001600160a01b03166010546001600160a01b03166012546001600160a01b03166013546001600160a01b03166014546001600160a01b03166015546001600160a01b0316906016546001600160a01b0316926018546001600160a01b0316946019546001600160a01b031696601a546001600160a01b031698601b546001600160a01b03169a601c546001600160a01b03169c6040519e8f91825260208201526040015260608d015260808c015260a08b015260c08a015260e08901526101008801526101208701526101408601526101608501526101808401526101a08301526101c08201526101e090f35b346106e95760203660031901126106e95760206109c6612289613929565b614eb8565b346106e95760603660031901126106e95760606123016122ac613929565b6122b4613955565b6122bc613964565b916122c8610a58614ca6565b6122d6610a6b601d54614d1d565b6001600160a01b03600c541633148015612326575b6122f4906142d9565b6122fc614c86565b61438b565b9060016005556001600160a01b03604051931683521515602083015215156040820152f35b506122f46001600160a01b0360125416331490506122eb565b346106e95760203660031901126106e9575f80808060043561236a6001600160a01b036107566157cf565b612372614c86565b6001600160a01b036123826157cf565b16828215612398575bf115610826576001600555005b506108fc61238b565b346106e95760203660031901126106e9576004355f9081526032602090815260408083205460308352818420546031845282852054603385529483902054835192835293820152908101929092526060820152608090f35b346106e9575f3660031901126106e957603b5461241581613a80565b906124236040519283613a5e565b808252602082019081603b5f527fbbe3212124853f8b0084a66a2d057c2966e251e132af3691db153ab65f0d1a4d5f915b8383106124b6578486604051918291602083019060208452518091526040830191905f5b818110612486575050500390f35b825180516001600160a01b0316855260209081015115158186015286955060409094019390920191600101612478565b6001602081926040516124c881613a42565b60ff86546001600160a01b038116835260a01c16151583820152815201920192019190612454565b346106e9575f3660031901126106e957612508614c86565b612510615591565b50335f52602d60205261252d611d0860405f205460255490613a03565b60016023541061259357600254602154111561254e57602061087133615774565b60405162461bcd60e51b815260206004820152601860248201527f6d6178737570706c7920696e2063697263756c6174696f6e00000000000000006044820152606490fd5b60405162461bcd60e51b81526020600482015260066024820152654150523d302560d01b6044820152606490fd5b346106e95760403660031901126106e9576001600160a01b036125e2613929565b165f52602e60205260405f206024355f52602052602060405f2054604051908152f35b346106e9575f3660031901126106e9576020603854604051908152f35b346106e95760203660031901126106e957612028600435612641614c86565b612649615518565b506126588180611c8333614eb8565b612662813361566c565b50336156dd565b346106e9575f3660031901126106e957612684610a58614ca6565b612692610a6b601d54614d1d565b61269e61037f33614d65565b6126a6614c86565b6020610a93613fa5565b346106e95760403660031901126106e9576126e96126cc613929565b6126d8610c5633614df7565b6126e0614c86565b60243590615195565b506001600555005b346106e9575f3660031901126106e9576104e7611fa033615080565b346106e9575f3660031901126106e957602060405160128152f35b346106e95760203660031901126106e957612741613929565b61274c610a58614ca6565b61275a610a6b601d54614d1d565b6127706001600160a01b03601854163314613b6f565b612778614c86565b612783601d54614d1d565b156129305761279181614db0565b6128fd576103e8603b5410156128c5576001600160a01b03604051916127b683613a42565b168082526003600260208401925f84525f516020615cb55f395f51905f526127dc614d40565b6127e4613c19565b9260405191825242602083015260a06040830152600d60a08301526c195e135a5b9d10dd1c9b105919609a1b60c0830152606082015260e0608082015280612831339460e0830190613905565b0390a4603b54600160401b8110156128b1578060016128539201603b55613f41565b91909161289e5791518154925174ffffffffffffffffffffffffffffffffffffffffff199093166001600160a01b03919091161791151560a01b60ff60a01b16919091179055611c9c565b634e487b7160e01b5f525f60045260245ffd5b634e487b7160e01b5f52604160045260245ffd5b60405162461bcd60e51b815260206004820152601060248201526f1b585e18dd1c9b1cc81c995858da195960821b6044820152606490fd5b60405162461bcd60e51b815260206004820152600b60248201526a6374726c2065786973747360a81b6044820152606490fd5b60405162461bcd60e51b815260206004820152601260248201527f71756f726d20636f646520696e76616c696400000000000000000000000000006044820152606490fd5b346106e9575f3660031901126106e95761298d614c86565b5f335f52602860205260405f2054908115612aad57602091335f52602d835260405f2054601f541115612a95575b6003600491335f52602885525f6040812055335f52602b85525f6040812055335f52602d85525f6040812055335f52602c85524260405f20558060345410155f14612a8c57612a0c81603454614953565b6034555b425f526031855260405f20612a26828254613a03565b90555f516020615cb55f395f51905f52612a3e614d40565b612a46613c19565b92604051918252428883015260a06040830152600760a083015266756e7374616b6560c81b60c0830152606082015260e0608082015280611de5339460e0830190613905565b5f603455612a10565b905060046003612aa433615774565b929150506129bb565b60405162461bcd60e51b815260206004820152601460248201527f6e6f20746f6b656e7320746f20756e7374616b650000000000000000000000006044820152606490fd5b346106e95760203660031901126106e957600435612b11610a58614ca6565b612b1f610a6b601d54614d1d565b612b2b61037f33614d65565b612b33614c86565b603a54811180612c035760049160039115612bfa575b612b51614d40565b9060405191825242602083015260a06040830152601a60a08301527f7570646174655374616b6572526577617264506572426c6f636b00000000000060c0830152606082015260e06080820152602960e08201527f6e65772076616c696461746f72207374616b657220726577617264207065722061010082015268189b1bd8dac81cd95d60ba1b6101208201525f516020615cb55f395f51905f526101403392a46001600555005b80603955612b49565b60405162461bcd60e51b815260206004820152600d60248201526c0ecc2d87ce4caeec2e4c89ac2f609b1b6044820152606490fd5b346106e9575f3660031901126106e9576040603954603a5482519182526020820152f35b346106e9575f3660031901126106e95760206109c6613f2b565b346106e95760603660031901126106e957611c9c612c92613929565b612c9a61393f565b60443591612ca6614c86565b612cb48380611feb84614eb8565b602254151580612d70575b612cd4575b612ccf833383615827565b6159cd565b60015f612cdf614d40565b60405190815242602082015260a06040820152600c60a08201526b7472616e7366657246726f6d60a01b60c082015285606082015260e06080820152602460e08201527f6661696c656420746f20646563726561736520747261636b656420616c6c6f7761010082015263616e636560e01b6101208201525f516020615cb55f395f51905f526101403392a4612cc4565b50612d7c833383614eef565b15612cbf565b346106e9575f3660031901126106e95760206109c633614e53565b346106e95760203660031901126106e9576040612def612dbb613929565b612dc6610a58614ca6565b612dd4610a6b601d54614d1d565b612dea6001600160a01b03601854163314613b6f565b613edc565b8251911515825215156020820152f35b346106e9575f3660031901126106e9576020600254604051908152f35b346106e95760203660031901126106e957612e3961037f33614d65565b612e41614c86565b6020610a93600435613c3e565b346106e95760a03660031901126106e9576004358015158082036106e957612e74613955565b612e7c613964565b9060643591821515918284036106e95760843595861515958688036106e957612ea6610a58614ca6565b612eb4610a6b601d54614d1d565b612eca6001600160a01b03601854163314613b6f565b612ed2614c86565b603754918160ff8460101c16151503613297575b50505060375490801515908160ff84161515036131cd575b50505060375490801515908160ff8460081c161515036130fe575b505050603754918160ff8460181c1615150361302b575b505050603754918160ff8460201c16151503612f56576001600555602060405160018152f35b60039264ff00000000849360201b169064ff00000000191617603755612f7a614d40565b9015613016575f516020615cb55f395f51905f526001915b60405190815242602082015260a0604082015260ff612fcd60a08301604090600b81526a195e14da1a595b1914d95d60aa1b60208201520190565b931660608201527f6d61696e74656e616e6365206d6f646520757064617465640000000000000000602082850394856080850152601881520152604033930190a4808080611c9c565b5f516020615cb55f395f51905f525f91612f92565b60039263ff000000849360181b169063ff00000019161760375561304d614d40565b90156130e9575f516020615cb55f395f51905f526001915b60405190815242602082015260a0604082015260ff6130a060a08301604090600b81526a195e14da1a595b1914d95d60aa1b60208201520190565b931660608201527f6275726e736869656c6420757064617465640000000000000000000000000000602082850394856080850152601281520152604033930190a4828080612f30565b5f516020615cb55f395f51905f525f91613065565b60039261ff00849360081b169061ff0019161760375561311c614d40565b90156131b8575f516020615cb55f395f51905f526001915b60405190815242602082015260a0604082015260ff61316f60a08301604090600b81526a195e14da1a595b1914d95d60aa1b60208201520190565b931660608201527f7374616b65736869656c64207570646174656400000000000000000000000000602082850394856080850152601381520152604033930190a4848080612f19565b5f516020615cb55f395f51905f525f91613134565b60039260ff8493169060ff1916176037556131e6614d40565b9015613282575f516020615cb55f395f51905f526001915b60405190815242602082015260a0604082015260ff61323960a08301604090600b81526a195e14da1a595b1914d95d60aa1b60208201520190565b931660608201527f6d696e7473736869656c64207570646174656400000000000000000000000000602082850394856080850152601381520152604033930190a4858080612efe565b5f516020615cb55f395f51905f525f916131fe565b60039262ff0000849360101b169062ff00001916176037556132b7614d40565b9015613353575f516020615cb55f395f51905f526001915b60405190815242602082015260a0604082015260ff61330a60a08301604090600b81526a195e14da1a595b1914d95d60aa1b60208201520190565b931660608201527f636c61696d736869656c64207570646174656400000000000000000000000000602082850394856080850152601381520152604033930190a4868080612ee6565b5f516020615cb55f395f51905f525f916132cf565b346106e95760403660031901126106e957613381613929565b6024359061338d614c86565b335f52602760205260405f20546022548110613435575b503315613422576001600160a01b031690811561340f57335f52600160205260405f20825f526020528060405f20556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a36001600555602060405160018152f35b634a1406b160e11b5f525f60045260245ffd5b63e602df0560e01b5f525f60045260245ffd5b5f9291906001600160a01b038216845b335f52602760205260405f20548110806135e1575b156135d757335f526027602052816001600160a01b03600161347f8460405f206139d6565b50015416146134965761349190613ba1565b613445565b8495506134b56002919592939495335f52602760205260405f206139d6565b50015560015b1561357d575b50600a8102818104600a14821517156108dc57602254906009820291808304600914901517156108dc5711156133a4575f6002916134fd614d40565b9060405191825242602083015260a06040830152600860a083015267185c1c1c9bdd985b60c21b60c0830152606082015260e06080820152601460e08201527f393025206361706163697479207761726e696e670000000000000000000000006101008201525f516020615cb55f395f51905f526101203392a4826133a4565b6040519061358a82613a26565b3382526020820152836040820152335f52602760205260405f208054600160401b8110156128b1576135c1916001820181556139d6565b91909161289e576135d191613aab565b836134c1565b50909192936134bb565b5060225481111561345a565b346106e9575f3660031901126106e9576040515f6003548060011c9060018116801561369e575b602083108114611f5e57828552908115611f3a5750600114613640576104e783611ec881850382613a5e565b91905060035f527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b915f905b80821061368457509091508101602001611ec8611eb8565b91926001816020925483858801015201910190929161366c565b91607f1691613614565b346106e95760203660031901126106e95760206004356136c9610a58614ca6565b6136d7610a6b601d54614d1d565b6136ed6001600160a01b03601854163314613b6f565b6136f5614c86565b806026556001600555604051908152f35b346106e9575f3660031901126106e95761371e614c86565b5f335f52602760205260405f20545f33155b82821061383c575050604051613747602082613a5e565b5f81525f805b818110613813575050335f52602760205260405f20815191600160401b83116128b15781548383558084106137c5575b50602001905f5260205f205f915b8383106137a75760408587600160055582519182526020820152f35b60036020826137b96001945186613aab565b0192019201919061378b565b806003029060038204036108dc57836003026003810485036108dc57835f5260205f2091820191015b8181106137fb575061377d565b6003905f81555f60018201555f6002820155016137ee565b60209060405161382281613a26565b5f81525f838201525f60408201528282860101520161374d565b613862819294335f52602760205260026138598760405f206139d6565b50015490613a03565b93335f5260276020526001600160a01b0360016138828360405f206139d6565b500154169161342257811561340f57600191335f528260205260405f206001600160a01b0382165f526020525f60408120556040515f81527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3335f5260276020526138fe6138f88260405f206139d6565b90613a10565b0190613730565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b600435906001600160a01b03821682036106e957565b602435906001600160a01b03821682036106e957565b6024359081151582036106e957565b6044359081151582036106e957565b60206040818301928281528451809452019201905f5b8181106139965750505090565b90919260206060600192604087516001600160a01b0381511683526001600160a01b03858201511685840152015160408201520194019101919091613989565b80548210156139ef575f52600360205f20910201905f90565b634e487b7160e01b5f52603260045260245ffd5b919082018092116108dc57565b9061289e576002815f8093558260018201550155565b6060810190811067ffffffffffffffff8211176128b157604052565b6040810190811067ffffffffffffffff8211176128b157604052565b90601f8019910116810190811067ffffffffffffffff8211176128b157604052565b67ffffffffffffffff81116128b15760051b60200190565b818102929181159184041417156108dc57565b9060406002916001600160a01b0380825116166001600160a01b03198554161784556001600160a01b036020820151166001600160a01b036001860191166001600160a01b03198254161790550151910155565b15613b0657565b60405162461bcd60e51b815260206004820152600b60248201526a38bab7b93690b2b9ba30b160a91b6044820152606490fd5b15613b4057565b60405162461bcd60e51b81526020600482015260076024820152661c58dd99985a5b60ca1b6044820152606490fd5b15613b7657565b606460405162461bcd60e51b81526020600482015260046024820152632165786560e01b6044820152fd5b5f1981146108dc5760010190565b15613bb657565b606460405162461bcd60e51b815260206004820152600460248201526310b3b7bb60e11b6044820152fd5b9060ff8091169116019060ff82116108dc57565b60405190613c04604083613a5e565b600682526511985a5b195960d21b6020830152565b60405190613c28604083613a5e565b60078252665375636365737360c81b6020830152565b905f916001600160a01b03600c54163314613ed3575b6001600160a01b03601254163314613eca575b6001600160a01b03601854163314613ec1575b5060ff613cc9613c8b601154614d1d565b613cbb613c99601754614d1d565b613ca4601d54614d1d565b9215613eba576001905b15613eb357600190613be1565b9015613eb357600190613be1565b1660028110613d6457509050613ce1600a5442613a03565b60095560046001613cf0614d40565b5f516020615cb55f395f51905f52613d06613c19565b9160405190815242602082015260a0604082015280613d5c613d4760a08301604090600e81526d32bc29b2b9b9b4b7b722b73a32b960911b60208201520190565b86606084015282810360808401523395613905565b0390a4600190565b80613de7575060026001613d76614d40565b5f516020615cb55f395f51905f52613d8c613bf5565b9160405190815242602082015260a0604082015280613de2613dcd60a08301604090600e81526d32bc29b2b9b9b4b7b722b73a32b960911b60208201520190565b5f606084015282810360808401523395613905565b0390a4565b600114613df057565b905060036001613dfe614d40565b60405190815242602082015260a060408201525f516020615cb55f395f51905f52613e4860a08301604090600e81526d32bc29b2b9b9b4b7b722b73a32b960911b60208201520190565b915f60608201527f72206d656d62657220746f20656e74657220636f646500000000000000000000604082850394856080850152603681527f636f64652061636365707465642c206177616974696e67206f6e65206f74686560208201520152606033930190a45f90565b5f90613be1565b5f90613cae565b601d555f613c7a565b80601755613c67565b80601155613c54565b613ee581614db0565b15613ef857613ef390614df7565b600191565b505f905f90565b15613f0957505050565b6001600160a01b039063391434e360e21b5f521660045260245260445260645ffd5b6002546020541015613f3b575f90565b60395490565b603b548110156139ef57603b5f5260205f2001905f90565b15613f6057565b60405162461bcd60e51b815260206004820152601e60248201527f6d696e746374726c20726f6c6520726571756972656420746f206d696e7400006044820152606490fd5b6001600160a01b03600c5416331480614259575b6141b9576001600160a01b03601254163314806141a8575b614108576001600160a01b03601854163314806140f7575b6140575760026001613ff9614d40565b5f516020615cb55f395f51905f5261400f613bf5565b9160405190815242602082015260a0604082015280614050613dcd60a08301604090600e81526d657853657373696f6e436c6f736560901b60208201520190565b0390a45f90565b4260095560046001614067614d40565b60405190815242602082015260a060408201525f516020615cb55f395f51905f526140b160a08301604090600e81526d657853657373696f6e436c6f736560901b60208201520190565b918360608201527f436c6f736564206279206578656375746f720000000000000000000000000000602082850394856080850152601281520152604033930190a4600190565b50614103601d54614d1d565b613fe9565b4260095560046001614118614d40565b60405190815242602082015260a060408201525f516020615cb55f395f51905f5261416260a08301604090600e81526d657853657373696f6e436c6f736560901b60208201520190565b918360608201527f436c6f73656420627920677561726469616e0000000000000000000000000000602082850394856080850152601281520152604033930190a4600190565b506141b4601754614d1d565b613fd1565b42600955600460016141c9614d40565b60405190815242602082015260a060408201525f516020615cb55f395f51905f5261421360a08301604090600e81526d657853657373696f6e436c6f736560901b60208201520190565b918360608201527f436c6f73656420627920637573746f6469616c00000000000000000000000000602082850394856080850152601381520152604033930190a4600190565b50614265601154614d1d565b613fb9565b1561427157565b60405162461bcd60e51b815260206004820152600e60248201526d72657761726420636f6f6c696e6760901b6044820152606490fd5b156142ae57565b606460405162461bcd60e51b8152602060048201526004602482015263216f726160e01b6044820152fd5b156142e057565b606460405162461bcd60e51b815260206004820152600460248201526310b1b3b760e11b6044820152fd5b9091604093928252602082015260a0838201526001600160a01b0361434e60a08301604090600d81526c195e135a5b9d10dd1c9b14d95d609a1b60208201520190565b921660608201526080818303910152601181527f76616c696461746f7220656e61626c656400000000000000000000000000000060208201520190565b919290603b54935f5b8581106143e05760405162461bcd60e51b815260206004820152601e60248201527f6374726c206e6f7420666f756e642c20616464206374726c20666972737400006044820152606490fd5b6001600160a01b036143f182613f41565b5054166001600160a01b03861690811461440e5750600101614394565b945094506145059060ff61442187613f41565b505460a01c161580614726575b15614653576003600161443f614d40565b5f516020615cb55f395f51905f526001600160a01b0361445e8b613f41565b5054169160405190815242602082015260a0604082015261449d60a08201604090600d81526c195e135a5b9d10dd1c9b14d95d609a1b60208201520190565b9260608201527f636f6e74726f6c6c657220656e61626c65640000000000000000000000000000602082850394856080850152601281520152604033930190a45b6144e786613f41565b50805460ff60a01b191691151560a01b60ff60a01b16919091179055565b801560018115148061463c575b156145b8575061453990835f52603c60205260405f209060ff801983541691151516179055565b60036001614545614d40565b5f516020615cb55f395f51905f5261457a6001600160a01b0361456789613f41565b505416604051918291339542908461430b565b0390a45b6001600160a01b0361458f84613f41565b505416915f52603c60205260ff6145ac8160405f20541694613f41565b505460a01c1691929190565b80614621575b6145c9575b5061457e565b6145ea90835f52603c60205260405f209060ff801983541691151516179055565b600360016145f6614d40565b5f516020615cb55f395f51905f526146186001600160a01b0361456789613f41565b0390a45f6145c3565b50825f52603c602052600160ff60405f2054161515146145be565b50835f52603c60205260ff60405f20541615614512565b60ff61465e87613f41565b505460a01c168061471e575b156144de576003600161467b614d40565b5f516020615cb55f395f51905f526001600160a01b0361469a8b613f41565b5054169160405190815242602082015260a060408201526146d960a08201604090600d81526c195e135a5b9d10dd1c9b14d95d609a1b60208201520190565b9260608201527f636f6e74726f6c6c65722064697361626c656400000000000000000000000000602082850394856080850152601381520152604033930190a46144de565b50801561466a565b508061442e565b811561494c576001600160a01b038116156148af57600254602154111561480e5761475a82600254613a03565b60215410614771579061476c91615930565b600190565b505f6002915f516020615cb55f395f51905f5261478c614d40565b60405190815242602082015260a060408201526147ca60a08201604090601081526f1b5a5b9d14dd185ad95c94995dd85c9960821b60208201520190565b9260608201527f6d696e742065786365656473206d6178737570706c7900000000000000000000602082850394856080850152601681520152604033930190a45f90565b505060015f61481b614d40565b5f516020615cb55f395f51905f526002549160405190815242602082015260a0604082015261486b60a08201604090601081526f1b5a5b9d14dd185ad95c94995dd85c9960821b60208201520190565b9260608201527f746f74616c737570706c792072656163686564206d6178737570706c79000000602082850394856080850152601d81520152604033930190a45f90565b50505f806148bb614d40565b60405190815242602082015260a060408201525f516020615cb55f395f51905f5261490760a08301604090601081526f1b5a5b9d14dd185ad95c94995dd85c9960821b60208201520190565b918360608201527f617474656d707420746f206d696e7420746f2061646472283029000000000000602082850394856080850152601a81520152604033930190a45f90565b5050600190565b919082039182116108dc57565b61496b601d54614d1d565b15614ba15761497981614db0565b15614b5c57603b54905f5b8281106149c15760405162461bcd60e51b815260206004820152600e60248201526d18dd1c9b081b9bdd08199bdd5b9960921b6044820152606490fd5b6001600160a01b036149d282613f41565b5054166001600160a01b0383168091146149ef5750600101614984565b92909150600360016149ff614d40565b5f516020615cb55f395f51905f526001600160a01b03614a1e87613f41565b50541691614a2a613c19565b9260405191825242602083015260a06040830152600d60a08301526c195e135a5b9d10dd1c9b11195b609a1b60c0830152606082015260e0608082015280614a77339460e0830190613905565b0390a45f1981019081116108dc57614a91614a9891613f41565b5091613f41565b61289e57818103614b12575b5050603b548015614afe575f1901614abb81613f41565b61289e575f9055603b55805f52603c602052600160ff60405f205416151514614ae5575b50600190565b5f52603c60205260405f2060ff1981541690555f614adf565b634e487b7160e01b5f52603160045260245ffd5b60ff826001600160a01b0380614b55955416166001600160a01b03198454161783555460a01c1681549060ff60a01b90151560a01b169060ff60a01b1916179055565b5f80614aa4565b60405162461bcd60e51b815260206004820152601360248201527f6374726c20646f6573206e6f74206578697374000000000000000000000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601260248201527f71756f726d20636f646520696e76616c756500000000000000000000000000006044820152606490fd5b600954421115614bf557505f90565b614bfe90614d1d565b90565b614c10600954600b5490613a03565b421015614c1d5760065490565b42600855614c2d600a5442613a03565b600955633b9aca00614c62614c59614c52600654614c4d42914390613a03565b613a03565b4590613a03565b60075490613a03565b6040516020810191825260208152614c7b604082613a5e565b519020068060065590565b600260055414614c97576002600555565b633ee5aeb560e01b5f5260045ffd5b6009544210614cb3575f90565b60025f601154614cc660065480926159a0565b614d14575b614cd7816017546159a0565b614cff575b614ce890601d546159a0565b614cf157101590565b614cfa90613ba1565b101590565b90614d0c614ce891613ba1565b919050614cdc565b60019150614ccb565b600954421115614d2c57505f90565b600654614d38916159a0565b61476c575f90565b6038545f191115614d5d57614d56603854613ba1565b8060385590565b5f6038555f90565b6001600160a01b0380600c54169116908114908115614d9b575b8115614d89575090565b90506001600160a01b03601854161490565b6012546001600160a01b031681149150614d7f565b603b54905f5b828110614dc4575050505f90565b6001600160a01b03614dd582613f41565b5054166001600160a01b03831614614def57600101614db6565b505050600190565b603b54905f5b828110614e0b575050505f90565b6001600160a01b03614e1c82613f41565b5054166001600160a01b0383161480614e3c575b614def57600101614dfd565b5060ff614e4882613f41565b505460a01c16614e30565b6001600160a01b0316805f52602d60205260405f2054601f541015614eb357614eaf8163bbf81e00925f52602d602052614e9160405f205442614953565b905f526028602052614eaa60405f205460235490613a98565b613a98565b0490565b505f90565b6001600160a01b03165f9081526020818152604080832054602890925290912054808210614ee957614bfe91614953565b50505f90565b91909160016022541061505d576001600160a01b03165f52602760205260405f20905f5b8254811015615064576001600160a01b036001614f3083866139d6565b500154166001600160a01b03851614614f4b57600101614f13565b919250806002614f5b84866139d6565b5001541061505d57614f7c6002614f7284866139d6565b5001918254614953565b90556002614f8a82846139d6565b5001541580615051575b614f9f575050600190565b81545f1981019081116108dc57808203614fd7575b505080548015614afe575f190190614fcf6138f883836139d6565b555f8061494c565b614fe4614fec91846139d6565b5091836139d6565b91909161289e57818114614fb4576002816001600160a01b038083945416166001600160a01b03198554161784556001600160a01b036001820154166001600160a01b036001860191166001600160a01b031982541617905501549101555f80614fb4565b50815460225410614f94565b5050505f90565b505050505f90565b80518210156139ef5760209160051b010190565b6001600160a01b0316805f52602760205260405f205461509f81613a80565b916150ad6040519384613a5e565b818352601f196150bc83613a80565b015f5b81811061516c5750505f5b8281106150d75750505090565b600190825f5260276020526001600160a01b036150f78260405f206139d6565b505416835f5260276020526001600160a01b03836151188460405f206139d6565b50015416845f52602760205260026151338460405f206139d6565b500154906040519261514484613a26565b83526020830152604082015261515a828761506c565b52615165818661506c565b50016150ca565b60209060405161517b81613a26565b5f81525f838201525f6040820152828288010152016150bf565b9060265480159081156152e2575b50506151b7906151b1615625565b50615a64565b906151c482600254613a03565b6021541061529d576001600160a01b03811615615258576151e433614df7565b61524e57505f80915f516020615cb55f395f51905f52615202614d40565b61520a613bf5565b9260405191825242602083015260a06040830152600460a0830152631b5a5b9d60e21b60c0830152606082015260e0608082015280614050339460e0830190613905565b9061476c91615930565b60405162461bcd60e51b815260206004820152601160248201527f61646472306d696e7421616c6c6f7765640000000000000000000000000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601c60248201527f746f74616c737570706c792b616d6f756e743e6d6178737570706c79000000006044820152606490fd5b600254916050820291820460501417156108dc576064900410615360575b60265461530f82600254613a03565b1161531b575f806151a3565b60405162461bcd60e51b815260206004820152601260248201527f68616c74206279206d696e74696d6974657200000000000000000000000000006044820152606490fd5b60025f61536b614d40565b60405190815242602082015260a06040820152600960a08201526817db5a5b9d10dd1c9b60ba1b60c082015283606082015260e06080820152601460e082015273383025206361706163697479207761726e696e6760601b6101008201525f516020615cb55f395f51905f526101203392a4615300565b90602654801590811561545d575b50506153fe906151b1615625565b9061540b82600254613a03565b6021541061529d576001600160a01b038116156152585761542b33614df7565b61544957505f80915f516020615cb55f395f51905f52615202614d40565b908161545882614adf94615930565b615b0a565b600254916050820291820460501417156108dc576064900410615496575b60265461548a82600254613a03565b1161531b575f806153f0565b60025f6154a1614d40565b60405190815242602082015260a06040820152600960a08201526817db5a5b9d10dd1c9b60ba1b60c082015283606082015260e06080820152601460e082015273383025206361706163697479207761726e696e6760601b6101008201525f516020615cb55f395f51905f526101203392a461547b565b60ff60375460181c166155665760ff60375460201c1661553757600190565b60405162461bcd60e51b81526020600482015260076024820152661191935052539560ca1b6044820152606490fd5b606460405162461bcd60e51b81526020600482015260046024820152634646425360e01b6044820152fd5b60ff60375460101c166155b05760ff60375460201c1661553757600190565b606460405162461bcd60e51b81526020600482015260046024820152634646435360e01b6044820152fd5b60ff60375460081c166155fa5760ff60375460201c1661553757600190565b606460405162461bcd60e51b81526020600482015260046024820152634646534360e01b6044820152fd5b60ff603754166156415760ff60375460201c1661553757600190565b606460405162461bcd60e51b815260206004820152600460248201526346464d5360e01b6044820152fd5b6001600160a01b0316805f52602a60205260405f2061568c838254613a03565b90555f52602f60205260405f20425f5260205260405f206156ae828254613a03565b90556156bc81603654613a03565b603655425f5260336020526156d660405f20918254613a03565b9055600190565b9091906001600160a01b0316801561576157805f525f60205260405f2054838110615747576020845f94957fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef938587528684520360408620558060025403600255604051908152a3565b915063391434e360e21b5f5260045260245260445260645ffd5b634b637e8f60e11b5f525f60045260245ffd5b6001600160a01b038116805f52602d60205260405f205461579760255442614953565b10614ee9576157cb906157b16157ac84614e53565b615a64565b9283915f52602d6020524260405f20556154588282615930565b5090565b6001600160a01b03601054166001600160a01b03601654168082148015615813575b156157fa575090565b90506001600160a01b03601c54168114614bfe57505f90565b506001600160a01b03601c541682146157f1565b6001600160a01b03909291921691825f52600160205260405f206001600160a01b0382165f5260205260405f2054925f198403615865575b50505050565b8284106158ac578015613422576001600160a01b0382161561340f575f5260016020526001600160a01b0360405f2091165f5260205260405f20910390555f80808061585f565b506001600160a01b038391637dc7a0d960e11b5f521660045260245260445260645ffd5b90614bfe949360e0936001600160a01b03928452602084015260a06040840152601160a08401527f5f676f764164647265737355706461746500000000000000000000000000000060c08401521660608201528160808201520190613905565b6001600160a01b031690811561598d577fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6020826159715f94600254613a03565b60025584845283825260408420818154019055604051908152a3565b63ec442f0560e01b5f525f60045260245ffd5b90606481018082116108dc5782111591826159ba57505090565b606319820192509082116108dc57101590565b6001600160a01b0316908115615761576001600160a01b031691821561598d57815f525f60205260405f2054818110615a4b57817fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92602092855f525f84520360405f2055845f525f825260405f20818154019055604051908152a3565b8263391434e360e21b5f5260045260245260445260645ffd5b615a7360215460025490614953565b9081811115615b05575060035f82615a89614d40565b9060405191825242602083015260a06040830152601360a08301527f5f61646a757374466f724d6178537570706c790000000000000000000000000060c0830152606082015260e06080820152600760e0820152661a5b9d9bdad95960ca1b6101008201525f516020615cb55f395f51905f526101203392a490565b905090565b81615b16575050600190565b6001600160a01b0316805f52602960205260405f20615b36838254613a03565b90555f52602e60205260405f20425f5260205260405f20615b58828254613a03565b9055615b6681603554613a03565b603555425f526032602052615b8060405f20918254613a03565b90555f8061494c565b9081518110156139ef570160200190565b6001600160a01b0316604051615bb1604082613a5e565b601081526f181899199a1a9b1b9c1cb0b131b232b360811b602082015260405191615bdd606084613a5e565b602a83526020830160403682378351156139ef57603090538251600110156139ef57607860218401535f5b60148110615c165750505090565b600c81018082116108dc5760208110156139ef5782901a906001600160f81b0319615c48600484901c600f1686615b89565b5116918160011b92828404600214831517156108dc578360020190816002116108dc57615c78905f1a9188615b89565b536001600160f81b031990615c9090600f1686615b89565b511691600301806003116108dc57615cad6001935f1a9187615b89565b5301615c0856feac3f3c836d294cc63876c73af7cd90e2e9938e01472164d046fa217ea075169ba2646970667358221220abedb7cda9e65829a8ff56f1504f6ef6814ac7caef106d1414989c61c2b94eeb64736f6c634300081b00330000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405260043610156100ec575b36156100595760405162461bcd60e51b815260206004820152601660248201527f436c6f73652c20627574206e6f2063696761722e2e2e000000000000000000006044820152606490fd5b610061614c86565b5f600361006c614d40565b60405190815242602082015260a06040820152600760a0820152667265636569766560c81b60c082015234606082015260e06080820152601560e08201527f6e617469766520746f6b656e20726563656976656400000000000000000000006101008201525f516020615cb55f395f51905f526101203392a46001600555005b5f3560e01c806302169792146137065780630435e393146136a857806306fdde03146135ed578063095ea7b31461336857806310e408a914612e4e578063158ea43d14612e1c57806318160ddd14612dff5780631a968f7814612d9d578063228cb73314612d8257806323b872dd14612c7657806324e770d014612c5c57806326cb131014612c3857806329fb7ef614612af25780632def6620146129755780632eaeb0fd14612728578063313ce5671461270d5780633ed10b92146126f157806340c10f19146126b05780634220b0ff1461266957806342966c681461262257806346205ec9146126055780634b8367ca146125c15780634e71d92d146124f05780636150aad1146123f957806368efcb50146123a15780636bc6c5a91461233f57806370337b331461228e57806370a082311461226b578063725264f7146121335780637364f0e5146120df57806379cc679014611fac5780638c40bbf814611f7c57806395d89b4114611e74578063a694fc3a14611cac578063a9059cbb14611c4d578063aae9261114611449578063ab8e786f146113af578063aeba297c14610f0b578063affed0e014610edd578063b69ef8a814610d85578063b7b2d03614610d6b578063b87b601614610ced578063bacd99ff14610c6c578063bb0ccf1214610c2c578063bc9b60a414610b61578063c199498514610aa2578063cda64d9414610a2f578063d5abeb0114610a12578063d60ed7fa146109ce578063d77c587f146109a3578063d98da96a14610944578063dd62ed3e146108f0578063df705e0714610897578063eff8e69514610831578063f1640e981461072a578063facd743b146106ed5763fda1a04e0361000e57346106e9575f3660031901126106e95761038461037f33614d65565b613baf565b61038c614c86565b600c546001600160a01b038116906001600160a01b0360125416906001600160a01b0360185416926001600160a01b03601354166001600160a01b036019541681145f146106da576001600160a01b03905b1680926001600160a01b03191617600c5503610639575b6001600160a01b03600e54166001600160a01b03601a541681145f14610626576001600160a01b03905b1690816001600160a01b0319601254161760125503610592575b6001600160a01b03600f54166001600160a01b036015541681145f1461057f576001600160a01b03905b1690816001600160a01b03196018541617601855036104eb575b6001600160a01b03600c54166001600160a01b0360125416906104e76001600160a01b03601854166104ad6157cf565b9060016005556040519485948592936001600160a01b03809296958160609581608089019a16885216602087015216604085015216910152565b0390f35b600460016104f7614d40565b5f516020615cb55f395f51905f526001600160a01b03601854169160405190815242602082015260a0604082015261054760a08201604090600781526619dbd15b1958dd60ca1b60208201520190565b9260608201526f115e1958dd5d1bdc88195b1958dd195960821b602082850394856080850152601081520152604033930190a461047d565b506001600160a01b038060185416610463565b6004600161059e614d40565b5f516020615cb55f395f51905f526001600160a01b03601254169160405190815242602082015260a060408201526105ee60a08201604090600781526619dbd15b1958dd60ca1b60208201520190565b9260608201526f11dd585c991a585b88195b1958dd195960821b602082850394856080850152601081520152604033930190a4610439565b506001600160a01b03806012541661041f565b60046001610645614d40565b5f516020615cb55f395f51905f526001600160a01b03600c54169160405190815242602082015260a0604082015261069560a08201604090600781526619dbd15b1958dd60ca1b60208201520190565b9260608201527f437573746f6469616c20656c6563746564000000000000000000000000000000602082850394856080850152601181520152604033930190a46103f5565b506001600160a01b03816103de565b5f80fd5b346106e95760203660031901126106e9576001600160a01b0361070e613929565b165f52603c602052602060ff60405f2054166040519015158152f35b346106e95760403660031901126106e957610743613929565b61075e6001600160a01b036107566157cf565b1633146142a7565b610766614c86565b60206001600160a01b03604461077a6157cf565b5f83604051968795869463a9059cbb60e01b86521660048501526024356024850152165af1908115610826575f916107eb575b50156107ba576001600555005b60405162461bcd60e51b81526020600482015260096024820152681d1e0819985a5b195960ba1b6044820152606490fd5b90506020813d60201161081e575b8161080660209383613a5e565b810103126106e9575180151581036106e957816107ad565b3d91506107f9565b6040513d5f823e3d90fd5b346106e9575f3660031901126106e9576001600160a01b03600c54163314801561087e575b61085f906142d9565b610867614c86565b6020610871614c01565b6001600555604051908152f35b5061085f6001600160a01b036012541633149050610856565b346106e9575f3660031901126106e9576108b361037f33614d65565b6009544281035f4212828212811690838313901516176108dc5760409182519182526020820152f35b634e487b7160e01b5f52601160045260245ffd5b346106e95760403660031901126106e957610909613929565b6001600160a01b0361091961393f565b91165f5260016020526001600160a01b0360405f2091165f52602052602060405f2054604051908152f35b346106e95760203660031901126106e9576001600160a01b03600c54163314801561098a575b610973906142d9565b6020610980600435614be6565b6040519015158152f35b506109736001600160a01b03601254163314905061096a565b346106e95760203660031901126106e95760206109c66109c1613929565b614e53565b604051908152f35b346106e95760403660031901126106e9576001600160a01b036109ef613929565b165f52602f60205260405f206024355f52602052602060405f2054604051908152f35b346106e9575f3660031901126106e9576020602154604051908152f35b346106e95760203660031901126106e9576020610a93610a4d613929565b610a5d610a58614ca6565b613aff565b610a70610a6b601d54614d1d565b613b39565b610a866001600160a01b03601854163314613b6f565b610a8e614c86565b614960565b60016005556040519015158152f35b346106e9575f3660031901126106e9576101e069ffffffffffffffffffff601e541660ff601f5460225460245460255460235460025490602154926020549460265496603754986040519b8c5260208c015260408b015260608a0152608089015260a088015260c087015260e0860152610100850152610120840152818160201c1615156101408401528181161515610160840152818160181c161515610180840152818160081c1615156101a084015260101c1615156101c0820152f35b346106e95760203660031901126106e9576020610ba8610b7f613929565b610b926001600160a01b036107566157cf565b610b9a614c86565b610ba2615591565b50615774565b80610bba576001600555604051908152f35b600480610bc5614d40565b604051908152428582015260a06040820152600760a0820152666f72436c61696d60c81b60c082015283606082015260e06080820152600760e08201526618db185a5b595960ca1b6101008201525f516020615cb55f395f51905f526101203392a4610871565b346106e95760403660031901126106e9576020610a93610c4a613929565b610c5b610c5633614df7565b613f59565b610c63614c86565b602435906153e2565b346106e9575f3660031901126106e957610c8861037f33614d65565b6001600160a01b03600c54166001600160a01b0360125416906104e76001600160a01b0360185416610cb86157cf565b906040519485948592936001600160a01b03809296958160609581608089019a16885216602087015216604085015216910152565b346106e9575f3660031901126106e9576001600160a01b03600c541633148015610d52575b610d1b906142d9565b60c0600654600754600854600954600a5491600b5493604051958652602086015260408501526060840152608083015260a0820152f35b50610d1b6001600160a01b036012541633149050610d12565b346106e9575f3660031901126106e9576020610980614ca6565b346106e9575f3660031901126106e9576101a05f5f5f90335f525f602052670de0b6b3a764000060405f20541015610ebf575b670de0b6b3a7640000610dca33614eb8565b1015610ea4575b335f526028602052670de0b6b3a764000060405f20541015610e87575b610df733614eb8565b91335f52602860205260405f205490335f525f60205260405f2054335f52602960205260405f2054335f52602a60205260405f205491603454936035549560025497603654996040519b8c5260208c015260408b015260608a0152608089015260a088015260c087015260e086015261010085015261012084015261014083015261016082015242610180820152f35b50335f526028602052670de0b6b3a764000060405f205404610dee565b9150670de0b6b3a7640000610eb833614eb8565b0491610dd1565b9050335f525f602052670de0b6b3a764000060405f20540490610db8565b346106e9575f3660031901126106e957610ef961037f33614d65565b610f01614c86565b6020610871614d40565b346106e95760a03660031901126106e95760043569ffffffffffffffffffff81168091036106e9576024356044356064359160843593610f4c610a58614ca6565b610f5a610a6b601d54614d1d565b610f706001600160a01b03601854163314613b6f565b610f78614c86565b80151580611397575b6112f7575b50801515806112eb575b61122d575b508060255403611179575b5080602354036110b6575b508060225403610ff6575b60a069ffffffffffffffffffff601e5416602454602554602354906022549260016005556040519485526020850152604084015260608301526080820152f35b60026004916103e881115f146110b0576103e85b6022555f516020615cb55f395f51905f52611023614d40565b60405190815242602082015260a0604082015261105c60a08201604090600b81526a195e11db1bd8985b14d95d60aa1b60208201520190565b92606082015264706461746560d81b604082850394856080850152602581527f6d6178696d756d20616c6c6f77616e636573207065722061646472657373207560208201520152606033930190a480610fb6565b8061100a565b600260049161271081115f14611173576127105b6023555f516020615cb55f395f51905f526110e3614d40565b60405190815242602082015260a0604082015261111c60a08201604090600b81526a195e11db1bd8985b14d95d60aa1b60208201520190565b92606082015267081d5c19185d195960c21b604082850394856080850152602881527f7374616b6520616e6e75616c2070657263656e7420726577617264207261746560208201520152606033930190a481610fab565b806110ca565b610e108111156112285750610e105b60255560046002611197614d40565b5f516020615cb55f395f51905f526025549160405190815242602082015260a060408201526111e260a08201604090600b81526a195e11db1bd8985b14d95d60aa1b60208201520190565b9260608201527f636c61696d20636f6f6c646f776e207570646174656400000000000000000000602082850394856080850152601681520152604033930190a482610fa0565b611188565b6002600491670de0b6b3a764000081105f146112e557670de0b6b3a76400005b6024555f516020615cb55f395f51905f52611266614d40565b60405190815242602082015260a0604082015261129f60a08201604090600b81526a195e11db1bd8985b14d95d60aa1b60208201520190565b9260608201527f6d696e696d756d207374616b6520616d6f756e74207570646174656400000000602082850394856080850152601c81520152604033930190a483610f95565b8061124d565b50806024541415610f90565b60028160049269ffffffffffffffffffff19601e541617601e555f516020615cb55f395f51905f52611327614d40565b60405190815242602082015260a0604082015261136060a08201604090600b81526a195e11db1bd8985b14d95d60aa1b60208201520190565b9260608201526d199d595b1259081d5c19185d195960921b602082850394856080850152600e81520152604033930190a484610f86565b508069ffffffffffffffffffff601e54161415610f81565b346106e95760403660031901126106e9576113c8613929565b6113d4610c5633614df7565b335f52603c602052600160ff60405f20541615150361140457610a936020916113fb614c86565b6024359061472d565b60405162461bcd60e51b815260206004820152601f60248201527f76616c696461746f7220726f6c6520726571756972656420746f206d696e74006044820152606490fd5b346106e95760803660031901126106e957611462613929565b61146a61393f565b6044356001600160a01b038116908181036106e957606435926001600160a01b038416948585036106e9576114a161037f33614d65565b6114a9614c86565b6001600160a01b0381169081151580611c3b575b80611c32575b15611bd9576001600160a01b03600c54163314611a37575b6001600160a01b03601254163314611873575b6001600160a01b03601854163314611587575b6004600161150d614d40565b60405190815242602082015260a06040820152600660a08201526519dbdd94d95d60d21b60c082015281606082015260e06080820152600f60e08201526e75706461746520636f6d706c65746560881b6101008201525f516020615cb55f395f51905f526101203392a46001600555602060405160018152f35b6001600160a01b0360185416330361150157816001600160a01b0360195416036117e5575b50506001600160a01b03601a5416906001600160a01b038116809203611757575b5050816001600160a01b03601b5416036116b2575b5050816001600160a01b03601c541603611601575b8080808080611501565b60016003915f516020615cb55f395f51905f52602061161e614d40565b9261168460386116396001600160a01b036018541693615b9a565b6040519485917f6f7261636c6520766f7465207570646174656420746f3a200000000000000000828401528051918291018484015e81015f838201520301601f198101845283613a5e565b61169760405192839233964290856158d0565b0390a46001600160a01b0319601c541617601c5580806115f7565b60016003915f516020615cb55f395f51905f5261173c602061172b603a6116e06116da614d40565b96615b9a565b6040519384917f6578656375746f7220766f7465207570646174656420746f3a20000000000000828401528051918291018484015e81015f838201520301601f198101835282613a5e565b6040519182918833964290856158d0565b0390a46001600160a01b0319601b541617601b5582806115e2565b60016003915f516020615cb55f395f51905f526117ca602061172b603a61177f6116da614d40565b6040519384917f677561726469616e20766f7465207570646174656420746f3a20000000000000828401528051918291018484015e81015f838201520301601f198101835282613a5e565b0390a46001600160a01b0319601a541617601a5584806115cd565b60016003915f516020615cb55f395f51905f52611858602061172b603b61180d6116da614d40565b6040519384917f637573746f6469616c20766f7465207570646174656420746f3a200000000000828401528051918291018484015e81015f838201520301601f198101835282613a5e565b0390a46001600160a01b0319601954161760195585806115ac565b6001600160a01b036012541633036114ee57816001600160a01b0360135416036119df575b6001600160a01b03601454166001600160a01b038416809103611998575b50846001600160a01b036015541603611940575b6016546001600160a01b031687146114ee57600360016118e8614d40565b5f516020615cb55f395f51905f5260208a61191360386116396001600160a01b036012541693615b9a565b61192660405192839233964290856158d0565b0390a4866001600160a01b031960165416176016556114ee565b6003600161194c614d40565b5f516020615cb55f395f51905f5261197e602061196d603a6116e08c615b9a565b6040519182918c33964290856158d0565b0390a4846001600160a01b031960155416176015556118ca565b600360016119a4614d40565b5f516020615cb55f395f51905f526119c5602061172b603a61177f8c615b9a565b0390a46001600160a01b03196014541617601455876118b6565b600360016119eb614d40565b5f516020615cb55f395f51905f52611a1d6020611a0c603b61180d89615b9a565b6040519182918933964290856158d0565b0390a4816001600160a01b03196013541617601355611898565b6001600160a01b03600c541633036114db57816001600160a01b03600d541603611b92575b6001600160a01b03600e54166001600160a01b038416809103611b4b575b50846001600160a01b03600f541603611b04575b6010546001600160a01b031687146114db5760036001611aac614d40565b5f516020615cb55f395f51905f5260208a611ad760386116396001600160a01b03600c541693615b9a565b611aea60405192839233964290856158d0565b0390a4866001600160a01b031960105416176010556114db565b60036001611b10614d40565b5f516020615cb55f395f51905f52611b31602061196d603a6116e08c615b9a565b0390a4846001600160a01b0319600f541617600f55611a8e565b60036001611b57614d40565b5f516020615cb55f395f51905f52611b78602061172b603a61177f8c615b9a565b0390a46001600160a01b0319600e541617600e5587611a7a565b60036001611b9e614d40565b5f516020615cb55f395f51905f52611bbf6020611a0c603b61180d89615b9a565b0390a4816001600160a01b0319600d541617600d55611a5c565b60405162461bcd60e51b815260206004820152602b60248201527f6f6e6c79206f7261636c65206d617920657175616c206164647265737328302960448201526a202864697361626c65642960a81b6064820152608490fd5b508415156114c3565b506001600160a01b03831615156114bd565b346106e95760403660031901126106e957611c9c611c69613929565b60243590611c75614c86565b611c968280611c8333614eb8565b1015611c8e33614eb8565b903390613eff565b336159cd565b6001600555602060405160018152f35b346106e95760203660031901126106e957600435611cc8614c86565b611cd06155db565b505f6024548210611e4057611ce433614eb8565b8211611e0d57602091335f52602d8352611d0f611d0860405f205460255490613a03565b421161426a565b335f52602d835260405f2054601f541115611df5575b6003600491335f526028855260405f20611d40828254613a03565b9055335f52602b85524260405f2055335f52602d85524260405f2055425f526030855260405f20611d72828254613a03565b9055611d8081603454613a03565b6034555f516020615cb55f395f51905f52611d99614d40565b611da1613c19565b92604051918252428883015260a06040830152600560a0830152647374616b6560d81b60c0830152606082015260e0608082015280611de5339460e0830190613905565b0390a46001600555604051908152f35b905060046003611e0433615774565b92915050611d25565b60405162461bcd60e51b815260206004820152600b60248201526a616d743e62616c616e636560a81b6044820152606490fd5b60405162461bcd60e51b815260206004820152600c60248201526b30b6ba1e39ba30b5b2b6b4b760a11b6044820152606490fd5b346106e9575f3660031901126106e9576040515f6004548060011c90600181168015611f72575b602083108114611f5e57828552908115611f3a5750600114611edc575b6104e783611ec881850382613a5e565b604051918291602083526020830190613905565b91905060045f527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b915f905b808210611f2057509091508101602001611ec8611eb8565b919260018160209254838588010152019101909291611f08565b60ff191660208086019190915291151560051b84019091019150611ec89050611eb8565b634e487b7160e01b5f52602260045260245ffd5b91607f1691611e9b565b346106e95760203660031901126106e9576104e7611fa0611f9b613929565b615080565b60405191829182613973565b346106e95760403660031901126106e957612028611fc8613929565b60243590611fd4614c86565b611fdc615518565b50611ffd8280611feb84614eb8565b101583611ff781614eb8565b91613eff565b6022541515806120cd575b61202f575b612018823383615827565b612022828261566c565b506156dd565b6001600555005b60015f61203a614d40565b60405190815242602082015260a06040820152600860a0820152676275726e46726f6d60c01b60c082015284606082015260e06080820152602a60e08201527f6661696c656420746f20646563726561736520747261636b656420616c6c6f7761010082015269616e63652076616c756560b01b6101208201525f516020615cb55f395f51905f526101403392a461200d565b506120d9823383614eef565b15612008565b346106e9575f3660031901126106e9576120fb61037f33614d65565b60e0600854600954600a54600b5491604051934385524260208601524560408601526060850152608084015260a083015260c0820152f35b346106e9575f3660031901126106e95761214c33614d65565b61215590613baf565b600c546001600160a01b0316600d546001600160a01b031690600e546001600160a01b0316600f546001600160a01b03166010546001600160a01b03166012546001600160a01b03166013546001600160a01b03166014546001600160a01b03166015546001600160a01b0316906016546001600160a01b0316926018546001600160a01b0316946019546001600160a01b031696601a546001600160a01b031698601b546001600160a01b03169a601c546001600160a01b03169c6040519e8f91825260208201526040015260608d015260808c015260a08b015260c08a015260e08901526101008801526101208701526101408601526101608501526101808401526101a08301526101c08201526101e090f35b346106e95760203660031901126106e95760206109c6612289613929565b614eb8565b346106e95760603660031901126106e95760606123016122ac613929565b6122b4613955565b6122bc613964565b916122c8610a58614ca6565b6122d6610a6b601d54614d1d565b6001600160a01b03600c541633148015612326575b6122f4906142d9565b6122fc614c86565b61438b565b9060016005556001600160a01b03604051931683521515602083015215156040820152f35b506122f46001600160a01b0360125416331490506122eb565b346106e95760203660031901126106e9575f80808060043561236a6001600160a01b036107566157cf565b612372614c86565b6001600160a01b036123826157cf565b16828215612398575bf115610826576001600555005b506108fc61238b565b346106e95760203660031901126106e9576004355f9081526032602090815260408083205460308352818420546031845282852054603385529483902054835192835293820152908101929092526060820152608090f35b346106e9575f3660031901126106e957603b5461241581613a80565b906124236040519283613a5e565b808252602082019081603b5f527fbbe3212124853f8b0084a66a2d057c2966e251e132af3691db153ab65f0d1a4d5f915b8383106124b6578486604051918291602083019060208452518091526040830191905f5b818110612486575050500390f35b825180516001600160a01b0316855260209081015115158186015286955060409094019390920191600101612478565b6001602081926040516124c881613a42565b60ff86546001600160a01b038116835260a01c16151583820152815201920192019190612454565b346106e9575f3660031901126106e957612508614c86565b612510615591565b50335f52602d60205261252d611d0860405f205460255490613a03565b60016023541061259357600254602154111561254e57602061087133615774565b60405162461bcd60e51b815260206004820152601860248201527f6d6178737570706c7920696e2063697263756c6174696f6e00000000000000006044820152606490fd5b60405162461bcd60e51b81526020600482015260066024820152654150523d302560d01b6044820152606490fd5b346106e95760403660031901126106e9576001600160a01b036125e2613929565b165f52602e60205260405f206024355f52602052602060405f2054604051908152f35b346106e9575f3660031901126106e9576020603854604051908152f35b346106e95760203660031901126106e957612028600435612641614c86565b612649615518565b506126588180611c8333614eb8565b612662813361566c565b50336156dd565b346106e9575f3660031901126106e957612684610a58614ca6565b612692610a6b601d54614d1d565b61269e61037f33614d65565b6126a6614c86565b6020610a93613fa5565b346106e95760403660031901126106e9576126e96126cc613929565b6126d8610c5633614df7565b6126e0614c86565b60243590615195565b506001600555005b346106e9575f3660031901126106e9576104e7611fa033615080565b346106e9575f3660031901126106e957602060405160128152f35b346106e95760203660031901126106e957612741613929565b61274c610a58614ca6565b61275a610a6b601d54614d1d565b6127706001600160a01b03601854163314613b6f565b612778614c86565b612783601d54614d1d565b156129305761279181614db0565b6128fd576103e8603b5410156128c5576001600160a01b03604051916127b683613a42565b168082526003600260208401925f84525f516020615cb55f395f51905f526127dc614d40565b6127e4613c19565b9260405191825242602083015260a06040830152600d60a08301526c195e135a5b9d10dd1c9b105919609a1b60c0830152606082015260e0608082015280612831339460e0830190613905565b0390a4603b54600160401b8110156128b1578060016128539201603b55613f41565b91909161289e5791518154925174ffffffffffffffffffffffffffffffffffffffffff199093166001600160a01b03919091161791151560a01b60ff60a01b16919091179055611c9c565b634e487b7160e01b5f525f60045260245ffd5b634e487b7160e01b5f52604160045260245ffd5b60405162461bcd60e51b815260206004820152601060248201526f1b585e18dd1c9b1cc81c995858da195960821b6044820152606490fd5b60405162461bcd60e51b815260206004820152600b60248201526a6374726c2065786973747360a81b6044820152606490fd5b60405162461bcd60e51b815260206004820152601260248201527f71756f726d20636f646520696e76616c696400000000000000000000000000006044820152606490fd5b346106e9575f3660031901126106e95761298d614c86565b5f335f52602860205260405f2054908115612aad57602091335f52602d835260405f2054601f541115612a95575b6003600491335f52602885525f6040812055335f52602b85525f6040812055335f52602d85525f6040812055335f52602c85524260405f20558060345410155f14612a8c57612a0c81603454614953565b6034555b425f526031855260405f20612a26828254613a03565b90555f516020615cb55f395f51905f52612a3e614d40565b612a46613c19565b92604051918252428883015260a06040830152600760a083015266756e7374616b6560c81b60c0830152606082015260e0608082015280611de5339460e0830190613905565b5f603455612a10565b905060046003612aa433615774565b929150506129bb565b60405162461bcd60e51b815260206004820152601460248201527f6e6f20746f6b656e7320746f20756e7374616b650000000000000000000000006044820152606490fd5b346106e95760203660031901126106e957600435612b11610a58614ca6565b612b1f610a6b601d54614d1d565b612b2b61037f33614d65565b612b33614c86565b603a54811180612c035760049160039115612bfa575b612b51614d40565b9060405191825242602083015260a06040830152601a60a08301527f7570646174655374616b6572526577617264506572426c6f636b00000000000060c0830152606082015260e06080820152602960e08201527f6e65772076616c696461746f72207374616b657220726577617264207065722061010082015268189b1bd8dac81cd95d60ba1b6101208201525f516020615cb55f395f51905f526101403392a46001600555005b80603955612b49565b60405162461bcd60e51b815260206004820152600d60248201526c0ecc2d87ce4caeec2e4c89ac2f609b1b6044820152606490fd5b346106e9575f3660031901126106e9576040603954603a5482519182526020820152f35b346106e9575f3660031901126106e95760206109c6613f2b565b346106e95760603660031901126106e957611c9c612c92613929565b612c9a61393f565b60443591612ca6614c86565b612cb48380611feb84614eb8565b602254151580612d70575b612cd4575b612ccf833383615827565b6159cd565b60015f612cdf614d40565b60405190815242602082015260a06040820152600c60a08201526b7472616e7366657246726f6d60a01b60c082015285606082015260e06080820152602460e08201527f6661696c656420746f20646563726561736520747261636b656420616c6c6f7761010082015263616e636560e01b6101208201525f516020615cb55f395f51905f526101403392a4612cc4565b50612d7c833383614eef565b15612cbf565b346106e9575f3660031901126106e95760206109c633614e53565b346106e95760203660031901126106e9576040612def612dbb613929565b612dc6610a58614ca6565b612dd4610a6b601d54614d1d565b612dea6001600160a01b03601854163314613b6f565b613edc565b8251911515825215156020820152f35b346106e9575f3660031901126106e9576020600254604051908152f35b346106e95760203660031901126106e957612e3961037f33614d65565b612e41614c86565b6020610a93600435613c3e565b346106e95760a03660031901126106e9576004358015158082036106e957612e74613955565b612e7c613964565b9060643591821515918284036106e95760843595861515958688036106e957612ea6610a58614ca6565b612eb4610a6b601d54614d1d565b612eca6001600160a01b03601854163314613b6f565b612ed2614c86565b603754918160ff8460101c16151503613297575b50505060375490801515908160ff84161515036131cd575b50505060375490801515908160ff8460081c161515036130fe575b505050603754918160ff8460181c1615150361302b575b505050603754918160ff8460201c16151503612f56576001600555602060405160018152f35b60039264ff00000000849360201b169064ff00000000191617603755612f7a614d40565b9015613016575f516020615cb55f395f51905f526001915b60405190815242602082015260a0604082015260ff612fcd60a08301604090600b81526a195e14da1a595b1914d95d60aa1b60208201520190565b931660608201527f6d61696e74656e616e6365206d6f646520757064617465640000000000000000602082850394856080850152601881520152604033930190a4808080611c9c565b5f516020615cb55f395f51905f525f91612f92565b60039263ff000000849360181b169063ff00000019161760375561304d614d40565b90156130e9575f516020615cb55f395f51905f526001915b60405190815242602082015260a0604082015260ff6130a060a08301604090600b81526a195e14da1a595b1914d95d60aa1b60208201520190565b931660608201527f6275726e736869656c6420757064617465640000000000000000000000000000602082850394856080850152601281520152604033930190a4828080612f30565b5f516020615cb55f395f51905f525f91613065565b60039261ff00849360081b169061ff0019161760375561311c614d40565b90156131b8575f516020615cb55f395f51905f526001915b60405190815242602082015260a0604082015260ff61316f60a08301604090600b81526a195e14da1a595b1914d95d60aa1b60208201520190565b931660608201527f7374616b65736869656c64207570646174656400000000000000000000000000602082850394856080850152601381520152604033930190a4848080612f19565b5f516020615cb55f395f51905f525f91613134565b60039260ff8493169060ff1916176037556131e6614d40565b9015613282575f516020615cb55f395f51905f526001915b60405190815242602082015260a0604082015260ff61323960a08301604090600b81526a195e14da1a595b1914d95d60aa1b60208201520190565b931660608201527f6d696e7473736869656c64207570646174656400000000000000000000000000602082850394856080850152601381520152604033930190a4858080612efe565b5f516020615cb55f395f51905f525f916131fe565b60039262ff0000849360101b169062ff00001916176037556132b7614d40565b9015613353575f516020615cb55f395f51905f526001915b60405190815242602082015260a0604082015260ff61330a60a08301604090600b81526a195e14da1a595b1914d95d60aa1b60208201520190565b931660608201527f636c61696d736869656c64207570646174656400000000000000000000000000602082850394856080850152601381520152604033930190a4868080612ee6565b5f516020615cb55f395f51905f525f916132cf565b346106e95760403660031901126106e957613381613929565b6024359061338d614c86565b335f52602760205260405f20546022548110613435575b503315613422576001600160a01b031690811561340f57335f52600160205260405f20825f526020528060405f20556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a36001600555602060405160018152f35b634a1406b160e11b5f525f60045260245ffd5b63e602df0560e01b5f525f60045260245ffd5b5f9291906001600160a01b038216845b335f52602760205260405f20548110806135e1575b156135d757335f526027602052816001600160a01b03600161347f8460405f206139d6565b50015416146134965761349190613ba1565b613445565b8495506134b56002919592939495335f52602760205260405f206139d6565b50015560015b1561357d575b50600a8102818104600a14821517156108dc57602254906009820291808304600914901517156108dc5711156133a4575f6002916134fd614d40565b9060405191825242602083015260a06040830152600860a083015267185c1c1c9bdd985b60c21b60c0830152606082015260e06080820152601460e08201527f393025206361706163697479207761726e696e670000000000000000000000006101008201525f516020615cb55f395f51905f526101203392a4826133a4565b6040519061358a82613a26565b3382526020820152836040820152335f52602760205260405f208054600160401b8110156128b1576135c1916001820181556139d6565b91909161289e576135d191613aab565b836134c1565b50909192936134bb565b5060225481111561345a565b346106e9575f3660031901126106e9576040515f6003548060011c9060018116801561369e575b602083108114611f5e57828552908115611f3a5750600114613640576104e783611ec881850382613a5e565b91905060035f527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b915f905b80821061368457509091508101602001611ec8611eb8565b91926001816020925483858801015201910190929161366c565b91607f1691613614565b346106e95760203660031901126106e95760206004356136c9610a58614ca6565b6136d7610a6b601d54614d1d565b6136ed6001600160a01b03601854163314613b6f565b6136f5614c86565b806026556001600555604051908152f35b346106e9575f3660031901126106e95761371e614c86565b5f335f52602760205260405f20545f33155b82821061383c575050604051613747602082613a5e565b5f81525f805b818110613813575050335f52602760205260405f20815191600160401b83116128b15781548383558084106137c5575b50602001905f5260205f205f915b8383106137a75760408587600160055582519182526020820152f35b60036020826137b96001945186613aab565b0192019201919061378b565b806003029060038204036108dc57836003026003810485036108dc57835f5260205f2091820191015b8181106137fb575061377d565b6003905f81555f60018201555f6002820155016137ee565b60209060405161382281613a26565b5f81525f838201525f60408201528282860101520161374d565b613862819294335f52602760205260026138598760405f206139d6565b50015490613a03565b93335f5260276020526001600160a01b0360016138828360405f206139d6565b500154169161342257811561340f57600191335f528260205260405f206001600160a01b0382165f526020525f60408120556040515f81527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3335f5260276020526138fe6138f88260405f206139d6565b90613a10565b0190613730565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b600435906001600160a01b03821682036106e957565b602435906001600160a01b03821682036106e957565b6024359081151582036106e957565b6044359081151582036106e957565b60206040818301928281528451809452019201905f5b8181106139965750505090565b90919260206060600192604087516001600160a01b0381511683526001600160a01b03858201511685840152015160408201520194019101919091613989565b80548210156139ef575f52600360205f20910201905f90565b634e487b7160e01b5f52603260045260245ffd5b919082018092116108dc57565b9061289e576002815f8093558260018201550155565b6060810190811067ffffffffffffffff8211176128b157604052565b6040810190811067ffffffffffffffff8211176128b157604052565b90601f8019910116810190811067ffffffffffffffff8211176128b157604052565b67ffffffffffffffff81116128b15760051b60200190565b818102929181159184041417156108dc57565b9060406002916001600160a01b0380825116166001600160a01b03198554161784556001600160a01b036020820151166001600160a01b036001860191166001600160a01b03198254161790550151910155565b15613b0657565b60405162461bcd60e51b815260206004820152600b60248201526a38bab7b93690b2b9ba30b160a91b6044820152606490fd5b15613b4057565b60405162461bcd60e51b81526020600482015260076024820152661c58dd99985a5b60ca1b6044820152606490fd5b15613b7657565b606460405162461bcd60e51b81526020600482015260046024820152632165786560e01b6044820152fd5b5f1981146108dc5760010190565b15613bb657565b606460405162461bcd60e51b815260206004820152600460248201526310b3b7bb60e11b6044820152fd5b9060ff8091169116019060ff82116108dc57565b60405190613c04604083613a5e565b600682526511985a5b195960d21b6020830152565b60405190613c28604083613a5e565b60078252665375636365737360c81b6020830152565b905f916001600160a01b03600c54163314613ed3575b6001600160a01b03601254163314613eca575b6001600160a01b03601854163314613ec1575b5060ff613cc9613c8b601154614d1d565b613cbb613c99601754614d1d565b613ca4601d54614d1d565b9215613eba576001905b15613eb357600190613be1565b9015613eb357600190613be1565b1660028110613d6457509050613ce1600a5442613a03565b60095560046001613cf0614d40565b5f516020615cb55f395f51905f52613d06613c19565b9160405190815242602082015260a0604082015280613d5c613d4760a08301604090600e81526d32bc29b2b9b9b4b7b722b73a32b960911b60208201520190565b86606084015282810360808401523395613905565b0390a4600190565b80613de7575060026001613d76614d40565b5f516020615cb55f395f51905f52613d8c613bf5565b9160405190815242602082015260a0604082015280613de2613dcd60a08301604090600e81526d32bc29b2b9b9b4b7b722b73a32b960911b60208201520190565b5f606084015282810360808401523395613905565b0390a4565b600114613df057565b905060036001613dfe614d40565b60405190815242602082015260a060408201525f516020615cb55f395f51905f52613e4860a08301604090600e81526d32bc29b2b9b9b4b7b722b73a32b960911b60208201520190565b915f60608201527f72206d656d62657220746f20656e74657220636f646500000000000000000000604082850394856080850152603681527f636f64652061636365707465642c206177616974696e67206f6e65206f74686560208201520152606033930190a45f90565b5f90613be1565b5f90613cae565b601d555f613c7a565b80601755613c67565b80601155613c54565b613ee581614db0565b15613ef857613ef390614df7565b600191565b505f905f90565b15613f0957505050565b6001600160a01b039063391434e360e21b5f521660045260245260445260645ffd5b6002546020541015613f3b575f90565b60395490565b603b548110156139ef57603b5f5260205f2001905f90565b15613f6057565b60405162461bcd60e51b815260206004820152601e60248201527f6d696e746374726c20726f6c6520726571756972656420746f206d696e7400006044820152606490fd5b6001600160a01b03600c5416331480614259575b6141b9576001600160a01b03601254163314806141a8575b614108576001600160a01b03601854163314806140f7575b6140575760026001613ff9614d40565b5f516020615cb55f395f51905f5261400f613bf5565b9160405190815242602082015260a0604082015280614050613dcd60a08301604090600e81526d657853657373696f6e436c6f736560901b60208201520190565b0390a45f90565b4260095560046001614067614d40565b60405190815242602082015260a060408201525f516020615cb55f395f51905f526140b160a08301604090600e81526d657853657373696f6e436c6f736560901b60208201520190565b918360608201527f436c6f736564206279206578656375746f720000000000000000000000000000602082850394856080850152601281520152604033930190a4600190565b50614103601d54614d1d565b613fe9565b4260095560046001614118614d40565b60405190815242602082015260a060408201525f516020615cb55f395f51905f5261416260a08301604090600e81526d657853657373696f6e436c6f736560901b60208201520190565b918360608201527f436c6f73656420627920677561726469616e0000000000000000000000000000602082850394856080850152601281520152604033930190a4600190565b506141b4601754614d1d565b613fd1565b42600955600460016141c9614d40565b60405190815242602082015260a060408201525f516020615cb55f395f51905f5261421360a08301604090600e81526d657853657373696f6e436c6f736560901b60208201520190565b918360608201527f436c6f73656420627920637573746f6469616c00000000000000000000000000602082850394856080850152601381520152604033930190a4600190565b50614265601154614d1d565b613fb9565b1561427157565b60405162461bcd60e51b815260206004820152600e60248201526d72657761726420636f6f6c696e6760901b6044820152606490fd5b156142ae57565b606460405162461bcd60e51b8152602060048201526004602482015263216f726160e01b6044820152fd5b156142e057565b606460405162461bcd60e51b815260206004820152600460248201526310b1b3b760e11b6044820152fd5b9091604093928252602082015260a0838201526001600160a01b0361434e60a08301604090600d81526c195e135a5b9d10dd1c9b14d95d609a1b60208201520190565b921660608201526080818303910152601181527f76616c696461746f7220656e61626c656400000000000000000000000000000060208201520190565b919290603b54935f5b8581106143e05760405162461bcd60e51b815260206004820152601e60248201527f6374726c206e6f7420666f756e642c20616464206374726c20666972737400006044820152606490fd5b6001600160a01b036143f182613f41565b5054166001600160a01b03861690811461440e5750600101614394565b945094506145059060ff61442187613f41565b505460a01c161580614726575b15614653576003600161443f614d40565b5f516020615cb55f395f51905f526001600160a01b0361445e8b613f41565b5054169160405190815242602082015260a0604082015261449d60a08201604090600d81526c195e135a5b9d10dd1c9b14d95d609a1b60208201520190565b9260608201527f636f6e74726f6c6c657220656e61626c65640000000000000000000000000000602082850394856080850152601281520152604033930190a45b6144e786613f41565b50805460ff60a01b191691151560a01b60ff60a01b16919091179055565b801560018115148061463c575b156145b8575061453990835f52603c60205260405f209060ff801983541691151516179055565b60036001614545614d40565b5f516020615cb55f395f51905f5261457a6001600160a01b0361456789613f41565b505416604051918291339542908461430b565b0390a45b6001600160a01b0361458f84613f41565b505416915f52603c60205260ff6145ac8160405f20541694613f41565b505460a01c1691929190565b80614621575b6145c9575b5061457e565b6145ea90835f52603c60205260405f209060ff801983541691151516179055565b600360016145f6614d40565b5f516020615cb55f395f51905f526146186001600160a01b0361456789613f41565b0390a45f6145c3565b50825f52603c602052600160ff60405f2054161515146145be565b50835f52603c60205260ff60405f20541615614512565b60ff61465e87613f41565b505460a01c168061471e575b156144de576003600161467b614d40565b5f516020615cb55f395f51905f526001600160a01b0361469a8b613f41565b5054169160405190815242602082015260a060408201526146d960a08201604090600d81526c195e135a5b9d10dd1c9b14d95d609a1b60208201520190565b9260608201527f636f6e74726f6c6c65722064697361626c656400000000000000000000000000602082850394856080850152601381520152604033930190a46144de565b50801561466a565b508061442e565b811561494c576001600160a01b038116156148af57600254602154111561480e5761475a82600254613a03565b60215410614771579061476c91615930565b600190565b505f6002915f516020615cb55f395f51905f5261478c614d40565b60405190815242602082015260a060408201526147ca60a08201604090601081526f1b5a5b9d14dd185ad95c94995dd85c9960821b60208201520190565b9260608201527f6d696e742065786365656473206d6178737570706c7900000000000000000000602082850394856080850152601681520152604033930190a45f90565b505060015f61481b614d40565b5f516020615cb55f395f51905f526002549160405190815242602082015260a0604082015261486b60a08201604090601081526f1b5a5b9d14dd185ad95c94995dd85c9960821b60208201520190565b9260608201527f746f74616c737570706c792072656163686564206d6178737570706c79000000602082850394856080850152601d81520152604033930190a45f90565b50505f806148bb614d40565b60405190815242602082015260a060408201525f516020615cb55f395f51905f5261490760a08301604090601081526f1b5a5b9d14dd185ad95c94995dd85c9960821b60208201520190565b918360608201527f617474656d707420746f206d696e7420746f2061646472283029000000000000602082850394856080850152601a81520152604033930190a45f90565b5050600190565b919082039182116108dc57565b61496b601d54614d1d565b15614ba15761497981614db0565b15614b5c57603b54905f5b8281106149c15760405162461bcd60e51b815260206004820152600e60248201526d18dd1c9b081b9bdd08199bdd5b9960921b6044820152606490fd5b6001600160a01b036149d282613f41565b5054166001600160a01b0383168091146149ef5750600101614984565b92909150600360016149ff614d40565b5f516020615cb55f395f51905f526001600160a01b03614a1e87613f41565b50541691614a2a613c19565b9260405191825242602083015260a06040830152600d60a08301526c195e135a5b9d10dd1c9b11195b609a1b60c0830152606082015260e0608082015280614a77339460e0830190613905565b0390a45f1981019081116108dc57614a91614a9891613f41565b5091613f41565b61289e57818103614b12575b5050603b548015614afe575f1901614abb81613f41565b61289e575f9055603b55805f52603c602052600160ff60405f205416151514614ae5575b50600190565b5f52603c60205260405f2060ff1981541690555f614adf565b634e487b7160e01b5f52603160045260245ffd5b60ff826001600160a01b0380614b55955416166001600160a01b03198454161783555460a01c1681549060ff60a01b90151560a01b169060ff60a01b1916179055565b5f80614aa4565b60405162461bcd60e51b815260206004820152601360248201527f6374726c20646f6573206e6f74206578697374000000000000000000000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601260248201527f71756f726d20636f646520696e76616c756500000000000000000000000000006044820152606490fd5b600954421115614bf557505f90565b614bfe90614d1d565b90565b614c10600954600b5490613a03565b421015614c1d5760065490565b42600855614c2d600a5442613a03565b600955633b9aca00614c62614c59614c52600654614c4d42914390613a03565b613a03565b4590613a03565b60075490613a03565b6040516020810191825260208152614c7b604082613a5e565b519020068060065590565b600260055414614c97576002600555565b633ee5aeb560e01b5f5260045ffd5b6009544210614cb3575f90565b60025f601154614cc660065480926159a0565b614d14575b614cd7816017546159a0565b614cff575b614ce890601d546159a0565b614cf157101590565b614cfa90613ba1565b101590565b90614d0c614ce891613ba1565b919050614cdc565b60019150614ccb565b600954421115614d2c57505f90565b600654614d38916159a0565b61476c575f90565b6038545f191115614d5d57614d56603854613ba1565b8060385590565b5f6038555f90565b6001600160a01b0380600c54169116908114908115614d9b575b8115614d89575090565b90506001600160a01b03601854161490565b6012546001600160a01b031681149150614d7f565b603b54905f5b828110614dc4575050505f90565b6001600160a01b03614dd582613f41565b5054166001600160a01b03831614614def57600101614db6565b505050600190565b603b54905f5b828110614e0b575050505f90565b6001600160a01b03614e1c82613f41565b5054166001600160a01b0383161480614e3c575b614def57600101614dfd565b5060ff614e4882613f41565b505460a01c16614e30565b6001600160a01b0316805f52602d60205260405f2054601f541015614eb357614eaf8163bbf81e00925f52602d602052614e9160405f205442614953565b905f526028602052614eaa60405f205460235490613a98565b613a98565b0490565b505f90565b6001600160a01b03165f9081526020818152604080832054602890925290912054808210614ee957614bfe91614953565b50505f90565b91909160016022541061505d576001600160a01b03165f52602760205260405f20905f5b8254811015615064576001600160a01b036001614f3083866139d6565b500154166001600160a01b03851614614f4b57600101614f13565b919250806002614f5b84866139d6565b5001541061505d57614f7c6002614f7284866139d6565b5001918254614953565b90556002614f8a82846139d6565b5001541580615051575b614f9f575050600190565b81545f1981019081116108dc57808203614fd7575b505080548015614afe575f190190614fcf6138f883836139d6565b555f8061494c565b614fe4614fec91846139d6565b5091836139d6565b91909161289e57818114614fb4576002816001600160a01b038083945416166001600160a01b03198554161784556001600160a01b036001820154166001600160a01b036001860191166001600160a01b031982541617905501549101555f80614fb4565b50815460225410614f94565b5050505f90565b505050505f90565b80518210156139ef5760209160051b010190565b6001600160a01b0316805f52602760205260405f205461509f81613a80565b916150ad6040519384613a5e565b818352601f196150bc83613a80565b015f5b81811061516c5750505f5b8281106150d75750505090565b600190825f5260276020526001600160a01b036150f78260405f206139d6565b505416835f5260276020526001600160a01b03836151188460405f206139d6565b50015416845f52602760205260026151338460405f206139d6565b500154906040519261514484613a26565b83526020830152604082015261515a828761506c565b52615165818661506c565b50016150ca565b60209060405161517b81613a26565b5f81525f838201525f6040820152828288010152016150bf565b9060265480159081156152e2575b50506151b7906151b1615625565b50615a64565b906151c482600254613a03565b6021541061529d576001600160a01b03811615615258576151e433614df7565b61524e57505f80915f516020615cb55f395f51905f52615202614d40565b61520a613bf5565b9260405191825242602083015260a06040830152600460a0830152631b5a5b9d60e21b60c0830152606082015260e0608082015280614050339460e0830190613905565b9061476c91615930565b60405162461bcd60e51b815260206004820152601160248201527f61646472306d696e7421616c6c6f7765640000000000000000000000000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601c60248201527f746f74616c737570706c792b616d6f756e743e6d6178737570706c79000000006044820152606490fd5b600254916050820291820460501417156108dc576064900410615360575b60265461530f82600254613a03565b1161531b575f806151a3565b60405162461bcd60e51b815260206004820152601260248201527f68616c74206279206d696e74696d6974657200000000000000000000000000006044820152606490fd5b60025f61536b614d40565b60405190815242602082015260a06040820152600960a08201526817db5a5b9d10dd1c9b60ba1b60c082015283606082015260e06080820152601460e082015273383025206361706163697479207761726e696e6760601b6101008201525f516020615cb55f395f51905f526101203392a4615300565b90602654801590811561545d575b50506153fe906151b1615625565b9061540b82600254613a03565b6021541061529d576001600160a01b038116156152585761542b33614df7565b61544957505f80915f516020615cb55f395f51905f52615202614d40565b908161545882614adf94615930565b615b0a565b600254916050820291820460501417156108dc576064900410615496575b60265461548a82600254613a03565b1161531b575f806153f0565b60025f6154a1614d40565b60405190815242602082015260a06040820152600960a08201526817db5a5b9d10dd1c9b60ba1b60c082015283606082015260e06080820152601460e082015273383025206361706163697479207761726e696e6760601b6101008201525f516020615cb55f395f51905f526101203392a461547b565b60ff60375460181c166155665760ff60375460201c1661553757600190565b60405162461bcd60e51b81526020600482015260076024820152661191935052539560ca1b6044820152606490fd5b606460405162461bcd60e51b81526020600482015260046024820152634646425360e01b6044820152fd5b60ff60375460101c166155b05760ff60375460201c1661553757600190565b606460405162461bcd60e51b81526020600482015260046024820152634646435360e01b6044820152fd5b60ff60375460081c166155fa5760ff60375460201c1661553757600190565b606460405162461bcd60e51b81526020600482015260046024820152634646534360e01b6044820152fd5b60ff603754166156415760ff60375460201c1661553757600190565b606460405162461bcd60e51b815260206004820152600460248201526346464d5360e01b6044820152fd5b6001600160a01b0316805f52602a60205260405f2061568c838254613a03565b90555f52602f60205260405f20425f5260205260405f206156ae828254613a03565b90556156bc81603654613a03565b603655425f5260336020526156d660405f20918254613a03565b9055600190565b9091906001600160a01b0316801561576157805f525f60205260405f2054838110615747576020845f94957fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef938587528684520360408620558060025403600255604051908152a3565b915063391434e360e21b5f5260045260245260445260645ffd5b634b637e8f60e11b5f525f60045260245ffd5b6001600160a01b038116805f52602d60205260405f205461579760255442614953565b10614ee9576157cb906157b16157ac84614e53565b615a64565b9283915f52602d6020524260405f20556154588282615930565b5090565b6001600160a01b03601054166001600160a01b03601654168082148015615813575b156157fa575090565b90506001600160a01b03601c54168114614bfe57505f90565b506001600160a01b03601c541682146157f1565b6001600160a01b03909291921691825f52600160205260405f206001600160a01b0382165f5260205260405f2054925f198403615865575b50505050565b8284106158ac578015613422576001600160a01b0382161561340f575f5260016020526001600160a01b0360405f2091165f5260205260405f20910390555f80808061585f565b506001600160a01b038391637dc7a0d960e11b5f521660045260245260445260645ffd5b90614bfe949360e0936001600160a01b03928452602084015260a06040840152601160a08401527f5f676f764164647265737355706461746500000000000000000000000000000060c08401521660608201528160808201520190613905565b6001600160a01b031690811561598d577fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6020826159715f94600254613a03565b60025584845283825260408420818154019055604051908152a3565b63ec442f0560e01b5f525f60045260245ffd5b90606481018082116108dc5782111591826159ba57505090565b606319820192509082116108dc57101590565b6001600160a01b0316908115615761576001600160a01b031691821561598d57815f525f60205260405f2054818110615a4b57817fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92602092855f525f84520360405f2055845f525f825260405f20818154019055604051908152a3565b8263391434e360e21b5f5260045260245260445260645ffd5b615a7360215460025490614953565b9081811115615b05575060035f82615a89614d40565b9060405191825242602083015260a06040830152601360a08301527f5f61646a757374466f724d6178537570706c790000000000000000000000000060c0830152606082015260e06080820152600760e0820152661a5b9d9bdad95960ca1b6101008201525f516020615cb55f395f51905f526101203392a490565b905090565b81615b16575050600190565b6001600160a01b0316805f52602960205260405f20615b36838254613a03565b90555f52602e60205260405f20425f5260205260405f20615b58828254613a03565b9055615b6681603554613a03565b603555425f526032602052615b8060405f20918254613a03565b90555f8061494c565b9081518110156139ef570160200190565b6001600160a01b0316604051615bb1604082613a5e565b601081526f181899199a1a9b1b9c1cb0b131b232b360811b602082015260405191615bdd606084613a5e565b602a83526020830160403682378351156139ef57603090538251600110156139ef57607860218401535f5b60148110615c165750505090565b600c81018082116108dc5760208110156139ef5782901a906001600160f81b0319615c48600484901c600f1686615b89565b5116918160011b92828404600214831517156108dc578360020190816002116108dc57615c78905f1a9188615b89565b536001600160f81b031990615c9090600f1686615b89565b511691600301806003116108dc57615cad6001935f1a9187615b89565b5301615c0856feac3f3c836d294cc63876c73af7cd90e2e9938e01472164d046fa217ea075169ba2646970667358221220abedb7cda9e65829a8ff56f1504f6ef6814ac7caef106d1414989c61c2b94eeb64736f6c634300081b0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : __fuelId (uint80): 0
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
32444:120631:0:-:0;;;;;;;;;-1:-1:-1;32444:120631:0;;;;;;-1:-1:-1;;;153032:32:0;;32444:120631;;153032:32;;32444:120631;;;;;;;;;;;153032:32;;;32444:120631;31467:107;;:::i;:::-;-1:-1:-1;152325:19:0;152286:8;;:::i;:::-;32444:120631;;;;;152296:15;32444:120631;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;152373:9;32444:120631;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;152281:127:0;152313:10;152281:127;;32444:120631;32088:21;32444:120631;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;46698:35;46706:18;46713:10;46706:18;:::i;:::-;46698:35;:::i;:::-;31467:107;;:::i;:::-;104253:9;32444:120631;-1:-1:-1;;;;;32444:120631:0;;;-1:-1:-1;;;;;104306:8:0;32444:120631;;;-1:-1:-1;;;;;104358:8:0;32444:120631;;;-1:-1:-1;;;;;104438:18:0;32444:120631;;-1:-1:-1;;;;;104460:18:0;32444:120631;;104438:40;;104437:82;;;;-1:-1:-1;;;;;104437:82:0;;32444:120631;;;-1:-1:-1;;;;;32444:120631:0;;;104253:9;32444:120631;104536:36;104532:223;;104437:82;-1:-1:-1;;;;;104817:18:0;32444:120631;;-1:-1:-1;;;;;104839:17:0;32444:120631;;104817:39;;104816:80;;;;-1:-1:-1;;;;;104816:80:0;;32444:120631;;;-1:-1:-1;;;;;32444:120631:0;104306:8;32444:120631;;;104306:8;32444:120631;104913:34;104909:219;;104816:80;-1:-1:-1;;;;;105190:18:0;32444:120631;;-1:-1:-1;;;;;105212:17:0;32444:120631;;105190:39;;105189:80;;;;-1:-1:-1;;;;;105189:80:0;;32444:120631;;;-1:-1:-1;;;;;32444:120631:0;104358:8;32444:120631;;;104358:8;32444:120631;105286:34;105282:217;;105189:80;-1:-1:-1;;;;;104253:9:0;32444:120631;;-1:-1:-1;;;;;104306:8:0;32444:120631;;;;-1:-1:-1;;;;;104358:8:0;32444:120631;;105632:9;;:::i;:::-;32444:120631;30837:1;32088:21;32444:120631;;;;;;;;;-1:-1:-1;;;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;105282:217;32444:120631;104438:18;105347:8;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;104358:8:0;32444:120631;;;;;;;;105357:15;32444:120631;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;46713:10;105342:145;;;;105282:217;;105189:80;32444:120631;-1:-1:-1;;;;;32444:120631:0;104358:8;32444:120631;;105189:80;;104909:219;32444:120631;104438:18;104976:8;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;104306:8:0;32444:120631;;;;;;;;104986:15;32444:120631;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;46713:10;104971:145;;;;104909:219;;104816:80;32444:120631;-1:-1:-1;;;;;32444:120631:0;104306:8;32444:120631;;104816:80;;104532:223;32444:120631;104438:18;104601:8;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;104253:9:0;32444:120631;;;;;;;;104611:15;32444:120631;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46713:10;104596:147;;;;104532:223;;104437:82;;-1:-1:-1;;;;;104437:82:0;;;32444:120631;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;-1:-1:-1;;;;;32444:120631:0;;:::i;:::-;;;;52749:43;32444:120631;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;;;:::i;:::-;48683:40;-1:-1:-1;;;;;48705:9:0;;:::i;:::-;32444:120631;48691:10;:23;48683:40;:::i;:::-;31467:107;;:::i;:::-;32444:120631;-1:-1:-1;;;;;151269:48:0;151299:9;;:::i;:::-;32444:120631;;;;;;;;;;;;151269:48;;32444:120631;;151269:48;;32444:120631;;;;;;;;151269:48;;;;;;;32444:120631;151269:48;;;32444:120631;;;;;;32088:21;32444:120631;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;-1:-1:-1;;;151269:48:0;32444:120631;;;;;;151269:48;;;32444:120631;151269:48;;32444:120631;151269:48;;;;;;32444:120631;151269:48;;;:::i;:::-;;;32444:120631;;;;;;;;;;;;151269:48;;;;;;-1:-1:-1;151269:48:0;;;32444:120631;;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;-1:-1:-1;;;;;48026:9:0;32444:120631;;48012:10;:30;:63;;;;32444:120631;48004:80;;;:::i;:::-;31467:107;;:::i;:::-;32444:120631;106146:746;;:::i;:::-;30837:1;32088:21;32444:120631;;;;;;;48012:63;32444:120631;48004:80;-1:-1:-1;;;;;48060:8:0;32444:120631;;48012:10;48046:29;48012:63;;;;32444:120631;;;;;;-1:-1:-1;;32444:120631:0;;;;46698:35;46706:18;46713:10;46706:18;:::i;46698:35::-;113033:16;32444:120631;113057:15;32444:120631;;;113057:15;32444:120631;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;;;:::i;:::-;-1:-1:-1;;;;;32444:120631:0;;:::i;:::-;;;;;21755:11;32444:120631;;-1:-1:-1;;;;;32444:120631:0;;;21755:27;32444:120631;-1:-1:-1;32444:120631:0;;;;;-1:-1:-1;32444:120631:0;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;-1:-1:-1;;;;;48026:9:0;32444:120631;;48012:10;:30;:63;;;;32444:120631;48004:80;;;:::i;:::-;32444:120631;107292:227;32444:120631;;107292:227;:::i;:::-;32444:120631;;;;;;;;48012:63;32444:120631;48004:80;-1:-1:-1;;;;;48060:8:0;32444:120631;;48012:10;48046:29;48012:63;;;;32444:120631;;;;;;-1:-1:-1;;32444:120631:0;;;;;93525:16;32444:120631;;:::i;:::-;93525:16;:::i;:::-;32444:120631;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;-1:-1:-1;;;;;32444:120631:0;;:::i;:::-;;;;91368:15;32444:120631;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;;147469:16;32444:120631;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;;136829:1621;32444:120631;;:::i;:::-;51014:36;51022:12;;:::i;:::-;51014:36;:::i;:::-;51119:52;51127:32;51145:13;32444:120631;51127:32;:::i;:::-;51119:52;:::i;:::-;47296:46;-1:-1:-1;;;;;47318:8:0;32444:120631;;47304:10;:29;47296:46;:::i;:::-;31467:107;;:::i;:::-;136829:1621;:::i;:::-;30837:1;32088:21;32444:120631;;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;;;143681:6;32444:120631;;;143696:13;32444:120631;143711:20;32444:120631;143733:15;32444:120631;143750:20;32444:120631;143785:35;32444:120631;20997:12;32444:120631;;143837:16;32444:120631;;143855:19;32444:120631;;143876:18;32444:120631;;143909:18;32444:120631;;;;;;;143855:19;32444:120631;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;143855:19;32444:120631;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;;90157:23;32444:120631;;:::i;:::-;48683:40;-1:-1:-1;;;;;48705:9:0;;:::i;48683:40::-;31467:107;;:::i;:::-;90083:25;;:::i;:::-;;90157:23;:::i;:::-;90221:11;90217:164;;30837:1;32088:21;32444:120631;;;;;;;90217:164;32444:120631;90259:8;;;:::i;:::-;32444:120631;;;;;90269:15;32444:120631;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;-1:-1:-1;;;;;;;;;;;90254:115:0;48691:10;90254:115;;90217:164;;32444:120631;;;;;;-1:-1:-1;;32444:120631:0;;;;;79471:31;32444:120631;;:::i;:::-;49379:79;49387:36;49412:10;49387:36;:::i;:::-;49379:79;:::i;:::-;31467:107;;:::i;:::-;32444:120631;;79471:31;;:::i;32444:120631::-;;;;;;-1:-1:-1;;32444:120631:0;;;;46698:35;46706:18;46713:10;46706:18;:::i;46698:35::-;-1:-1:-1;;;;;103420:9:0;32444:120631;;-1:-1:-1;;;;;103438:8:0;32444:120631;;;;-1:-1:-1;;;;;103455:8:0;32444:120631;;103472:9;;:::i;:::-;32444:120631;;;;;;;;;-1:-1:-1;;;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;-1:-1:-1;;;;;48026:9:0;32444:120631;;48012:10;:30;:63;;;;32444:120631;48004:80;;;:::i;:::-;32444:120631;141079:6;32444:120631;141092:11;32444:120631;141105:16;32444:120631;141123:16;32444:120631;141141:17;32444:120631;;141160:22;32444:120631;;;;;;;;;;;;;;;;;;;;;;;;;;;;48012:63;32444:120631;48004:80;-1:-1:-1;;;;;48060:8:0;32444:120631;;48012:10;48046:29;48012:63;;;;32444:120631;;;;;;-1:-1:-1;;32444:120631:0;;;;;120801:12;;:::i;32444:120631::-;;;;;;-1:-1:-1;;32444:120631:0;;;;;;;;82089:10;;32444:120631;;;;;82104:7;32444:120631;;;;82073:38;;82069:135;;32444:120631;82104:7;59503:19;82089:10;59503:19;:::i;:::-;82220:32;;82216:124;;32444:120631;82089:10;32444:120631;;82356:13;32444:120631;;82104:7;32444:120631;;;;82356:36;;82352:130;;32444:120631;59503:19;82089:10;59503:19;:::i;:::-;82089:10;;32444:120631;;82356:13;32444:120631;;;;;;82089:10;;32444:120631;;;;;;;;;82089:10;32444:120631;;82756:14;32444:120631;;;;;;82089:10;32444:120631;;82803:13;32444:120631;;;;;;;82849:18;32444:120631;;82888:19;32444:120631;;20997:12;32444:120631;;82962:18;32444:120631;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82996:15;32444:120631;;;;;82352:130;82089:10;;32444:120631;;82356:13;32444:120631;;82104:7;32444:120631;;;;;82352:130;;82216:124;82089:10;;82104:7;59503:19;82089:10;59503:19;:::i;:::-;32444:120631;82216:124;;;82069:135;82089:10;;;32444:120631;;;;;82104:7;32444:120631;;;;;82069:135;;;32444:120631;;;;;;-1:-1:-1;;32444:120631:0;;;;46698:35;46706:18;46713:10;46706:18;:::i;46698:35::-;31467:107;;:::i;:::-;32444:120631;146437:8;;:::i;32444:120631::-;;;;;;-1:-1:-1;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;51022:12;51014:36;51022:12;;:::i;51014:36::-;51119:52;51127:32;51145:13;32444:120631;51127:32;:::i;51119:52::-;47296:46;-1:-1:-1;;;;;47318:8:0;32444:120631;;47304:10;:29;47296:46;:::i;:::-;31467:107;;:::i;:::-;122432:11;;;:39;;;32444:120631;122428:246;;32444:120631;122827:13;;;;:45;;;32444:120631;122823:304;;32444:120631;;;123270:20;32444:120631;123270:47;123266:338;;32444:120631;;;123783:35;32444:120631;123783:68;123779:415;;32444:120631;;;124355:20;32444:120631;124355:38;124351:320;;32444:120631;;;123270:6;32444:120631;;;;123270:20;32444:120631;123783:35;32444:120631;;124355:20;32444:120631;;;32088:21;32444:120631;;;;;;;;;;;;;;;;;;;;;;;124351:320;124544:18;32444:120631;124435:45;124452:4;124435:21;;:45;124452:4;;;;124435:45;124355:20;32444:120631;-1:-1:-1;;;;;;;;;;;124505:8:0;;:::i;:::-;32444:120631;;;;;124515:15;32444:120631;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;123270:20;32444:120631;;;;;;;;;;47304:10;124500:159;;;;124351:320;;;124435:45;;;;123779:415;124049:18;32444:120631;123908:77;123940:5;123908:37;;:77;123940:5;;;;123908:77;123783:35;32444:120631;-1:-1:-1;;;;;;;;;;;124010:8:0;;:::i;:::-;32444:120631;;;;;124020:15;32444:120631;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;47304:10;124005:177;;;;123779:415;;;123908:77;;;;123266:338;123385:4;123359:30;;123385:4;;;123359:63;123385:4;123359:63;123270:20;32444:120631;;123486:18;123447:8;;:::i;:::-;-1:-1:-1;;;;;;;;;;;123270:20:0;32444:120631;;;;;;;123457:15;32444:120631;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47304:10;123442:150;;;;123266:338;;;123359:63;;;122823:304;123014:18;32444:120631;122909:41;122921:7;122909:19;;:41;122921:7;;;;122909:41;32444:120631;;-1:-1:-1;;;;;;;;;;;122975:8:0;;:::i;:::-;32444:120631;;;;;122985:15;32444:120631;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47304:10;122970:145;;;;122823:304;;;122909:41;;;;122827:45;32444:120631;;;;122844:28;;122827:45;;122428:246;122577:18;32444:120631;;;;;122490:6;32444:120631;;;122490:6;32444:120631;-1:-1:-1;;;;;;;;;;;122538:8:0;;:::i;:::-;32444:120631;;;;;122548:15;32444:120631;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;47304:10;122533:129;;;;122428:246;;;122432:39;32444:120631;;;122447:6;32444:120631;;122447:24;;122432:39;;32444:120631;;;;;;-1:-1:-1;;32444:120631:0;;;;;;:::i;:::-;49379:79;49387:36;49412:10;49387:36;:::i;49379:79::-;49412:10;32444:120631;;50114:11;32444:120631;;;;;;;;;;;50114:31;32444:120631;;94482:1282;32444:120631;31467:107;;;:::i;:::-;32444:120631;;94482:1282;;:::i;32444:120631::-;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;;;:::i;:::-;;;:::i;:::-;;;-1:-1:-1;;;;;32444:120631:0;;;;;;;;;;;-1:-1:-1;;;;;32444:120631:0;;;;;;;;46698:35;46706:18;46713:10;46706:18;:::i;46698:35::-;31467:107;;:::i;:::-;-1:-1:-1;;;;;32444:120631:0;;102118:25;;;;:53;;;32444:120631;102118:81;;;32444:120631;;;;-1:-1:-1;;;;;102278:9:0;32444:120631;;46713:10;102264:30;102260:116;;32444:120631;-1:-1:-1;;;;;102404:8:0;32444:120631;;46713:10;102390:29;102386:116;;32444:120631;-1:-1:-1;;;;;102530:8:0;32444:120631;;46713:10;102516:29;102512:116;;32444:120631;;102689:19;102650:8;;:::i;:::-;32444:120631;;;;;102660:15;32444:120631;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;-1:-1:-1;;;;;;;;;;;102645:120:0;46713:10;102645:120;;102689:19;32088:21;32444:120631;;;;102689:19;32444:120631;;;102512:116;-1:-1:-1;;;;;102530:8:0;32444:120631;;46713:10;99530:27;102512:116;99526:1690;32444:120631;-1:-1:-1;;;;;99645:16:0;32444:120631;;99645:31;99641:339;;99526:1690;32444:120631;;-1:-1:-1;;;;;100063:15:0;32444:120631;;;-1:-1:-1;;;;;32444:120631:0;;100063:29;;;100059:333;;99526:1690;32444:120631;;;-1:-1:-1;;;;;100475:15:0;32444:120631;;100475:29;100471:333;;99526:1690;32444:120631;;;-1:-1:-1;;;;;100885:13:0;32444:120631;;100885:25;100881:324;;99526:1690;;;;;;102512:116;;100881:324;99645:16;100475:15;100943:8;-1:-1:-1;;;;;;;;;;;32444:120631:0;100943:8;;:::i;:::-;32444:120631;101072:71;32444:120631;101117:25;-1:-1:-1;;;;;102530:8:0;32444:120631;;101117:25;;:::i;:::-;32444:120631;;101072:71;;;32444:120631;101072:71;;;32444:120631;;;;;;;;;;;;;;;;;;101072:71;;32444:120631;;101072:71;;;;;;:::i;:::-;100938:207;32444:120631;;46713:10;;;;100953:15;;100938:207;;;:::i;:::-;;;;-1:-1:-1;;;;;32444:120631:0;100885:13;32444:120631;;;100885:13;32444:120631;100881:324;;;;100471:333;99645:16;100475:15;100537:8;-1:-1:-1;;;;;;;;;;;100532:208:0;32444:120631;100663:75;32444:120631;100710:27;100537:8;;:::i;:::-;100710:27;;:::i;:::-;32444:120631;;100663:75;;;32444:120631;100663:75;;;32444:120631;;;;;;;;;;;;;;;;;;100663:75;;32444:120631;;100663:75;;;;;;:::i;:::-;32444:120631;;46713:10;;;;;100547:15;;100532:208;;;:::i;:::-;;;;-1:-1:-1;;;;;32444:120631:0;100475:15;32444:120631;;;100475:15;32444:120631;100471:333;;;;100059;99645:16;100185:15;100125:8;-1:-1:-1;;;;;;;;;;;100120:208:0;32444:120631;100251:75;32444:120631;100298:27;100125:8;;:::i;100298:27::-;32444:120631;;100251:75;;;32444:120631;100251:75;;;32444:120631;;;;;;;;;;;;;;;;;;100251:75;;32444:120631;;100251:75;;;;;;:::i;100120:208::-;;;;-1:-1:-1;;;;;32444:120631:0;100063:15;32444:120631;;;100063:15;32444:120631;100059:333;;;;99641:339;99645:16;99769:15;99709:8;-1:-1:-1;;;;;;;;;;;99704:211:0;32444:120631;99836:77;32444:120631;99884:28;99709:8;;:::i;99884:28::-;32444:120631;;99836:77;;;32444:120631;99836:77;;;32444:120631;;;;;;;;;;;;;;;;;;99836:77;;32444:120631;;99836:77;;;;;;:::i;99704:211::-;;;;-1:-1:-1;;;;;32444:120631:0;99645:16;32444:120631;;;99645:16;32444:120631;99641:339;;;;102386:116;-1:-1:-1;;;;;102404:8:0;32444:120631;;46713:10;99530:27;102386:116;99526:1690;32444:120631;-1:-1:-1;;;;;99645:16:0;32444:120631;;99645:31;99641:339;;99526:1690;-1:-1:-1;;;;;100063:15:0;32444:120631;;-1:-1:-1;;;;;32444:120631:0;;100063:29;;;100059:333;;99526:1690;32444:120631;;-1:-1:-1;;;;;100475:15:0;32444:120631;;100475:29;100471:333;;99526:1690;100885:13;32444:120631;-1:-1:-1;;;;;32444:120631:0;100881:324;;102386:116;100881:324;100475:15;99645:16;100943:8;;:::i;:::-;-1:-1:-1;;;;;;;;;;;32444:120631:0;;101072:71;32444:120631;101117:25;-1:-1:-1;;;;;102404:8:0;32444:120631;;101117:25;;:::i;101072:71::-;100938:207;32444:120631;;46713:10;;;;100953:15;;100938:207;;;:::i;:::-;;;;32444:120631;-1:-1:-1;;;;;32444:120631:0;100885:13;32444:120631;;;100885:13;32444:120631;102386:116;;100471:333;100475:15;99645:16;100537:8;;:::i;:::-;-1:-1:-1;;;;;;;;;;;100532:208:0;32444:120631;100663:75;32444:120631;100710:27;;;:::i;100663:75::-;32444:120631;;46713:10;;;;;100547:15;;100532:208;;;:::i;:::-;;;;32444:120631;-1:-1:-1;;;;;32444:120631:0;100475:15;32444:120631;;;100475:15;32444:120631;100471:333;;100059;100185:15;99645:16;100125:8;;:::i;:::-;-1:-1:-1;;;;;;;;;;;100120:208:0;32444:120631;100251:75;32444:120631;100298:27;;;:::i;100120:208::-;;;;-1:-1:-1;;;;;32444:120631:0;100063:15;32444:120631;;;100063:15;32444:120631;100059:333;;;99641:339;99769:15;99645:16;99709:8;;:::i;:::-;-1:-1:-1;;;;;;;;;;;99704:211:0;32444:120631;99836:77;32444:120631;99884:28;;;:::i;99836:77::-;32444:120631;;46713:10;;;;;99719:15;;99704:211;;;:::i;:::-;;;;32444:120631;-1:-1:-1;;;;;32444:120631:0;99645:16;32444:120631;;;99645:16;32444:120631;99641:339;;102260:116;-1:-1:-1;;;;;102278:9:0;32444:120631;;46713:10;99530:27;102260:116;99526:1690;32444:120631;-1:-1:-1;;;;;99645:16:0;32444:120631;;99645:31;99641:339;;99526:1690;-1:-1:-1;;;;;100063:15:0;32444:120631;;-1:-1:-1;;;;;32444:120631:0;;100063:29;;;100059:333;;99526:1690;32444:120631;;-1:-1:-1;;;;;100475:15:0;32444:120631;;100475:29;100471:333;;99526:1690;100885:13;32444:120631;-1:-1:-1;;;;;32444:120631:0;100881:324;;102260:116;100881:324;100475:15;99645:16;100943:8;;:::i;:::-;-1:-1:-1;;;;;;;;;;;32444:120631:0;;101072:71;32444:120631;101117:25;-1:-1:-1;;;;;102278:9:0;32444:120631;;101117:25;;:::i;101072:71::-;100938:207;32444:120631;;46713:10;;;;100953:15;;100938:207;;;:::i;:::-;;;;32444:120631;-1:-1:-1;;;;;32444:120631:0;100885:13;32444:120631;;;100885:13;32444:120631;102260:116;;100471:333;100475:15;99645:16;100537:8;;:::i;:::-;-1:-1:-1;;;;;;;;;;;100532:208:0;32444:120631;100663:75;32444:120631;100710:27;;;:::i;100532:208::-;;;;32444:120631;-1:-1:-1;;;;;32444:120631:0;100475:15;32444:120631;;;100475:15;32444:120631;100471:333;;100059;100185:15;99645:16;100125:8;;:::i;:::-;-1:-1:-1;;;;;;;;;;;100120:208:0;32444:120631;100251:75;32444:120631;100298:27;;;:::i;100120:208::-;;;;-1:-1:-1;;;;;32444:120631:0;100063:15;32444:120631;;;100063:15;32444:120631;100059:333;;;99641:339;99769:15;99645:16;99709:8;;:::i;:::-;-1:-1:-1;;;;;;;;;;;99704:211:0;32444:120631;99836:77;32444:120631;99884:28;;;:::i;99704:211::-;;;;32444:120631;-1:-1:-1;;;;;32444:120631:0;99645:16;32444:120631;;;99645:16;32444:120631;99641:339;;32444:120631;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;102118:81;102175:24;;;;102118:81;;:53;32444:120631;-1:-1:-1;;;;;32444:120631:0;;102147:24;;102118:53;;32444:120631;;;;;;-1:-1:-1;;32444:120631:0;;;;21549:5;32444:120631;;:::i;:::-;;;31467:107;;;:::i;:::-;60257:109;60276:10;;60265:22;60276:10;60265:22;:::i;:::-;:31;;60335:22;60276:10;60335:22;:::i;:::-;60276:10;;60257:109;;:::i;:::-;60276:10;21549:5;:::i;:::-;32444:120631;32088:21;32444:120631;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;;;31467:107;;:::i;:::-;85834:25;;:::i;:::-;;32444:120631;84383:15;32444:120631;84371:27;;32444:120631;;84446:22;84457:10;84446:22;:::i;:::-;84434:34;;32444:120631;;;84457:10;;32444:120631;;84503:21;32444:120631;;84495:101;84503:56;32444:120631;;;;84539:20;32444:120631;84503:56;;:::i;:::-;84562:15;-1:-1:-1;84495:101:0;:::i;:::-;84457:10;32444:120631;;84503:21;32444:120631;;;;;;84689:13;32444:120631;-1:-1:-1;84652:50:0;84648:113;;32444:120631;85846:12;32444:120631;84457:10;;32444:120631;;84816:13;32444:120631;;;;;84816:37;32444:120631;;;84816:37;:::i;:::-;32444:120631;;84457:10;32444:120631;;84864:15;32444:120631;;84562:15;32444:120631;;;;84457:10;32444:120631;;84503:21;32444:120631;;84562:15;32444:120631;;;;84562:15;32444:120631;;85020:20;32444:120631;;;;;85020:49;32444:120631;;;85020:49;:::i;:::-;32444:120631;;85080:30;32444:120631;85080:18;32444:120631;85080:30;:::i;:::-;:18;32444:120631;-1:-1:-1;;;;;;;;;;;85156:8:0;;:::i;:::-;33194;;:::i;:::-;32444:120631;;;;;;84562:15;32444:120631;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;84457:10;32444:120631;84457:10;32444:120631;;;;;;:::i;:::-;85151:120;;;32444:120631;;;;;;;;;84648:113;84457:10;;32444:120631;85846:12;84731:18;84457:10;84731:18;:::i;:::-;84648:113;;;;;;32444:120631;;;-1:-1:-1;;;32444:120631:0;;;;;;;;84383:15;32444:120631;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;84383:15;32444:120631;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;-1:-1:-1;32444:120631:0;;-1:-1:-1;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;32444:120631:0;;-1:-1:-1;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;;68325:27;32444:120631;;:::i;:::-;68325:27;:::i;:::-;32444:120631;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;32444:120631:0;;;;64260:5;32444:120631;;:::i;:::-;;;31467:107;;;:::i;:::-;63344:24;;:::i;:::-;;63551:100;63559:19;;;;;:::i;:::-;:28;;63623:19;;;;:::i;:::-;63551:100;;:::i;:::-;63717:20;32444:120631;63717:24;;:75;;;32444:120631;63713:262;;32444:120631;64118:5;64106:10;;64118:5;;:::i;:::-;64170:31;;;;:::i;:::-;;64260:5;:::i;:::-;32444:120631;32088:21;32444:120631;;63713:262;32444:120631;;63821:8;;:::i;:::-;32444:120631;;;;;63831:15;32444:120631;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;-1:-1:-1;;;;;;;;;;;63816:147:0;63848:10;63816:147;;63713:262;;63717:75;63774:10;63746:46;63774:10;;63746:46;;:::i;:::-;63745:47;63717:75;;32444:120631;;;;;;-1:-1:-1;;32444:120631:0;;;;46698:35;46706:18;46713:10;46706:18;:::i;46698:35::-;32444:120631;114947:16;32444:120631;114965:16;32444:120631;114983:17;32444:120631;115002:22;32444:120631;;;;114900:12;;32444:120631;;114914:15;32444:120631;;;;114931:14;32444:120631;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;46706:18;46713:10;46706:18;:::i;:::-;46698:35;;;:::i;:::-;117963:9;32444:120631;-1:-1:-1;;;;;32444:120631:0;117981:19;32444:120631;-1:-1:-1;;;;;32444:120631:0;;118002:18;32444:120631;-1:-1:-1;;;;;32444:120631:0;118022:18;32444:120631;-1:-1:-1;;;;;32444:120631:0;118042:16;32444:120631;-1:-1:-1;;;;;32444:120631:0;118073:8;32444:120631;-1:-1:-1;;;;;32444:120631:0;118091:18;32444:120631;-1:-1:-1;;;;;32444:120631:0;118112:17;32444:120631;-1:-1:-1;;;;;32444:120631:0;118132:17;32444:120631;-1:-1:-1;;;;;32444:120631:0;;118152:15;32444:120631;-1:-1:-1;;;;;32444:120631:0;;118182:8;32444:120631;-1:-1:-1;;;;;32444:120631:0;;118200:18;32444:120631;-1:-1:-1;;;;;32444:120631:0;;118221:17;32444:120631;-1:-1:-1;;;;;32444:120631:0;;118241:17;32444:120631;-1:-1:-1;;;;;32444:120631:0;;118261:15;32444:120631;-1:-1:-1;;;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;;59503:19;32444:120631;;:::i;:::-;59503:19;:::i;32444:120631::-;;;;;;-1:-1:-1;;32444:120631:0;;;;;133621:2147;32444:120631;;:::i;:::-;;;:::i;:::-;;;:::i;:::-;51022:12;51014:36;51022:12;;:::i;51014:36::-;51119:52;51127:32;51145:13;32444:120631;51127:32;:::i;51119:52::-;-1:-1:-1;;;;;48026:9:0;32444:120631;;48012:10;:30;:63;;;;32444:120631;48004:80;;;:::i;:::-;31467:107;;:::i;:::-;133621:2147;:::i;:::-;32444:120631;30837:1;32088:21;32444:120631;-1:-1:-1;;;;;32444:120631:0;;;;;;;;;;;;;;;;;;;48012:63;32444:120631;48004:80;-1:-1:-1;;;;;48060:8:0;32444:120631;;48012:10;48046:29;48012:63;;;;32444:120631;;;;;;-1:-1:-1;;32444:120631:0;;;;;;;;;;48683:40;-1:-1:-1;;;;;48705:9:0;;:::i;48683:40::-;31467:107;;:::i;:::-;-1:-1:-1;;;;;151937:9:0;;:::i;:::-;32444:120631;151929:35;;;;;32444:120631;151929:35;;;;32444:120631;32088:21;32444:120631;;151929:35;;;;;32444:120631;;;;;;-1:-1:-1;;32444:120631:0;;;;;;;;;;83802:21;32444:120631;;;;;;;;;83837:20;32444:120631;;;;;;83871:22;32444:120631;;;;;;83908:20;32444:120631;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;144561:15;32444:120631;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;144561:15;32444:120631;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;32444:120631:0;;;;;;;;;;;;;;;;-1:-1:-1;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;32444:120631:0;;;;;;;;;;;;32818:4;32444:120631;;;;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;31467:107;;:::i;:::-;89174:25;;:::i;:::-;;89296:10;32444:120631;;89274:21;32444:120631;;89266:101;89274:56;32444:120631;;;;89310:20;32444:120631;89274:56;;:::i;89266:101::-;89472:1;89433:35;32444:120631;89433:40;32444:120631;;20997:12;32444:120631;89588:16;32444:120631;-1:-1:-1;32444:120631:0;;;;89653:18;89296:10;89653:18;:::i;32444:120631::-;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;-1:-1:-1;;;;;32444:120631:0;;:::i;:::-;;;;90844:16;32444:120631;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;;146897:12;32444:120631;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;62819:5;32444:120631;;31467:107;;:::i;:::-;62356:24;;:::i;:::-;;62559:109;62578:10;;62567:22;62578:10;62567:22;:::i;62559:109::-;62714:33;62578:10;;62714:33;:::i;:::-;;62578:10;62819:5;:::i;32444:120631::-;;;;;;-1:-1:-1;;32444:120631:0;;;;51014:36;51022:12;;:::i;51014:36::-;51119:52;51127:32;51145:13;32444:120631;51127:32;:::i;51119:52::-;46698:35;46706:18;46713:10;46706:18;:::i;46698:35::-;31467:107;;:::i;:::-;32444:120631;110771:1516;;:::i;32444:120631::-;;;;;;-1:-1:-1;;32444:120631:0;;;;80357:28;32444:120631;;:::i;:::-;49379:79;49387:36;49412:10;49387:36;:::i;49379:79::-;31467:107;;:::i;:::-;32444:120631;;80357:28;;:::i;:::-;-1:-1:-1;32444:120631:0;32088:21;32444:120631;;;;;;;;-1:-1:-1;;32444:120631:0;;;;;68890:30;68909:10;68890:30;:::i;32444:120631::-;;;;;;-1:-1:-1;;32444:120631:0;;;;;;;20843:2;32444:120631;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;;;:::i;:::-;51014:36;51022:12;;:::i;51014:36::-;51119:52;51127:32;51145:13;32444:120631;51127:32;:::i;51119:52::-;47296:46;-1:-1:-1;;;;;47318:8:0;32444:120631;;47304:10;:29;47296:46;:::i;:::-;31467:107;;:::i;:::-;132004:32;51145:13;32444:120631;132004:32;:::i;:::-;32444:120631;;;132145:31;;;:::i;:::-;32444:120631;;32818:4;132285:15;32444:120631;132285:45;32818:4;;;-1:-1:-1;;;;;32444:120631:0;;;;;;:::i;:::-;;;;;132645:15;132625:18;32444:120631;132463:100;;32818:4;32444:120631;32818:4;;-1:-1:-1;;;;;;;;;;;132586:8:0;;:::i;:::-;33194;;:::i;:::-;32444:120631;;;;;;132596:15;32444:120631;32818:4;;32444:120631;32818:4;32444:120631;32818:4;;;;;;;32444:120631;-1:-1:-1;;;32444:120631:0;;;32818:4;;;;32444:120631;;32818:4;;;;47304:10;32818:4;47304:10;32818:4;32444:120631;32818:4;;;;:::i;:::-;132581:133;;;132285:15;32818:4;-1:-1:-1;;;32818:4:0;;;;;;32444:120631;32818:4;;;132285:15;32818:4;;:::i;:::-;;;;;;32444:120631;;;;32818:4;;-1:-1:-1;;32818:4:0;;;-1:-1:-1;;;;;32444:120631:0;;;;32818:4;32444:120631;;;32818:4;;-1:-1:-1;;;32818:4:0;;;;;;;;;;32444:120631;;;;;;;;;;;32818:4;32444:120631;;;;;;;;;;;32818:4;32444:120631;;-1:-1:-1;;;32818:4:0;;32444:120631;;32818:4;;;;;;;32444:120631;-1:-1:-1;;;32444:120631:0;;;32818:4;;;;32444:120631;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;31467:107;;:::i;:::-;32444:120631;86240:10;32444:120631;;86226:13;32444:120631;;;;;;86270:12;;;32444:120631;;;86240:10;;32444:120631;;86363:21;32444:120631;;;;;;86400:13;32444:120631;-1:-1:-1;86363:50:0;86359:111;;32444:120631;87078:19;32444:120631;86240:10;;32444:120631;;86226:13;32444:120631;;;;;;;86240:10;32444:120631;;86557:15;32444:120631;;;;;;;86240:10;32444:120631;;86363:21;32444:120631;;;;;;;86240:10;32444:120631;;86647:17;32444:120631;;86679:15;32444:120631;;;;;86746:18;32444:120631;86746:30;;86742:152;86746:30;;;86795;32444:120631;86746:18;32444:120631;86795:30;:::i;:::-;86746:18;32444:120631;86742:152;86679:15;32444:120631;;86942:22;32444:120631;;;;;86942:51;32444:120631;;;86942:51;:::i;:::-;32444:120631;;-1:-1:-1;;;;;;;;;;;87039:8:0;;:::i;:::-;33194;;:::i;:::-;32444:120631;;;;;;86679:15;32444:120631;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;86240:10;32444:120631;86240:10;32444:120631;;;;;;:::i;86742:152::-;32444:120631;86746:18;32444:120631;86742:152;;86359:111;86240:10;;32444:120631;87078:19;86440:18;86240:10;86440:18;:::i;:::-;86359:111;;;;;;32444:120631;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;;;51014:36;51022:12;;:::i;51014:36::-;51119:52;51127:32;51145:13;32444:120631;51127:32;:::i;51119:52::-;46698:35;46706:18;46713:10;46706:18;:::i;46698:35::-;31467:107;;:::i;:::-;97518:32;32444:120631;97493:57;;32444:120631;;;;97493:57;97885:19;97493:57;;97656:145;;32444:120631;97846:8;;:::i;:::-;32444:120631;;;;;;97856:15;32444:120631;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;-1:-1:-1;;;;;;;;;;;97841:186:0;46713:10;97841:186;;32444:120631;32088:21;32444:120631;;97656:145;32444:120631;97518:8;32444:120631;97656:145;;32444:120631;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;;52390:24;32444:120631;52390:24;32444:120631;;;;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;32444:120631:0;;;;23090:5;32444:120631;;:::i;:::-;;;:::i;:::-;;;31467:107;;;:::i;:::-;61383:91;61391:16;;;;;:::i;61383:91::-;61540:20;32444:120631;61540:24;;:72;;;32444:120631;61536:294;;32444:120631;23053:5;11160:10;;23053:5;;:::i;:::-;23090;:::i;61536:294::-;32444:120631;;61679:8;;:::i;:::-;32444:120631;;;;;61689:15;32444:120631;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;-1:-1:-1;;;;;;;;;;;61674:144:0;61705:10;61674:144;;61536:294;;61540:72;61594:10;61569:43;61594:10;;61569:43;;:::i;:::-;61568:44;61540:72;;32444:120631;;;;;;-1:-1:-1;;32444:120631:0;;;;;92788:19;92796:10;92788:19;:::i;32444:120631::-;;;;;;-1:-1:-1;;32444:120631:0;;;;;130305:517;32444:120631;;:::i;:::-;51014:36;51022:12;;:::i;51014:36::-;51119:52;51127:32;51145:13;32444:120631;51127:32;:::i;51119:52::-;47296:46;-1:-1:-1;;;;;47318:8:0;32444:120631;;47304:10;:29;47296:46;:::i;:::-;130305:517;:::i;:::-;32444:120631;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;;20997:12;32444:120631;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;46698:35;46706:18;46713:10;46706:18;:::i;46698:35::-;31467:107;;:::i;:::-;32444:120631;31534:1;32444:120631;;31534:1;:::i;32444:120631::-;;;;;;-1:-1:-1;;32444:120631:0;;;;;;;;;;;;;;;;:::i;:::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;51014:36;51022:12;;:::i;51014:36::-;51119:52;51127:32;51145:13;32444:120631;51127:32;:::i;51119:52::-;47296:46;-1:-1:-1;;;;;47318:8:0;32444:120631;;47304:10;:29;47296:46;:::i;:::-;31467:107;;:::i;:::-;125653:18;32444:120631;;;;;;;;;;125653:34;125649:263;;32444:120631;;;;125653:18;32444:120631;;;;;;;;;;;;125928:32;125924:258;;32444:120631;;;;125653:18;32444:120631;;;;;;;;;;;;;;126198:34;126194:263;;32444:120631;;;;125653:18;32444:120631;;;;;47318:8;32444:120631;;;;126473:32;126469:257;;32444:120631;;;;125653:18;32444:120631;;;;;;;;;;126742:34;126738:268;;127025:4;32088:21;32444:120631;;;;127025:4;32444:120631;;;126738:268;126892:19;32444:120631;;;;;;;;;;;;125653:18;32444:120631;126853:8;;:::i;:::-;126945:20;;;;-1:-1:-1;;;;;;;;;;;126960:1:0;126945:20;;32444:120631;;;;;126863:15;32444:120631;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;47318:8;32444:120631;;;;;47304:10;126848:146;;;;126738:268;;;;;126945:20;-1:-1:-1;;;;;;;;;;;32444:120631:0;126945:20;;;126469:257;126619:19;32444:120631;;;;47318:8;32444:120631;;;;;;;125653:18;32444:120631;126580:8;;:::i;:::-;126672:19;;;;-1:-1:-1;;;;;;;;;;;126686:1:0;126672:19;;32444:120631;;;;;126590:15;32444:120631;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47304:10;126575:139;;;;126469:257;;;;;126672:19;-1:-1:-1;;;;;;;;;;;32444:120631:0;126672:19;;;126194:263;126348:19;32444:120631;;;;;;;;;;;;125653:18;32444:120631;126309:8;;:::i;:::-;126401:20;;;;-1:-1:-1;;;;;;;;;;;126416:1:0;126401:20;;32444:120631;;;;;126319:15;32444:120631;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47304:10;126304:141;;;;126194:263;;;;;126401:20;-1:-1:-1;;;;;;;;;;;32444:120631:0;126401:20;;;125924:258;126074:19;32444:120631;;;;;;;;;;125653:18;32444:120631;126035:8;;:::i;:::-;126127:19;;;;-1:-1:-1;;;;;;;;;;;126141:1:0;126127:19;;32444:120631;;;;;126045:15;32444:120631;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47304:10;126030:140;;;;125924:258;;;;;126127:19;-1:-1:-1;;;;;;;;;;;32444:120631:0;126127:19;;;125649:263;125803:19;32444:120631;;;;;;;;;;;;125653:18;32444:120631;125764:8;;:::i;:::-;125856:20;;;;-1:-1:-1;;;;;;;;;;;125871:1:0;125856:20;;32444:120631;;;;;125774:15;32444:120631;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47304:10;125759:141;;;;125649:263;;;;;125856:20;-1:-1:-1;;;;;;;;;;;32444:120631:0;125856:20;;;32444:120631;;;;;;-1:-1:-1;;32444:120631:0;;;;;;:::i;:::-;;;31467:107;;;:::i;:::-;65386:10;32444:120631;;65360:25;32444:120631;;;;;;65572:20;32444:120631;65549:43;;65545:1060;;32444:120631;65386:10;;28030:19;28026:91;;-1:-1:-1;;;;;32444:120631:0;28131:21;;;28127:92;;65386:10;32444:120631;;;;;;;;;-1:-1:-1;32444:120631:0;;;;;-1:-1:-1;32444:120631:0;;;;;;;28310:31;32444:120631;65386:10;28310:31;;32444:120631;32088:21;32444:120631;;;;;;;;28127:92;28176:31;;;32444:120631;28176:31;32444:120631;;;;;28176:31;28026:91;28073:32;;;32444:120631;28073:32;32444:120631;;;;;28073:32;65545:1060;32444:120631;;65670:18;;-1:-1:-1;;;;;32444:120631:0;;;65801:3;65386:10;32444:120631;;65360:25;32444:120631;;;;;;65722:48;;:77;;;65801:3;65722:77;;;65386:10;32444:120631;;65360:25;32444:120631;;;-1:-1:-1;;;;;32444:120631:0;65831:40;32444:120631;;;;65831:40;:::i;:::-;:48;;32444:120631;;65831:59;65827:228;;65801:3;;;:::i;:::-;65710:10;;65827:228;65386:10;;;65917:40;:47;65386:10;;;;;;;32444:120631;;65360:25;32444:120631;;;;;65917:40;:::i;:::-;:47;;32444:120631;;65705:365;66090:6;66086:221;;65705:365;32444:120631;66383:2;32444:120631;;;;;66383:2;32444:120631;;;;;;;65572:20;32444:120631;;65360:25;32444:120631;;;;;;65360:25;32444:120631;;;;;;;66360:52;66356:238;65545:1060;66356:238;32444:120631;66503:16;66445:8;;;:::i;:::-;32444:120631;;;;;;66455:15;32444:120631;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;66440:138:0;65386:10;66440:138;;66356:238;65545:1060;;66086:221;32444:120631;;;;;;:::i;:::-;65386:10;32444:120631;;;66151:65;;32444:120631;66151:65;32444:120631;66151:65;;32444:120631;65386:10;32444:120631;;65360:25;32444:120631;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;66086:221;;;65722:77;;;;;;;;;32444:120631;65572:20;32444:120631;65774:25;;;65722:77;;32444:120631;;;;;;-1:-1:-1;;32444:120631:0;;;;;;;19894:5;32444:120631;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;19894:5;32444:120631;;;;;;;;;;;;-1:-1:-1;32444:120631:0;;-1:-1:-1;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;;;;51014:36;51022:12;;:::i;51014:36::-;51119:52;51127:32;51145:13;32444:120631;51127:32;:::i;51119:52::-;47296:46;-1:-1:-1;;;;;47318:8:0;32444:120631;;47304:10;:29;47296:46;:::i;:::-;31467:107;;:::i;:::-;32444:120631;139084:18;32444:120631;;32088:21;32444:120631;;;;;;;;;;;;;-1:-1:-1;;32444:120631:0;;;;31467:107;;:::i;:::-;32444:120631;71482:10;32444:120631;;71456:25;32444:120631;;;;;;;71482:10;28030:19;71568:26;;;;;;-1:-1:-1;;32444:120631:0;;;;;;:::i;:::-;;;;-1:-1:-1;;32444:120631:0;;;;;;71482:10;;;32444:120631;;71456:25;32444:120631;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32088:21;32444:120631;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71690:47;32444:120631;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;71596:3;71663:74;71482:10;;;;32444:120631;;71456:25;32444:120631;;71690:47;:40;32444:120631;;;;71690:40;:::i;:::-;:47;;32444:120631;71663:74;;:::i;:::-;71482:10;;32444:120631;;71456:25;32444:120631;;-1:-1:-1;;;;;32444:120631:0;71817:40;32444:120631;;;;71817:40;:::i;:::-;:48;;32444:120631;;28026:91;;;28131:21;;28127:92;;32444:120631;71482:10;;32444:120631;;;;;;;;-1:-1:-1;;;;;32444:120631:0;;-1:-1:-1;32444:120631:0;;;;;;;;;;;;;28310:31;32444:120631;71482:10;28310:31;;71482:10;32444:120631;;71456:25;32444:120631;;71926:47;71933:40;32444:120631;;;;71933:40;:::i;:::-;71926:47;;:::i;:::-;32444:120631;71556:10;;;32444:120631;;;;;;;;;;;;;;;;;-1:-1:-1;32444:120631:0;;;;;;;;-1:-1:-1;;32444:120631:0;;;;:::o;:::-;;;;-1:-1:-1;;;;;32444:120631:0;;;;;;:::o;:::-;;;;-1:-1:-1;;;;;32444:120631:0;;;;;;:::o;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;-1:-1:-1;;;;;32444:120631:0;;;;;-1:-1:-1;;;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;32444:120631:0;;;-1:-1:-1;32444:120631:0;;;;;-1:-1:-1;32444:120631:0;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;:::o;:::-;;;;;-1:-1:-1;;;;;32444:120631:0;;;;;-1:-1:-1;;;;;32444:120631:0;;;;;;;-1:-1:-1;;;;;32444:120631:0;;;;;-1:-1:-1;;;;;32444:120631:0;;;;;-1:-1:-1;;;;;32444:120631:0;;;;;;;;;;;;:::o;:::-;;;;:::o;:::-;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;-1:-1:-1;;32444:120631:0;;;;;;;:::o;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;:::i;:::-;;;;-1:-1:-1;;;32444:120631:0;;;;:::o;33194:8::-;32444:120631;;;;;;;:::i;:::-;33194:8;32444:120631;;-1:-1:-1;;;32444:120631:0;33194:8;;;:::o;108342:1940::-;;32444:120631;;-1:-1:-1;;;;;108634:9:0;32444:120631;;108620:10;:30;108616:88;;108342:1940;-1:-1:-1;;;;;108734:8:0;32444:120631;;108620:10;108720:29;108716:86;;108342:1940;-1:-1:-1;;;;;108832:8:0;32444:120631;;108620:10;108818:29;108814:86;;108342:1940;32444:120631;;109120:85;108932:33;108950:14;32444:120631;108932:33;:::i;:::-;109120:56;108995:32;109013:13;32444:120631;108995:32;:::i;:::-;109057;109075:13;32444:120631;109057:32;:::i;:::-;109121:25;;;;109141:1;109121:25;;109151:24;;;109170:1;109151:24;109120:56;:::i;:::-;109180:24;;;;109199:1;109180:24;109120:85;:::i;:::-;32444:120631;109328:1;109314:15;;109328:1;;32444:120631;;;109407:35;109425:17;32444:120631;109407:15;:35;:::i;:::-;109388:16;32444:120631;109425:17;109508:19;109469:8;;:::i;:::-;-1:-1:-1;;;;;;;;;;;33194:8:0;;:::i;:::-;32444:120631;;;;;;109407:15;33140:9;;;32444:120631;33140:9;32444:120631;33140:9;;;;;;;;;32444:120631;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;33140:9;;;;;32444:120631;33140:9;;;;;;;108620:10;33140:9;;:::i;:::-;109464:122;;;109508:19;109601:11;:::o;109310:965::-;109749:15;;;109797:8;109328:1;109836:19;109797:8;;:::i;:::-;-1:-1:-1;;;;;;;;;;;32444:120631:0;;:::i;:::-;;;;;;;109807:15;33194:8;;;32444:120631;33194:8;32444:120631;33194:8;;;;;;;;;32444:120631;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;33194:8;32444:120631;33194:8;;;32444:120631;33194:8;;;;;;;108620:10;33194:8;;:::i;:::-;109792:115;;;108342:1940::o;109745:519::-;110028:1;110014:15;110010:254;;108342:1940::o;110010:254::-;110062:8;;110122:15;110028:1;110062:8;;:::i;:::-;32444:120631;;;;;110072:15;32444:120631;;;;;;;;;-1:-1:-1;;;;;;;;;;;32444:120631:0;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;108620:10;110057:160;;;;32444:120631;110236:12;:::o;109180:24::-;32444:120631;109180:24;109120:85;:::i;109121:25::-;32444:120631;109121:25;;;108814:86;108866:13;32444:120631;108814:86;;;108716;32444:120631;108768:13;32444:120631;108716:86;;108616:88;32444:120631;108669:14;32444:120631;108616:88;;130305:517;130503:31;;;:::i;:::-;;;;130628:38;;;:::i;:::-;130622:4;;130614:53::o;130499:316::-;130782:21;130790:5;130782:21;130790:5;130782:21;:::o;32444:120631::-;;;;;;;:::o;:::-;-1:-1:-1;;;;;32444:120631:0;;;;;;;;;;;;;;;;96000:269;20997:12;32444:120631;96172:19;32444:120631;-1:-1:-1;96172:19:0;;;32444:120631;96195:8;:::o;96152:110::-;96230:8;32444:120631;96223:36;:::o;32818:4::-;132285:15;32444:120631;32818:4;;;;;132285:15;-1:-1:-1;32444:120631:0;;-1:-1:-1;32444:120631:0;32818:4;;-1:-1:-1;32818:4:0;:::o;32444:120631::-;;;;:::o;:::-;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;110771:1516;-1:-1:-1;;;;;110910:9:0;32444:120631;;110896:10;:30;:67;;;110771:1516;110892:356;;-1:-1:-1;;;;;111278:8:0;32444:120631;;110896:10;111264:29;:65;;;110771:1516;111260:353;;-1:-1:-1;;;;;111643:8:0;32444:120631;;110896:10;111629:29;:65;;;110771:1516;111625:353;;112153:16;112132:19;112093:8;;:::i;:::-;-1:-1:-1;;;;;;;;;;;32444:120631:0;;:::i;:::-;;;;;;;112103:15;32444:120631;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;112088:115;;;-1:-1:-1;110771:1516:0;:::o;111625:353::-;111772:15;111753:16;32444:120631;111874:22;111853:19;111814:8;;:::i;:::-;32444:120631;;;;;111772:15;32444:120631;;;;;;;;;-1:-1:-1;;;;;;;;;;;32444:120631:0;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;111278:8;32444:120631;;;;;110896:10;111809:131;;;;111853:19;111955:11;:::o;111629:65::-;32444:120631;111662:32;111680:13;32444:120631;111662:32;:::i;:::-;111629:65;;111260:353;111407:15;111388:16;32444:120631;111509:22;111488:19;111449:8;;:::i;:::-;32444:120631;;;;;111407:15;32444:120631;;;;;;;;;-1:-1:-1;;;;;;;;;;;32444:120631:0;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;111278:8;32444:120631;;;;;110896:10;111444:131;;;;111488:19;111590:11;:::o;111264:65::-;32444:120631;111297:32;111315:13;32444:120631;111297:32;:::i;:::-;111264:65;;110892:356;111041:15;111022:16;32444:120631;111143:22;111122:19;111083:8;;:::i;:::-;32444:120631;;;;;111041:15;32444:120631;;;;;;;;;-1:-1:-1;;;;;;;;;;;32444:120631:0;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;110896:10;111078:132;;;;111122:19;111225:11;:::o;110896:67::-;32444:120631;110930:33;110948:14;32444:120631;110930:33;:::i;:::-;110896:67;;32444:120631;;;;:::o;:::-;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;32444:120631:0;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;133621:2147::-;;;;133936:15;32444:120631;134024:10;134033:1;134036:26;;;;;;32444:120631;;-1:-1:-1;;;135720:40:0;;32444:120631;135720:40;;;32444:120631;;;;;;;;;;;135720:40;;;134064:3;-1:-1:-1;;;;;134151:18:0;;;:::i;:::-;32444:120631;;;-1:-1:-1;;;;;32444:120631:0;;134135:50;;;134131:1566;;134064:3;32444:120631;;134024:10;;134131:1566;134263:18;;;;134807:38;134263:18;32444:120631;134263:18;;;:::i;:::-;32444:120631;;;;;134262:27;:40;;;134131:1566;134258:529;;;134399:15;32444:120631;134339:8;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;134441:18:0;;;:::i;:::-;32444:120631;;;;;;;;;134349:15;32444:120631;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;134366:10;134334:165;;;;134258:529;134807:18;;;:::i;:::-;-1:-1:-1;32818:4:0;;-1:-1:-1;;;;32818:4:0;32444:120631;;;32818:4;;-1:-1:-1;;;32818:4:0;;;;;;;;134807:38;32444:120631;;;;;134870:21;:59;;;134258:529;134866:696;;;32444:120631;134956:41;32444:120631;;134033:1;32444:120631;134956:11;32444:120631;;;134033:1;32444:120631;;;;;;;;;;;;;;;;134956:41;135092:15;32444:120631;135032:8;;:::i;:::-;-1:-1:-1;;;;;;;;;;;135027:164:0;-1:-1:-1;;;;;135134:18:0;;;:::i;:::-;32444:120631;;;;;135059:10;;;;135042:15;;135027:164;;;:::i;:::-;;;;134866:696;-1:-1:-1;;;;;135591:18:0;;;:::i;:::-;32444:120631;;;;134033:1;32444:120631;135627:11;32444:120631;;;135654:18;32444:120631;;134033:1;32444:120631;;;135654:18;;:::i;:::-;32444:120631;;;;;135583:98;;;;:::o;134866:696::-;135221:59;;;134866:696;135217:345;;134866:696;;;;135217:345;135307:41;32444:120631;;134033:1;32444:120631;135307:11;32444:120631;;;134033:1;32444:120631;;;;;;;;;;;;;;;;135307:41;135443:15;32444:120631;135383:8;;:::i;:::-;-1:-1:-1;;;;;;;;;;;135378:164:0;-1:-1:-1;;;;;135485:18:0;;;:::i;135378:164::-;;;;135217:345;;;135221:59;32444:120631;;134033:1;32444:120631;135247:11;32444:120631;;;;;134033:1;32444:120631;;;;;135247:33;135221:59;;134870;32444:120631;;134033:1;32444:120631;134895:11;32444:120631;;;;134033:1;32444:120631;;;;134870:59;;134258:529;32444:120631;134529:18;;;:::i;:::-;32444:120631;;;;;134529:40;;;134258:529;134525:262;134258:529;134525:262;134666:15;32444:120631;134606:8;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;134708:18:0;;;:::i;:::-;32444:120631;;;;;;;;;134616:15;32444:120631;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;134633:10;134601:166;;;;134258:529;;134529:40;134559:10;;;134529:40;;134262;;;;;94482:1282;94685:11;;94681:33;;-1:-1:-1;;;;;32444:120631:0;;94771:23;94767:221;;20997:12;32444:120631;95087:16;32444:120631;-1:-1:-1;95070:33:0;95066:249;;95389:22;32444:120631;20997:12;32444:120631;95389:22;:::i;:::-;95087:16;32444:120631;-1:-1:-1;95385:242:0;;95682:6;;;;:::i;:::-;95752:4;94482:1282;:::o;95385:242::-;95459:8;94695:1;20997:12;95459:8;-1:-1:-1;;;;;;;;;;;95459:8:0;;:::i;:::-;32444:120631;;;;;95469:15;32444:120631;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;95486:10;95454:134;;;;94695:1;95603:12;:::o;95066:249::-;95132:8;;32444:120631;94695:1;95132:8;;:::i;:::-;-1:-1:-1;;;;;;;;;;;20997:12:0;32444:120631;;;;;;;95142:15;32444:120631;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;95159:10;95127:149;;;;94695:1;95291:12;:::o;94767:221::-;94823:8;;94695:1;94823:8;;;:::i;:::-;32444:120631;;;;;94833:15;32444:120631;;;;;;;;;-1:-1:-1;;;;;;;;;;;32444:120631:0;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94850:10;94818:131;;;;94695:1;94964:12;:::o;94681:33::-;94700:11;;94707:4;94700:11;:::o;32444:120631::-;;;;;;;;;;:::o;136829:1621::-;137023:32;137041:13;32444:120631;137023:32;:::i;:::-;32444:120631;;;137167:31;;;:::i;:::-;32444:120631;;;137327:15;32444:120631;137460:10;-1:-1:-1;137472:26:0;;;;;;32444:120631;;-1:-1:-1;;;138418:24:0;;32444:120631;138418:24;;;32444:120631;;;;;;-1:-1:-1;;;32444:120631:0;;;;138418:24;;;137500:3;-1:-1:-1;;;;;137526:18:0;;;:::i;:::-;32444:120631;;;-1:-1:-1;;;;;32444:120631:0;;137526:50;;;137522:796;;137500:3;32444:120631;;137460:10;;137522:796;137654:8;;;;137714:15;32444:120631;137654:8;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;137756:18:0;;;:::i;:::-;32444:120631;;;33194:8;;;:::i;:::-;32444:120631;;;;;;137664:15;32444:120631;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;137681:10;32444:120631;137681:10;32444:120631;;;;;;:::i;:::-;137649:156;;;-1:-1:-1;;32444:120631:0;;;;;;;137963:43;137942:18;137963:43;;:::i;:::-;137942:18;;;:::i;:::-;32444:120631;;;;;;;137522:796;32444:120631;;137327:15;32444:120631;;;;;-1:-1:-1;;32444:120631:0;;;;:::i;:::-;;;-1:-1:-1;32444:120631:0;;137327:15;32444:120631;;-1:-1:-1;32444:120631:0;138182:11;32444:120631;;;;;-1:-1:-1;32444:120631:0;;;;;138182:33;138178:77;;137522:796;138291:11;32444:120631;138291:11;:::o;138178:77::-;-1:-1:-1;32444:120631:0;138182:11;32444:120631;;;-1:-1:-1;32444:120631:0;;;;;;;;138178:77;;;32444:120631;;;;-1:-1:-1;32444:120631:0;;;;;-1:-1:-1;32444:120631:0;;;;-1:-1:-1;;;;;32444:120631:0;;;;;;-1:-1:-1;;;;;32444:120631:0;;;;;;;;;;;32818:4;;;32444:120631;32818:4;;32444:120631;;;32818:4;;;;32444:120631;32818:4;;;;;;;;32444:120631;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;107292:227;107405:16;32444:120631;107424:15;-1:-1:-1;107424:15:0;;;107443:12;-1:-1:-1;107443:12:0;:::o;107401:111::-;107483:25;;;:::i;:::-;107475:34;:::o;106146:746::-;106377:41;:16;32444:120631;106396:22;32444:120631;106377:41;;:::i;:::-;106359:15;:59;106396:22;;;106377:6;32444:120631;106422:20;:::o;106355:530::-;106359:15;106582:16;32444:120631;106650:35;106668:17;32444:120631;106359:15;106650:35;:::i;:::-;106377:16;32444:120631;106829:7;106748:75;:61;:44;106377:6;32444:120631;106748:26;106359:15;106762:12;;106748:26;;:::i;:::-;:44;:::i;:::-;106795:14;106748:61;;:::i;:::-;106812:11;32444:120631;106748:75;;:::i;:::-;32444:120631;;106731:93;;;32444:120631;;;106731:93;;;;32444:120631;106731:93;;:::i;:::-;32444:120631;106721:104;;32444:120631;;106377:6;32444:120631;106853:20;:::o;31582:315::-;30880:1;31711:7;32444:120631;31711:18;31707:88;;30880:1;31711:7;32444:120631;31582:315::o;31707:88::-;31753:30;;;-1:-1:-1;31753:30:0;;-1:-1:-1;31753:30:0;119578:724;119704:16;32444:120631;119723:15;-1:-1:-1;119700:494:0;;32444:120631;119578:724;:::o;119700:494::-;120180:1;32444:120631;119921:14;32444:120631;119899:50;119704:6;32444:120631;119899:50;;;:::i;:::-;119895:73;;119700:494;119986:50;32444:120631;120008:13;32444:120631;119986:50;:::i;:::-;119982:73;;119700:494;120073:50;32444:120631;120095:13;32444:120631;120073:50;:::i;:::-;120069:73;;120166:15;;120158:24;:::o;120069:73::-;120127:12;;;:::i;:::-;120166:15;;120158:24;:::o;119982:73::-;120040:12;;120073:50;120040:12;;:::i;:::-;119982:73;;;;;119895;32444:120631;;-1:-1:-1;119895:73:0;;98427:317;98540:16;32444:120631;98522:15;:34;98540:16;;;98560:12;32444:120631;98560:12;:::o;98518:152::-;98540:6;32444:120631;98610:42;;;:::i;:::-;98606:64;;32444:120631;98427:317;:::o;145517:254::-;145584:12;32444:120631;-1:-1:-1;;;32444:120631:0;;;145632:14;145584:12;32444:120631;145632:14;:::i;:::-;32444:120631;145584:12;32444:120631;145661:19;:::o;145578:186::-;32444:120631;145584:12;32444:120631;;145744:8;:::o;64612:186::-;-1:-1:-1;;;;;32444:120631:0;64709:9;32444:120631;;;;64696:29;;;:61;;;;;64612:186;64696:93;;;;64688:102;64612:186;:::o;64696:93::-;32444:120631;;-1:-1:-1;;;;;64774:8:0;32444:120631;;64761:28;64612:186;:::o;64696:61::-;64742:8;32444:120631;-1:-1:-1;;;;;32444:120631:0;64729:28;;;-1:-1:-1;64696:61:0;;127417:688;127599:15;32444:120631;127696:10;32444:120631;127708:26;;;;;;128085:12;;;32444:120631;127417:688;:::o;127736:3::-;-1:-1:-1;;;;;127864:18:0;;;:::i;:::-;32444:120631;;;-1:-1:-1;;;;;32444:120631:0;;127864:50;127860:156;;32444:120631;;127696:10;;127860:156;127989:11;;;32444:120631;127989:11;:::o;128510:728::-;128699:15;32444:120631;128796:10;32444:120631;128808:26;;;;;;129218:12;;;32444:120631;128510:728;:::o;128836:3::-;-1:-1:-1;;;;;128937:18:0;;;:::i;:::-;32444:120631;;;-1:-1:-1;;;;;32444:120631:0;;128937:50;:80;;;128836:3;128933:193;;32444:120631;;128796:10;;128937:80;128991:18;32444:120631;128991:18;;;:::i;:::-;32444:120631;;;;;128937:80;;91874:501;-1:-1:-1;;;;;32444:120631:0;;;;91984:21;32444:120631;;;;;;92020:13;32444:120631;-1:-1:-1;91984:49:0;91980:68;;92262:85;32444:120631;92352:14;32444:120631;;;91984:21;32444:120631;;92088:50;32444:120631;;;;92088:15;:50;:::i;:::-;32444:120631;;;92262:13;32444:120631;;92262:62;32444:120631;;;;92289:35;32444:120631;92262:62;;:::i;:::-;:85;:::i;:::-;32444:120631;91874:501;:::o;91980:68::-;92037:8;32444:120631;92037:8;:::o;58445:570::-;-1:-1:-1;;;;;32444:120631:0;;;;;;;;;;;;;;58759:13;32444:120631;;;;;;;58889:39;;;;;58939:38;;;:::i;58885:123::-;58997:8;;32444:120631;58997:8;:::o;69288:1521::-;;;;69541:1;69518:20;32444:120631;69518:24;69514:47;;-1:-1:-1;;;;;32444:120631:0;;;69612:25;32444:120631;;;;;69664:10;32444:120631;69705:3;32444:120631;;69676:27;;;;;-1:-1:-1;;;;;69541:1:0;69731:19;;;;:::i;:::-;:27;;32444:120631;;-1:-1:-1;;;;;32444:120631:0;;69731:40;69727:959;;69541:1;32444:120631;69664:10;;69727:959;69798:19;;;;:26;:19;;;;:::i;:::-;:26;;32444:120631;69798:37;69794:210;;70070:38;69798:26;70070:19;;;;:::i;:::-;:26;;32444:120631;;;70070:38;:::i;:::-;32444:120631;;69798:26;70229:19;;;;:::i;:::-;:26;;32444:120631;70229:31;:81;;;69727:959;70225:371;;70659:11;;69541:1;70659:11;:::o;70225:371::-;32444:120631;;-1:-1:-1;;32444:120631:0;;;;;;;70376:32;;;70372:158;;70225:371;32444:120631;;;;;;;;-1:-1:-1;;32444:120631:0;;;;;;;:::i;:::-;;70225:371;;;;70372:158;70461:45;70439:19;32444:120631;70461:45;;:::i;:::-;70439:19;;;;:::i;:::-;32444:120631;;;;;;;;70372:158;32444:120631;69798:26;32444:120631;-1:-1:-1;;;;;32444:120631:0;;;;;;-1:-1:-1;;;;;32444:120631:0;;;;;;;-1:-1:-1;;;;;69541:1:0;32444:120631;;;;-1:-1:-1;;;;;69541:1:0;32444:120631;;;;-1:-1:-1;;;;;32444:120631:0;;;;;;;;;;;;;;70372:158;;70229:81;32444:120631;;;69518:20;32444:120631;-1:-1:-1;70229:81:0;;69794:210;69972:12;;;32444:120631;69972:12;:::o;69676:27::-;;;;;32444:120631;69288:1521;:::o;32444:120631::-;;;;;;;;;;;;;;;:::o;67092:683::-;-1:-1:-1;;;;;32444:120631:0;;-1:-1:-1;32444:120631:0;67336:25;32444:120631;;;-1:-1:-1;32444:120631:0;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;-1:-1:-1;;32444:120631:0;;;:::i;:::-;;-1:-1:-1;32444:120631:0;;;;;;67487:10;;-1:-1:-1;67499:28:0;;;;;;67744:23;;;67092:683;:::o;67529:3::-;32444:120631;;;-1:-1:-1;32444:120631:0;67336:25;32444:120631;;-1:-1:-1;;;;;67583:37:0;32444:120631;;-1:-1:-1;32444:120631:0;67583:37;:::i;:::-;32444:120631;;;;-1:-1:-1;32444:120631:0;67336:25;32444:120631;;-1:-1:-1;;;;;32444:120631:0;67628:37;32444:120631;;-1:-1:-1;32444:120631:0;67628:37;:::i;:::-;:45;;32444:120631;;;-1:-1:-1;32444:120631:0;67336:25;32444:120631;;67675:44;:37;32444:120631;;-1:-1:-1;32444:120631:0;67675:37;:::i;:::-;:44;;32444:120631;;;;;;;;:::i;:::-;;;;67573:147;;32444:120631;;67573:147;;32444:120631;67551:169;;;;:::i;:::-;;;;;;:::i;:::-;;32444:120631;67487:10;;32444:120631;;;;;;;;:::i;:::-;-1:-1:-1;32444:120631:0;;-1:-1:-1;32444:120631:0;;;;-1:-1:-1;32444:120631:0;;;;;;;;;;;;;76997:1641;;77120:18;32444:120631;77120:23;;;;;77116:535;;76997:1641;77706:24;;77780:29;77706:24;;;:::i;:::-;;77780:29;:::i;:::-;32444:120631;77873:24;32444:120631;20997:12;32444:120631;77873:24;:::i;:::-;77901:16;32444:120631;-1:-1:-1;32444:120631:0;;-1:-1:-1;;;;;32444:120631:0;;77970:18;32444:120631;;78067:36;78092:10;78067:36;:::i;:::-;78092:10;;78163:8;32444:120631;78163:8;;-1:-1:-1;;;;;;;;;;;78163:8:0;;:::i;:::-;32444:120631;;:::i;:::-;;;;;;;78173:15;32444:120631;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;78092:10;32444:120631;78092:10;32444:120631;;;;;;:::i;78063:568::-;78412:8;;;;:::i;32444:120631::-;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;77116:535;20997:12;32444:120631;;77289:2;32444:120631;;;;;77289:2;32444:120631;;;;;77295:3;32444:120631;;-1:-1:-1;77247:222:0;;77116:535;77120:18;32444:120631;77592:24;32444:120631;20997:12;32444:120631;77592:24;:::i;:::-;-1:-1:-1;32444:120631:0;;77116:535;;;;32444:120631;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;77295:3;;32444:120631;77247:222;20997:12;32444:120631;77331:8;;:::i;:::-;32444:120631;;;;;77341:15;32444:120631;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;-1:-1:-1;;;;;;;;;;;77326:127:0;77358:10;77326:127;;77247:222;;76997:1641;;77120:18;32444:120631;77120:23;;;;;77116:535;;76997:1641;77706:24;;77780:29;77706:24;;;:::i;77780:29::-;32444:120631;77873:24;32444:120631;20997:12;32444:120631;77873:24;:::i;:::-;77901:16;32444:120631;-1:-1:-1;32444:120631:0;;-1:-1:-1;;;;;32444:120631:0;;77970:18;32444:120631;;78067:36;78092:10;78067:36;:::i;:::-;78092:10;;78163:8;32444:120631;78163:8;;-1:-1:-1;;;;;;;;;;;78163:8:0;;:::i;78063:568::-;78412:8;;;;78499:31;78412:8;;:::i;:::-;78499:31;:::i;77116:535::-;20997:12;32444:120631;;77289:2;32444:120631;;;;;77289:2;32444:120631;;;;;77295:3;32444:120631;;-1:-1:-1;77247:222:0;;77116:535;77120:18;32444:120631;77592:24;32444:120631;20997:12;32444:120631;77592:24;:::i;:::-;-1:-1:-1;32444:120631:0;;77116:535;;;;77247:222;20997:12;32444:120631;77331:8;;:::i;:::-;32444:120631;;;;;77341:15;32444:120631;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;-1:-1:-1;;;;;;;;;;;77326:127:0;77358:10;77326:127;;77247:222;;75297:912;32444:120631;75892:17;32444:120631;;;;;;;75892:17;32444:120631;;;;76024:124;;32444:120631;75297:912;:::o;76024:124::-;32444:120631;;-1:-1:-1;;;76065:17:0;;32444:120631;76065:17;;;32444:120631;;;;;;-1:-1:-1;;;32444:120631:0;;;;76065:17;;;32444:120631;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;75297:912;32444:120631;75502:18;32444:120631;;;;;;;75502:18;32444:120631;;;;76024:124;;32444:120631;75297:912;:::o;32444:120631::-;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;75297:912;32444:120631;75764:18;32444:120631;;;;;;;75764:18;32444:120631;;;;76024:124;;32444:120631;75297:912;:::o;32444:120631::-;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;75297:912;32444:120631;75632:17;32444:120631;;;;;75632:17;32444:120631;;;;76024:124;;77718:11;75297:912;:::o;32444:120631::-;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;;74320:562;-1:-1:-1;;;;;32444:120631:0;;-1:-1:-1;32444:120631:0;74480:13;32444:120631;;;-1:-1:-1;32444:120631:0;74480:34;32444:120631;;;74480:34;:::i;:::-;32444:120631;;-1:-1:-1;32444:120631:0;74579:15;32444:120631;;;-1:-1:-1;32444:120631:0;74604:15;-1:-1:-1;32444:120631:0;;;;-1:-1:-1;32444:120631:0;74579:53;32444:120631;;;74579:53;:::i;:::-;32444:120631;;74705:30;32444:120631;74705:18;32444:120631;74705:30;:::i;:::-;:18;32444:120631;74604:15;-1:-1:-1;32444:120631:0;74771:20;32444:120631;;74771:49;32444:120631;-1:-1:-1;32444:120631:0;;;;74771:49;:::i;:::-;32444:120631;;74870:4;74320:562;:::o;26172:211::-;;;;-1:-1:-1;;;;;32444:120631:0;26243:21;;26239:91;;32444:120631;26262:1;32444:120631;26262:1;32444:120631;;;26262:1;32444:120631;;24481:19;;;24477:117;;32444:120631;;26262:1;32444:120631;;25245:25;32444:120631;;;;;;;;;;;;;24963:21;32444:120631;;24963:21;32444:120631;;;;;;25245:25;26172:211::o;24477:117::-;32444:120631;;;;;26262:1;24528:50;;32444:120631;;;;;;26262:1;24528:50;26239:91;26288:30;;;26262:1;26288:30;26262:1;26288:30;32444:120631;;26262:1;26288:30;88184:728;-1:-1:-1;;;;;32444:120631:0;;;;;88401:21;32444:120631;;;;;;88442:38;88460:20;32444:120631;88442:15;:38;:::i;:::-;-1:-1:-1;88397:98:0;;88836:41;88567:24;88547:45;88567:24;;;:::i;:::-;88547:45;:::i;:::-;32444:120631;;;;;88401:21;32444:120631;;88442:15;32444:120631;;;;88786:7;;;;:::i;88836:41::-;;88184:728;:::o;72506:298::-;-1:-1:-1;;;;;72581:16:0;32444:120631;;-1:-1:-1;;;;;72601:15:0;32444:120631;;72581:35;;;:74;;;;72506:298;72577:190;;;72659:23;;:::o;72577:190::-;32444:120631;;-1:-1:-1;;;;;72723:15:0;32444:120631;;72704:34;;72700:67;;72577:190;32444:120631;72506:298;:::o;72581:74::-;32444:120631;-1:-1:-1;;;;;72640:15:0;32444:120631;;72620:35;;72581:74;;28652:487;-1:-1:-1;;;;;28652:487:0;;;;32444:120631;;;-1:-1:-1;32444:120631:0;21755:11;32444:120631;;;-1:-1:-1;32444:120631:0;-1:-1:-1;;;;;32444:120631:0;;-1:-1:-1;32444:120631:0;;;;-1:-1:-1;32444:120631:0;;;;;28819:37;;28815:317;;28652:487;;;;;:::o;28815:317::-;28877:24;;;28873:132;;28030:19;;28026:91;;-1:-1:-1;;;;;32444:120631:0;;28131:21;28127:92;;-1:-1:-1;32444:120631:0;21755:11;32444:120631;;-1:-1:-1;;;;;32444:120631:0;-1:-1:-1;32444:120631:0;28229:27;32444:120631;-1:-1:-1;32444:120631:0;;;;-1:-1:-1;32444:120631:0;;;;;28815:317;;;;;;28873:132;28929:60;-1:-1:-1;;;;;28929:60:0;;;;;-1:-1:-1;28929:60:0;32444:120631;28929:60;32444:120631;;;;;;-1:-1:-1;28929:60:0;32444:120631;;;;;;;-1:-1:-1;;;;;32444:120631:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;25631:213::-;-1:-1:-1;;;;;32444:120631:0;25702:21;;;25698:93;;25245:25;32444:120631;;24371:21;25721:1;32444:120631;24371:21;32444:120631;24371:21;:::i;:::-;;32444:120631;;;;;;;;;;;;;;;;;;;;;25245:25;25631:213::o;25698:93::-;25747:32;;;25721:1;25747:32;25721:1;25747:32;32444:120631;;25721:1;25747:32;118908:159;;119029:3;32444:120631;;;;;;;119012:20;;;119011:48;;;;119004:55;;118908:159;:::o;119011:48::-;-1:-1:-1;;32444:120631:0;;;-1:-1:-1;32444:120631:0;;;;;119038:20;;118908:159;:::o;23511:308::-;-1:-1:-1;;;;;32444:120631:0;23595:18;;;23591:88;;-1:-1:-1;;;;;32444:120631:0;23693:16;;;23689:88;;32444:120631;23611:1;32444:120631;23611:1;32444:120631;;;23611:1;32444:120631;;24481:19;;;24477:117;;32444:120631;25245:25;32444:120631;;;;23611:1;32444:120631;23611:1;32444:120631;;;;23611:1;32444:120631;;;23611:1;32444:120631;23611:1;32444:120631;;;23611:1;32444:120631;;;;;;;;;;;;25245:25;23511:308::o;24477:117::-;32444:120631;;;;23611:1;24528:50;;32444:120631;;;;;;23611:1;24528:50;148588:843;148771:32;:16;32444:120631;20997:12;32444:120631;148771:32;;:::i;:::-;148820:26;;;;;;;148961:33;148771:16;32444:120631;148961:33;149076:8;;:::i;:::-;32444:120631;;;;;;149086:15;32444:120631;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32444:120631:0;;;;-1:-1:-1;;;;;;;;;;;149071:130:0;149103:10;149071:130;;148588:843;:::o;148816:520::-;149298:26;;148588:843;:::o;73211:703::-;73368:12;73364:489;;73895:11;;73902:4;73211:703;:::o;73364:489::-;-1:-1:-1;;;;;32444:120631:0;;73379:1;32444:120631;73467:14;32444:120631;;;73379:1;32444:120631;73467:36;32444:120631;;;73467:36;:::i;:::-;32444:120631;;73379:1;32444:120631;73576:16;32444:120631;;;73379:1;32444:120631;73603:15;73379:1;32444:120631;;;;73379:1;32444:120631;73576:55;32444:120631;;;73576:55;:::i;:::-;32444:120631;;73716:31;32444:120631;73716:19;32444:120631;73716:31;:::i;:::-;:19;32444:120631;73603:15;73379:1;32444:120631;73791:21;32444:120631;;73791:50;32444:120631;73379:1;32444:120631;;;;73791:50;:::i;:::-;32444:120631;;73364:489;;;;32444:120631;;;;;;;;;;;;;:::o;150022:506::-;-1:-1:-1;;;;;32444:120631:0;;;;;;;:::i;:::-;;;;-1:-1:-1;;;32444:120631:0;;;;;;;;;;;:::i;:::-;150254:2;32444:120631;;;;;;;;;;;;;;150270:12;;;32444:120631;;150297:1;32444:120631;;;;150293:12;32444:120631;;;150293:12;-1:-1:-1;150335:6:0;150339:2;150335:6;;;;150502:18;;;150022:506;:::o;150343:3::-;150403:2;32444:120631;;;;;;;;150393:13;;;;;;;;;-1:-1:-1;;;;;;150378:35:0;150410:1;32444:120631;;;150472:4;32444:120631;150378:35;;:::i;:::-;32444:120631;;;;150297:1;32444:120631;;;;;150369:1;32444:120631;;;;;;;;150369:1;32444:120631;;;150369:1;32444:120631;;;150365:48;;-1:-1:-1;150365:48:0;;;;:::i;:::-;;-1:-1:-1;;;;;;32444:120631:0;150441:37;;150472:4;32444:120631;150441:37;;:::i;:::-;32444:120631;;;150432:1;32444:120631;;150432:1;32444:120631;;;150428:50;150297:1;150428:50;-1:-1:-1;150428:50:0;;;;:::i;:::-;;32444:120631;150323:10;
Swarm Source
ipfs://abedb7cda9e65829a8ff56f1504f6ef6814ac7caef106d1414989c61c2b94eeb
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.