false
true
0

Contract Address Details

0xbbeA78397d4d4590882EFcc4820f03074aB2AB29

Token
XUSD Vibratile Asset (XUSD)
Creator
0x000006–a90503 at 0x97e44a–853795
Balance
0 PLS ( )
Tokens
Fetching tokens...
Transactions
14,361 Transactions
Transfers
0 Transfers
Gas Used
0
Last Balance Update
25900029
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
XUSD




Optimization enabled
false
Compiler version
v0.8.26+commit.8a97fa7a




EVM Version
paris




Verified at
2024-09-24T16:22:09.254724Z

Constructor Arguments

0x00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000052b7d2dcc80cd2e4000000000000000000000000000000cb13ca54a9744afa2586e6232b94a58cf9b5e25c0000000000000000000000003246f31ad1b00991965d7a68aef694c4464d89eb00000000000000000000000000000000000000000000000000000000000000145855534420566962726174696c6520417373657400000000000000000000000000000000000000000000000000000000000000000000000000000000000000045855534400000000000000000000000000000000000000000000000000000000

Arg [0] (string) : XUSD Vibratile Asset
Arg [1] (string) : XUSD
Arg [2] (uint256) : 100000000000000000000000000
Arg [3] (address) : 0xcb13ca54a9744afa2586e6232b94a58cf9b5e25c
Arg [4] (address) : 0x3246f31ad1b00991965d7a68aef694c4464d89eb

              

contracts/XUSD.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/utils/structs/Checkpoints.sol";
import "./VibeRegistry.sol";
import "./AccessorMod.sol";

contract XUSD is Context, IERC20, IERC20Metadata, AccesorMod, Ownable {
    using Checkpoints for Checkpoints.Trace224; // Using Checkpoints library for tracking burn history

    // Storage
    mapping(address => uint32[]) private _burnBlockNumbersEOA;
    mapping(address => uint32[]) private _burnBlockNumbersContract;
    mapping(address => uint256) private _balances;
    mapping(address => mapping(address => uint256)) private _allowances;
    mapping(address => uint256) internal _contractBurnBalances;
    mapping(address => uint256) internal _eoaBurnBalances;
    mapping(address => Checkpoints.Trace224) private _burnCheckpointsEOA;
    mapping(address => Checkpoints.Trace224) private _burnCheckpointsContract;
    uint256 internal _totalBurnedEOA;
    uint256 internal _totalBurnedContract;
    uint private burnIt = 700;
    uint private bankIt = 300;
    address tressury;
    uint256 private _totalSupply;
    uint256 internal _totalBurned;
    string private _name;
    string private _symbol;
    bool private tradingOpen;
    bool private paid = false;
    bool private swapEnabled = false;
    mapping(address => bool) private _isExcludedFromTax;
    address public immutable burnAddress =
        0x0000000000000000000000000000000000000369;

    VibeRegistry public registry;

    // Constructor
    constructor(
        string memory name_,
        string memory symbol_,
        uint256 initialBalance_,
        address _access,
        address t
    ) AccesorMod(_access) Ownable(msg.sender) {
        require(initialBalance_ > 0, "Initial supply cannot be zero");
        tressury = t;
        _name = name_;
        _symbol = symbol_;
        _mint(_msgSender(), initialBalance_);
    }

    // View function to return burn balance of a user (Contracts)
    function burnBalanceContract(
        address contractAddr
    ) public view returns (uint256) {
        return _contractBurnBalances[contractAddr];
    }

    // View function to return burn balance of a user (EOAs)
    function burnBalanceEOA(address user) public view returns (uint256) {
        return _eoaBurnBalances[user];
    }

    // Returns the total amount burned (combining EOAs and contracts)
    function totalBurned() external view returns (uint256) {
        return _totalBurnedEOA + _totalBurnedContract;
    }

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

    // Returns the symbol of the token
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    // Returns the number of decimals (defaults to 18)
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    // Returns total supply of tokens
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    // Returns the balance of a specific account
    function balanceOf(
        address account
    ) public view virtual override returns (uint256) {
        return _balances[account];
    }

    // Returns allowance granted to spender by _owner
    function allowance(
        address _owner,
        address spender
    ) public view virtual override returns (uint256) {
        return _allowances[_owner][spender];
    }
    function setTreasury(address t) external onlyConsul(){
    tressury = t;

    }
    function setTaxVariable(uint treasury, uint burn) external onlyConsul(){
        burnIt = burn;
        bankIt = treasury;

    }

    // Approves a spender
    function approve(
        address spender,
        uint256 amount
    ) public virtual override returns (bool) {
        address _owner = _msgSender();
        _approve(_owner, spender, amount);
        return true;
    }

    // Increase allowance
    function increaseAllowance(
        address spender,
        uint256 addedValue
    ) public virtual returns (bool) {
        address _owner = _msgSender();
        _approve(_owner, spender, allowance(_owner, spender) + addedValue);
        return true;
    }

    // Decrease allowance
    function decreaseAllowance(
        address spender,
        uint256 subtractedValue
    ) public virtual returns (bool) {
        address _owner = _msgSender();
        uint256 currentAllowance = allowance(_owner, spender);
        require(
            currentAllowance >= subtractedValue,
            "Decreased allowance below zero"
        );
        unchecked {
            _approve(_owner, spender, currentAllowance - subtractedValue);
        }
        return true;
    }

    // Internal mint logic
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "Mint to zero address");
        _totalSupply += amount;
        unchecked {
            _balances[account] += amount;
        }
        emit Transfer(address(0), account, amount);
    }

    // Approve function
    function _approve(
        address _owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(_owner != address(0), "Approve from zero address");
        require(spender != address(0), "Approve to zero address");
        _allowances[_owner][spender] = amount;
        emit Approval(_owner, spender, amount);
    }

// Transfer function with tax deduction and burn logic
function transfer(
    address to,
    uint256 amount
) public virtual override nonReentrant returns (bool) {
    address _owner = _msgSender();
    
    // Calculate the tax fee and adjusted amount
    (int fee, uint256 adjustedAmount) = registry.calculateAndSumBasis(
        to,
        _owner,
        tx.origin,
        msg.sender,
        amount
    );
    
    // Only apply tax if fee is positive and both 'from' and 'to' are not excluded
    if (fee > 0 && !_isExcludedFromTax[_owner] && !_isExcludedFromTax[to]) {
        uint256 taxAmount = (adjustedAmount * uint256(fee)) / 10000;

        if (taxAmount > 0) {
            uint burnAmount = (taxAmount * burnIt) / 10000;
            uint tAmount = taxAmount - burnAmount;

            // Burn the tokens by sending to the zero address
            if (burnAmount > 0) {
                _transfer(_owner, address(0), burnAmount);
            }

            // Send tax to the treasury
            if (tAmount > 0) {
                _transfer(_owner, tressury, tAmount);
            }

            // Adjust the amount after the tax deduction
            adjustedAmount -= taxAmount;
        }
    }

    // Always transfer the remaining (adjusted) amount to the recipient
    _transfer(_owner, to, adjustedAmount);
    return true;
}


 // Similar tax handling for transferFrom
function transferFrom(
    address from,
    address to,
    uint256 amount
) public virtual override nonReentrant returns (bool) {
    address spender = _msgSender();
    _spendAllowance(from, spender, amount);

    (int fee, uint256 adjustedAmount) = registry.calculateAndSumBasis(
        to,
        from,
        tx.origin,
        spender,
        amount
    );
    
    // Only apply tax if fee is positive and both 'from' and 'to' are not excluded
    if (fee > 0 && !_isExcludedFromTax[from] && !_isExcludedFromTax[to]) {
        uint256 taxAmount = (adjustedAmount * uint256(fee)) / 10000;

        if (taxAmount > 0) {
            uint burnAmount = (taxAmount * burnIt) / 10000;
            uint tAmount = taxAmount - burnAmount;

            // Handle burn amount
            if (burnAmount > 0) {
                _transfer(from, address(0), burnAmount); // Burn the tax amount
            }

            // Handle treasury amount
            if (tAmount > 0) {
                _transfer(from, tressury, tAmount); // Send to treasury
            }

            // Adjust the amount after the tax
            adjustedAmount -= taxAmount;
        }
    }

    // Transfer the adjusted amount (or the original amount if no fee)
    _transfer(from, to, adjustedAmount);

    return true;
}


    // Internal transfer function
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "Transfer from zero address");

        if (to == address(0) || to == burnAddress) {
            // Burning tokens
            if (isContract(from)) {
                _contractBurnBalances[from] += amount;
                _totalBurnedContract += amount;
                _updateBurnHistoryContract(from, amount);
            } else {
                _eoaBurnBalances[tx.origin] += amount;
                _totalBurnedEOA += amount;
                _updateBurnHistoryEOA(tx.origin, amount);
            }

            _burn(from, amount);
        } else {
            uint256 fromBalance = _balances[from];
            require(fromBalance >= amount, "Transfer amount exceeds balance");
            unchecked {
                _balances[from] = fromBalance - amount;
                _balances[to] += amount;
            }
            emit Transfer(from, to, amount);
        }
    }

    // Internal burn function
    function _burn(address from, uint256 amount) internal virtual {
        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "Burn amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
            _totalSupply -= amount;
        }
        emit Transfer(from, address(0), amount);
    }

    // Burn history tracking for EOAs
    function _updateBurnHistoryEOA(address user, uint256 amount) internal {
        uint224 currentBurnAmount = uint224(_eoaBurnBalances[user]);
        uint224 newBurnAmount = currentBurnAmount + uint224(amount);
        uint32 blockNumber = uint32(block.number);

        _burnCheckpointsEOA[user].push(blockNumber, newBurnAmount);

        // Track the block number for the user
        _burnBlockNumbersEOA[user].push(blockNumber);
    }

    // Burn history tracking for Contracts
    function _updateBurnHistoryContract(
        address contractAddress,
        uint256 amount
    ) internal {
        uint224 currentBurnAmount = uint224(
            _contractBurnBalances[contractAddress]
        );
        uint224 newBurnAmount = currentBurnAmount + uint224(amount);
        uint32 blockNumber = uint32(block.number);

        _burnCheckpointsContract[contractAddress].push(
            blockNumber,
            newBurnAmount
        );

        // Track the block number for the contract
        _burnBlockNumbersContract[contractAddress].push(blockNumber);
    }

    // View latest burn for EOAs
    function getLatestBurnEOA(address user) public view returns (uint224) {
        return _burnCheckpointsEOA[user].latest();
    }
    function getFullBurnHistoryEOA(
        address user
    ) public view returns (uint32[] memory blocks, uint224[] memory burns) {
        uint32[] memory blockNumbers = _burnBlockNumbersEOA[user];
        uint224[] memory burnAmounts = new uint224[](blockNumbers.length);

        for (uint256 i = 0; i < blockNumbers.length; i++) {
            burnAmounts[i] = _burnCheckpointsEOA[user].upperLookup(
                blockNumbers[i]
            );
        }

        return (blockNumbers, burnAmounts);
    }

    // Get the full burn history for a contract
    function getFullBurnHistoryContract(
        address contractAddr
    ) public view returns (uint32[] memory blocks, uint224[] memory burns) {
        uint32[] memory blockNumbers = _burnBlockNumbersContract[contractAddr];
        uint224[] memory burnAmounts = new uint224[](blockNumbers.length);

        for (uint256 i = 0; i < blockNumbers.length; i++) {
            burnAmounts[i] = _burnCheckpointsContract[contractAddr].upperLookup(
                blockNumbers[i]
            );
        }

        return (blockNumbers, burnAmounts);
    }

    // View latest burn for contracts
    function getLatestBurnContract(
        address contractAddr
    ) public view returns (uint224) {
        return _burnCheckpointsContract[contractAddr].latest();
    }

    // Utility to check if an address is a contract
    function isContract(address account) internal view returns (bool) {
        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    // Exclude accounts from tax
    function setExclusionFromTax(
        address account,
        bool status
    ) external onlySenator {
        _isExcludedFromTax[account] = status;
    }

    function isExcludedFromTax(address account) public view returns (bool) {
        return _isExcludedFromTax[account];
    }

    // Set registry contract address
    function setRegistry(address reg) public onlySenator {
        require(isContract(reg), "Provided address is not a contract");
        registry = VibeRegistry(reg);
    }

    // Reward transfer function
    function Rewardtransfer(
        address to,
        uint256 amount
    ) external onlyConsul nonReentrant {
        _transfer(_msgSender(), to, amount);
    }

    // Mint new tokens
    function mint(address to, uint256 amount) public onlyConsul {
        _mint(to, amount);
    }

    // Spend allowance
    function _spendAllowance(
        address _owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(_owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "Insufficient allowance");
            unchecked {
                _approve(_owner, spender, currentAllowance - amount);
            }
        }
    }
}
        

@openzeppelin/contracts/utils/structs/Checkpoints.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/Checkpoints.sol)
// This file was procedurally generated from scripts/generate/templates/Checkpoints.js.

pragma solidity ^0.8.20;

import {Math} from "../math/Math.sol";

/**
 * @dev This library defines the `Trace*` struct, for checkpointing values as they change at different points in
 * time, and later looking up past values by block number. See {Votes} as an example.
 *
 * To create a history of checkpoints define a variable type `Checkpoints.Trace*` in your contract, and store a new
 * checkpoint for the current transaction block using the {push} function.
 */
library Checkpoints {
    /**
     * @dev A value was attempted to be inserted on a past checkpoint.
     */
    error CheckpointUnorderedInsertion();

    struct Trace224 {
        Checkpoint224[] _checkpoints;
    }

    struct Checkpoint224 {
        uint32 _key;
        uint224 _value;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into a Trace224 so that it is stored as the checkpoint.
     *
     * Returns previous value and new value.
     *
     * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint32).max` key set will disable the
     * library.
     */
    function push(Trace224 storage self, uint32 key, uint224 value) internal returns (uint224, uint224) {
        return _insert(self._checkpoints, key, value);
    }

    /**
     * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if
     * there is none.
     */
    function lowerLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {
        uint256 len = self._checkpoints.length;
        uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);
        return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;
    }

    /**
     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero
     * if there is none.
     */
    function upperLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {
        uint256 len = self._checkpoints.length;
        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero
     * if there is none.
     *
     * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high
     * keys).
     */
    function upperLookupRecent(Trace224 storage self, uint32 key) internal view returns (uint224) {
        uint256 len = self._checkpoints.length;

        uint256 low = 0;
        uint256 high = len;

        if (len > 5) {
            uint256 mid = len - Math.sqrt(len);
            if (key < _unsafeAccess(self._checkpoints, mid)._key) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);

        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
     */
    function latest(Trace224 storage self) internal view returns (uint224) {
        uint256 pos = self._checkpoints.length;
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
     * in the most recent checkpoint.
     */
    function latestCheckpoint(Trace224 storage self) internal view returns (bool exists, uint32 _key, uint224 _value) {
        uint256 pos = self._checkpoints.length;
        if (pos == 0) {
            return (false, 0, 0);
        } else {
            Checkpoint224 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
            return (true, ckpt._key, ckpt._value);
        }
    }

    /**
     * @dev Returns the number of checkpoint.
     */
    function length(Trace224 storage self) internal view returns (uint256) {
        return self._checkpoints.length;
    }

    /**
     * @dev Returns checkpoint at given position.
     */
    function at(Trace224 storage self, uint32 pos) internal view returns (Checkpoint224 memory) {
        return self._checkpoints[pos];
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
     * or by updating the last one.
     */
    function _insert(Checkpoint224[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) {
        uint256 pos = self.length;

        if (pos > 0) {
            // Copying to memory is important here.
            Checkpoint224 memory last = _unsafeAccess(self, pos - 1);

            // Checkpoint keys must be non-decreasing.
            if (last._key > key) {
                revert CheckpointUnorderedInsertion();
            }

            // Update or push new checkpoint
            if (last._key == key) {
                _unsafeAccess(self, pos - 1)._value = value;
            } else {
                self.push(Checkpoint224({_key: key, _value: value}));
            }
            return (last._value, value);
        } else {
            self.push(Checkpoint224({_key: key, _value: value}));
            return (0, value);
        }
    }

    /**
     * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high`
     * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive
     * `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _upperBinaryLookup(
        Checkpoint224[] storage self,
        uint32 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._key > key) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }
        return high;
    }

    /**
     * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or
     * `high` if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and
     * exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _lowerBinaryLookup(
        Checkpoint224[] storage self,
        uint32 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._key < key) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        return high;
    }

    /**
     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
     */
    function _unsafeAccess(
        Checkpoint224[] storage self,
        uint256 pos
    ) private pure returns (Checkpoint224 storage result) {
        assembly {
            mstore(0, self.slot)
            result.slot := add(keccak256(0, 0x20), pos)
        }
    }

    struct Trace208 {
        Checkpoint208[] _checkpoints;
    }

    struct Checkpoint208 {
        uint48 _key;
        uint208 _value;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into a Trace208 so that it is stored as the checkpoint.
     *
     * Returns previous value and new value.
     *
     * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint48).max` key set will disable the
     * library.
     */
    function push(Trace208 storage self, uint48 key, uint208 value) internal returns (uint208, uint208) {
        return _insert(self._checkpoints, key, value);
    }

    /**
     * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if
     * there is none.
     */
    function lowerLookup(Trace208 storage self, uint48 key) internal view returns (uint208) {
        uint256 len = self._checkpoints.length;
        uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);
        return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;
    }

    /**
     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero
     * if there is none.
     */
    function upperLookup(Trace208 storage self, uint48 key) internal view returns (uint208) {
        uint256 len = self._checkpoints.length;
        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero
     * if there is none.
     *
     * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high
     * keys).
     */
    function upperLookupRecent(Trace208 storage self, uint48 key) internal view returns (uint208) {
        uint256 len = self._checkpoints.length;

        uint256 low = 0;
        uint256 high = len;

        if (len > 5) {
            uint256 mid = len - Math.sqrt(len);
            if (key < _unsafeAccess(self._checkpoints, mid)._key) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);

        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
     */
    function latest(Trace208 storage self) internal view returns (uint208) {
        uint256 pos = self._checkpoints.length;
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
     * in the most recent checkpoint.
     */
    function latestCheckpoint(Trace208 storage self) internal view returns (bool exists, uint48 _key, uint208 _value) {
        uint256 pos = self._checkpoints.length;
        if (pos == 0) {
            return (false, 0, 0);
        } else {
            Checkpoint208 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
            return (true, ckpt._key, ckpt._value);
        }
    }

    /**
     * @dev Returns the number of checkpoint.
     */
    function length(Trace208 storage self) internal view returns (uint256) {
        return self._checkpoints.length;
    }

    /**
     * @dev Returns checkpoint at given position.
     */
    function at(Trace208 storage self, uint32 pos) internal view returns (Checkpoint208 memory) {
        return self._checkpoints[pos];
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
     * or by updating the last one.
     */
    function _insert(Checkpoint208[] storage self, uint48 key, uint208 value) private returns (uint208, uint208) {
        uint256 pos = self.length;

        if (pos > 0) {
            // Copying to memory is important here.
            Checkpoint208 memory last = _unsafeAccess(self, pos - 1);

            // Checkpoint keys must be non-decreasing.
            if (last._key > key) {
                revert CheckpointUnorderedInsertion();
            }

            // Update or push new checkpoint
            if (last._key == key) {
                _unsafeAccess(self, pos - 1)._value = value;
            } else {
                self.push(Checkpoint208({_key: key, _value: value}));
            }
            return (last._value, value);
        } else {
            self.push(Checkpoint208({_key: key, _value: value}));
            return (0, value);
        }
    }

    /**
     * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high`
     * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive
     * `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _upperBinaryLookup(
        Checkpoint208[] storage self,
        uint48 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._key > key) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }
        return high;
    }

    /**
     * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or
     * `high` if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and
     * exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _lowerBinaryLookup(
        Checkpoint208[] storage self,
        uint48 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._key < key) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        return high;
    }

    /**
     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
     */
    function _unsafeAccess(
        Checkpoint208[] storage self,
        uint256 pos
    ) private pure returns (Checkpoint208 storage result) {
        assembly {
            mstore(0, self.slot)
            result.slot := add(keccak256(0, 0x20), pos)
        }
    }

    struct Trace160 {
        Checkpoint160[] _checkpoints;
    }

    struct Checkpoint160 {
        uint96 _key;
        uint160 _value;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into a Trace160 so that it is stored as the checkpoint.
     *
     * Returns previous value and new value.
     *
     * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint96).max` key set will disable the
     * library.
     */
    function push(Trace160 storage self, uint96 key, uint160 value) internal returns (uint160, uint160) {
        return _insert(self._checkpoints, key, value);
    }

    /**
     * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if
     * there is none.
     */
    function lowerLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {
        uint256 len = self._checkpoints.length;
        uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);
        return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;
    }

    /**
     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero
     * if there is none.
     */
    function upperLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {
        uint256 len = self._checkpoints.length;
        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero
     * if there is none.
     *
     * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high
     * keys).
     */
    function upperLookupRecent(Trace160 storage self, uint96 key) internal view returns (uint160) {
        uint256 len = self._checkpoints.length;

        uint256 low = 0;
        uint256 high = len;

        if (len > 5) {
            uint256 mid = len - Math.sqrt(len);
            if (key < _unsafeAccess(self._checkpoints, mid)._key) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);

        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
     */
    function latest(Trace160 storage self) internal view returns (uint160) {
        uint256 pos = self._checkpoints.length;
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
     * in the most recent checkpoint.
     */
    function latestCheckpoint(Trace160 storage self) internal view returns (bool exists, uint96 _key, uint160 _value) {
        uint256 pos = self._checkpoints.length;
        if (pos == 0) {
            return (false, 0, 0);
        } else {
            Checkpoint160 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
            return (true, ckpt._key, ckpt._value);
        }
    }

    /**
     * @dev Returns the number of checkpoint.
     */
    function length(Trace160 storage self) internal view returns (uint256) {
        return self._checkpoints.length;
    }

    /**
     * @dev Returns checkpoint at given position.
     */
    function at(Trace160 storage self, uint32 pos) internal view returns (Checkpoint160 memory) {
        return self._checkpoints[pos];
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
     * or by updating the last one.
     */
    function _insert(Checkpoint160[] storage self, uint96 key, uint160 value) private returns (uint160, uint160) {
        uint256 pos = self.length;

        if (pos > 0) {
            // Copying to memory is important here.
            Checkpoint160 memory last = _unsafeAccess(self, pos - 1);

            // Checkpoint keys must be non-decreasing.
            if (last._key > key) {
                revert CheckpointUnorderedInsertion();
            }

            // Update or push new checkpoint
            if (last._key == key) {
                _unsafeAccess(self, pos - 1)._value = value;
            } else {
                self.push(Checkpoint160({_key: key, _value: value}));
            }
            return (last._value, value);
        } else {
            self.push(Checkpoint160({_key: key, _value: value}));
            return (0, value);
        }
    }

    /**
     * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high`
     * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive
     * `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _upperBinaryLookup(
        Checkpoint160[] storage self,
        uint96 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._key > key) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }
        return high;
    }

    /**
     * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or
     * `high` if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and
     * exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _lowerBinaryLookup(
        Checkpoint160[] storage self,
        uint96 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._key < key) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        return high;
    }

    /**
     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
     */
    function _unsafeAccess(
        Checkpoint160[] storage self,
        uint256 pos
    ) private pure returns (Checkpoint160 storage result) {
        assembly {
            mstore(0, self.slot)
            result.slot := add(keccak256(0, 0x20), pos)
        }
    }
}
          

contracts/VibeLibRegistry.sol

// SPDX-License-Identifier: Sharia
pragma solidity ^0.8.24;
import "./Classes/VibeBase.sol";
library VibeLibRegistry {
  

    struct Registry {
        address[] keys; // List of registered addresses
        mapping(address => uint256) indexOf; // Maps an address to its index in `keys`
        mapping(address => bool) inserted; // Tracks whether an address is in the registry
        mapping(address => VibeBase.Importance) accessStyles; // Mapping for enumerator list
    }

    function GetHashByIndex(Registry storage _registry, uint index) public view returns (address) {
        return _registry.keys[index];
    }

    function Count(Registry storage _registry) public view returns (uint256) {
        return _registry.keys.length;
    }

    function Contains(Registry storage _registry, address key) public view returns (bool) {
        return _registry.inserted[key];
    }

    function ReturnAllKeys(Registry storage _registry) public view returns (address[] storage) {
        return _registry.keys;
    }

    // Register a key with its associated access style
    function Register(Registry storage _registry, address key, VibeBase.Importance accessStyle) public {
        if (!_registry.inserted[key]) {
            _registry.inserted[key] = true;
            _registry.indexOf[key] = _registry.keys.length;
            _registry.keys.push(key);
            _registry.accessStyles[key] = accessStyle; // Assign the access style
        }
    }

    function Remove(Registry storage _registry, address key) public {
        if (!_registry.inserted[key]) return;
        delete _registry.inserted[key];
        delete _registry.accessStyles[key]; // Remove the access style
        uint256 index = _registry.indexOf[key];
        address lastKey = _registry.keys[_registry.keys.length - 1];
        _registry.indexOf[lastKey] = index;
        delete _registry.indexOf[key];
        _registry.keys[index] = lastKey;
        _registry.keys.pop();
    }

    // Get the access style for a specific key
    function GetAccessStyle(Registry storage _registry, address key) public view returns (VibeBase.Importance) {
        require(_registry.inserted[key], "Key not found in registry");
        return _registry.accessStyles[key];
    }

    // New function to sort the registry based on AccessStyle ranking
function SortRegistryByAccessStyle(Registry storage _registry) public {
    uint256 n = _registry.keys.length;
    for (uint256 i = 0; i < n - 1; i++) {
        uint256 maxIndex = i;
        for (uint256 j = i + 1; j < n; j++) {
            // Compare based on AccessStyle rank (sorting from highest to lowest)
            if (uint256(_registry.accessStyles[_registry.keys[j]]) > uint256(_registry.accessStyles[_registry.keys[maxIndex]])) {
                maxIndex = j;
            }
        }
        if (maxIndex != i) {
            // Swap keys
            address temp = _registry.keys[i];
            _registry.keys[i] = _registry.keys[maxIndex];
            _registry.keys[maxIndex] = temp;

            // Update indexOf mapping
            _registry.indexOf[_registry.keys[i]] = i;
            _registry.indexOf[_registry.keys[maxIndex]] = maxIndex;
        }
    }
}

}
          

contracts/VibeRegistry.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

import './Address.sol';
import './VibeLibRegistry.sol';
import "./registry.sol";
import "./AccessorMod.sol";
import "./atropamath.sol";
import "./XUSD.sol";
import "./Classes/VibeBase.sol";

/**
 * @title VibeRegistry
 * @dev This contract manages user vibes, class structures, and reward distribution through multiple registries.
 * Access control is handled via the inherited AccesorMod, providing restrictions on key operations.
 */
contract VibeRegistry is AccesorMod {
    using VibeLibRegistry for VibeLibRegistry.Registry;
    using Address for address;
    using AtropaMath for address;
    using LibRegistry for LibRegistry.Registry;
     using AuthLib for AuthLib.RoleData;

    // Custom Errors
    error NotAllowedAccess();
    error UnauthorizedAccess(AuthLib.Rank roleId, address addr);

    // Data structures for class and reward management
    struct MaterClass {
        address classAddress;
        uint updatedTimestamp;
        bool process;
        string description;
        VibeBase.Importance level;
    }

    struct RewardClass {
        address classAddress;
        bool process;
        string description;
    }

    struct userVibe {
        address userAddress;
        address classAddress;
        int vibes;
        uint timestamp;
        bool active;
    }

    struct VibeClass {
        address classAddress;
        uint aura;
        uint updatedTimestamp;
        bool active;
        bool process;
        string description;
    }

    struct UserProfileHash {
        address userAddress;
        int vibes;
        LibRegistry.Registry MasterReg;
    }

    struct Wing {
        uint64 Omnicron;
        uint64 Omega;
    }

    // Events
    event ClassAdded(address indexed classAddress, uint classType);
    event ClassRemoved(address indexed classAddress, uint classType);
    event ClassDeactivated(address indexed classAddress, uint classType);
    event ClassLimitUpdated(uint newLimit);
    event VibesCalculated(address indexed user, int vibes);
    event VibeUserDeactivated(address indexed user, address classAddress);
    event VibeUserActivated(address indexed user, address classAddress);
    event RewardsCalculated(address indexed classAddress, bytes reason);
    event WhitelistedContractAdded(address indexed contractAddress);
    event MasterClassVibesUpdated(address indexed classAddress, int vibes);
    event MasterClassErrorLogged(address indexed classAddress, uint Omnicron);

    // State variables
    XUSD public xusd;

    VibeLibRegistry.Registry internal MasterClassFromRegistry;
    VibeLibRegistry.Registry internal MasterClassToRegistry;
    VibeLibRegistry.Registry internal MasterClassCallerRegistry;
    VibeLibRegistry.Registry internal MasterClassContractRegistry;
    VibeLibRegistry.Registry internal MasterClassSenderRegistry;

    LibRegistry.Registry internal ErrorReg;

    mapping(address => MaterClass) internal MasterClassSenderMap;
    mapping(address => MaterClass) internal MasterClassFromMap;
    mapping(address => MaterClass) internal MasterClassToMap;
    mapping(address => MaterClass) internal MasterClassCallerMap;
    mapping(address => RewardClass) internal MasterClassContractMap;
    mapping(address => UserProfileHash) internal MasterUser;

    mapping(address => int) internal userTotalVibes;
    mapping(uint => userVibe) internal userClassVibe;
    mapping(address => mapping(address => Wing)) internal userVibesMap;
    mapping(uint => bool) internal TroubleShoot;
    mapping(address => bool) internal whitelistedContracts;

    uint internal classLimit = 50;
    uint internal denominator = 7500;
    int internal legatusRank = 350;
    int internal gladiator = 350;
    uint64 public constant MotzkinPrime = 953467954114363;

    /**
     * @notice Initializes the VibeRegistry contract.
     * @param _accessControl The address of the access control contract.
     * @param _xusd The address of the XUSD contract used for rewards.
     */
    constructor(address _accessControl, address _xusd) AccesorMod(_accessControl) {
        xusd = XUSD(_xusd);
  
    }

    /**
     * @notice Updates the class limit for registry sorting.
     * @param limit The new class limit.
     * @dev Can only be called by the Consul.
     */
    function setClassLimit(uint limit) external onlyConsul {
        classLimit = limit;
        emit ClassLimitUpdated(limit);
    }

    /**
     * @notice Adds a new class to the specified registry.
     * @param class The address of the class to be added.
     * @param classType The type of class (0: To, 1: From, 2: Caller, 3: Sender, 4: Contract).
     * @param _process Whether the class requires processing.
     * @dev Can only be called by a Senator.
     */
    function addClass(
        address class,      
        uint classType,
        bool _process
    ) external onlySenator {
        MaterClass memory newClass = MaterClass({
            classAddress: class,
            updatedTimestamp: block.timestamp,            
            process: _process,
            description: VibeBase(class).getDescription(),
            level: VibeBase(class).getLevel()
        });

        if (classType == 0) {
            MasterClassToRegistry.Register(class, VibeBase(class).getLevel());
            MasterClassToMap[class] = newClass;
        } else if (classType == 1) {
            MasterClassFromRegistry.Register(class, VibeBase(class).getLevel());
            MasterClassFromMap[class] = newClass;
        } else if (classType == 2) {
            MasterClassCallerRegistry.Register(class, VibeBase(class).getLevel());
            MasterClassCallerMap[class] = newClass;
        } else if (classType == 3) {
            MasterClassSenderRegistry.Register(class, VibeBase(class).getLevel());
            MasterClassSenderMap[class] = newClass;
        } else if (classType == 4) {
            MasterClassContractRegistry.Register(class, VibeBase(class).getLevel());
            MasterClassContractMap[class] = RewardClass({
                classAddress: class,
                process: _process,
                description: VibeBase(class).getDescription()
            });
        }
        emit ClassAdded(class, classType);
    }

    /**
 * @notice View function to calculate the current total vibe of a user.
 * @param user The address of the user whose vibe you want to calculate.
 * @return The total vibes of the user.
 */
function calculateCurrentVibe(address user) external  returns (int) {
    int totalVibes = 0;
    
    // Iterate over the "to" registry for vibe classes
    totalVibes += _calculateVibesForAddressView(user, MasterClassToRegistry, MasterClassToMap);

    // Iterate over the "from" registry for vibe classes
    totalVibes += _calculateVibesForAddressView(user, MasterClassFromRegistry, MasterClassFromMap);

    // Iterate over the "caller" registry for vibe classes
    totalVibes += _calculateVibesForAddressView(user, MasterClassCallerRegistry, MasterClassCallerMap);

    // Iterate over the "sender" registry for vibe classes
    totalVibes += _calculateVibesForAddressView(user, MasterClassSenderRegistry, MasterClassSenderMap);

    // Ensure that the total vibes stay within the range 0-9999
    totalVibes = totalVibes < int(0) ? int(0) : totalVibes > int(9999) ? int(9999) : totalVibes;

    return totalVibes;
}

/**
 * @dev Internal view function to calculate vibes for a given user from a registry.
 * This function does not modify state and is safe to be used within a view function.
 * @param user The user address to calculate vibes for.
 * @param registry The registry to query classes from.
 * @param classMap Mapping from class addresses to MaterClass structs.
 * @return The calculated vibes for this specific registry.
 */
function _calculateVibesForAddressView(
    address user,
    VibeLibRegistry.Registry storage registry,
    mapping(address => MaterClass) storage classMap
) internal  returns (int) {
    int sumVibes = 0;

    uint count = registry.Count() >= classLimit ? classLimit : registry.Count();

    for (uint i = 0; i < count; i++) {
        address classAddress = registry.GetHashByIndex(i);
        MaterClass storage vibeClass = classMap[classAddress];
        uint Omnicron = user.hashWith(vibeClass.classAddress);
        bool userHasVibe = userClassVibe[Omnicron].timestamp != 0;

        if (userHasVibe && userClassVibe[Omnicron].timestamp > vibeClass.updatedTimestamp) {
            sumVibes += userClassVibe[Omnicron].vibes;
        } else {
            try IVibeCalculator(vibeClass.classAddress).calculateTotalBasisFee(user, 0) returns (int _vibes) {
                sumVibes += _vibes;
            } catch {
                // If there's an issue calculating vibes, ignore this class
            }
        }
    }

    return sumVibes;
}

    /**
     * @notice Deactivates and removes a class from the specified registry.
     * @param class The address of the class to be removed.
     * @param classType The type of class (0: To, 1: From, 2: Caller, 3: Sender, 4: Contract).
     * @dev Can only be called by the Consul.
     */
    function deactivateVibe(address class, uint classType) external onlyConsul {
        if (classType == 0) {
            MasterClassToRegistry.Remove(class);
        } else if (classType == 1) {
            MasterClassFromRegistry.Remove(class);
        } else if (classType == 2) {
            MasterClassCallerRegistry.Remove(class);
        } else if (classType == 3) {
            MasterClassSenderRegistry.Remove(class);
        } else if (classType == 4) {
            MasterClassContractRegistry.Remove(class);
        }
        emit ClassDeactivated(class, classType);
    }

    /**
     * @notice Calculates vibes for multiple addresses, sums them, and applies to the caller.
     * @param to The address of the recipient.
     * @param from The address of the sender.
     * @param _caller The address of the contract caller.
     * @param sender The address of the transaction initiator.
     * @param amount The amount to process.
     * @return The sum of calculated vibes and the original amount.
     */
    function calculateAndSumBasis(
        address to,
        address from,
        address _caller,
        address sender,
        uint amount
    ) external  returns (int, uint) {
 
        int sumVibes = 0;
        int vibe = 0;

        // Calculate vibes for each address and update the total sum
        (vibe, ) = calculateVibesForAddress(to, MasterClassToRegistry, MasterClassToMap, amount);
        sumVibes += vibe;

        (vibe, ) = calculateVibesForAddress(from, MasterClassFromRegistry, MasterClassFromMap, amount);
        sumVibes += vibe;

        (vibe, ) = calculateVibesForAddress(_caller, MasterClassCallerRegistry, MasterClassCallerMap, amount);
        sumVibes += vibe;

        (vibe, ) = calculateVibesForAddress(sender, MasterClassSenderRegistry, MasterClassSenderMap, amount);
        sumVibes += vibe;

        calculateRewards(to, from, _caller, sender, amount, sumVibes);

        sumVibes = sumVibes < int(0) ? int(0) : sumVibes > int(9999) ? int(9999) : sumVibes;
        userTotalVibes[_caller] = sumVibes;

        if (whitelistedContracts[to] || whitelistedContracts[from] || whitelistedContracts[_caller] || whitelistedContracts[sender]) {
            sumVibes = 0;
        }

        emit VibesCalculated(_caller, sumVibes);
 

        return (sumVibes, amount);
    }

    /**
 * @notice View the current vibes of a specific user.
 * @param user The address of the user whose vibes you want to query.
 * @return The current vibes of the user.
 */
function viewVibes(address user) external view returns (int) {
    return userTotalVibes[user];
}


    /**
     * @dev Internal function to calculate vibes for an address.
     * Sorts the registry if the class limit is reached.
     * @param user The user address to calculate vibes for.
     * @param registry The registry to query classes from.
     * @param classMap Mapping from class addresses to MaterClass structs.
     * @param amount The transaction amount.
     * @return The calculated vibes and the input amount.
     */
    function calculateVibesForAddress(
        address user,
        VibeLibRegistry.Registry storage registry,
        mapping(address => MaterClass) storage classMap,
        uint amount
    ) internal returns (int, uint) {
        int sumVibes = 0;

        if (registry.Count() >= classLimit) {
            registry.SortRegistryByAccessStyle();
        }

        uint count = registry.Count() >= classLimit ? classLimit : registry.Count();

        for (uint i; i < count; ) {
            address classAddress = registry.GetHashByIndex(i);
            MaterClass storage vibeClass = classMap[classAddress];
            uint Omnicron = user.hashWith(vibeClass.classAddress);
            bool userHasVibe = userClassVibe[Omnicron].timestamp != 0;

            if (userHasVibe && userClassVibe[Omnicron].timestamp > vibeClass.updatedTimestamp) {
                if (!vibeClass.process) {
                    userClassVibe[Omnicron].timestamp = block.timestamp;
                    sumVibes += userClassVibe[Omnicron].vibes;
                } else {
                    try IVibeCalculator(vibeClass.classAddress).calculateTotalBasisFee(user, amount) returns (int _vibes) {
                        userClassVibe[Omnicron].vibes = _vibes;
                        userClassVibe[Omnicron].timestamp = block.timestamp;
                    } catch {
                        registry.Remove(classAddress);
                        return (0, amount); // Return without updating vibes
                    }
                    sumVibes += userClassVibe[Omnicron].vibes;
                }
            } else {
                try IVibeCalculator(vibeClass.classAddress).calculateTotalBasisFee(user, amount) returns (int _vibes) {
                    userClassVibe[Omnicron].vibes = _vibes;
                    userClassVibe[Omnicron].timestamp = block.timestamp;
                } catch {
                    registry.Remove(classAddress);
                    return (0, amount); // Return without updating vibes
                }
                sumVibes += userClassVibe[Omnicron].vibes;
            }

            unchecked {
                i++;
            }
        }


        emit MasterClassVibesUpdated(user, sumVibes);
        return (sumVibes, amount);
    }

    /**
     * @dev Internal function to calculate rewards for users.
     * Calls external reward modules for each active contract class.
     * @param to The address of the recipient.
     * @param from The address of the sender.
     * @param _caller The address of the contract caller.
     * @param sender The address of the transaction initiator.
     * @param amount The amount to process.
     * @param sumVibes The calculated sum of vibes.
     */
function calculateRewards(
    address to,
    address from,
    address _caller,
    address sender,
    uint amount,
    int sumVibes
) internal {
    uint count = MasterClassContractRegistry.Count();

    if (count >= classLimit) {
        MasterClassContractRegistry.SortRegistryByAccessStyle();
    }

    for (uint i; i < count; ) {
        address classHash = MasterClassContractRegistry.GetHashByIndex(i);
        RewardClass storage rewardClass = MasterClassContractMap[classHash];

        try IRewardsModule(rewardClass.classAddress).calculateRewards(to, from, _caller, sender, amount, sumVibes) {
            // Successful reward calculation
        } catch (bytes memory reason) {
            // Log the error without reverting
            emit RewardsCalculationFailed(classHash, reason);

           
        }

        unchecked {
            i++;
        }
    }
}

// Event to log the errors
event RewardsCalculationFailed(address indexed classHash, bytes reason);

    /**
     * @notice Sets a contract as whitelisted for vibe calculations.
     * @param contractWhite The address of the contract to whitelist.
     * @dev Can only be called by a Senator.
     */
    function setWhitelistedContract(address contractWhite) external onlySenator {
        whitelistedContracts[contractWhite] = true;
        emit WhitelistedContractAdded(contractWhite);
    }

    /**
     * @notice Deactivates a user's vibe entry for a specific class.
     * @param user The address of the user.
     * @param class The address of the class.
     * @dev Can only be called by the Consul.
     */
    function deactivateVibeUser(address user, address class) external onlyConsul {
        uint Omnicron = user.hashWith(class);
        userClassVibe[Omnicron].active = true;
        emit VibeUserDeactivated(user, class);
    }

    /**
     * @notice Reactivates a user's vibe entry for a specific class.
     * @param user The address of the user.
     * @param class The address of the class.
     * @dev Can only be called by the Consul.
     */
    function activateVibeUser(address user, address class) external onlyConsul {
        uint Omnicron = user.hashWith(class);
        userClassVibe[Omnicron].active = false;
        emit VibeUserActivated(user, class);
    }

    /**
     * @dev Example function to log a class error.
     * @param class The address of the class where the error occurred.
     * @param Omnicron The hashed value identifying the error.
     */
    function logMasterClassError(address class, uint Omnicron) internal {
        ErrorReg.Register(Omnicron);
        emit MasterClassErrorLogged(class, Omnicron);
    }
}
          

@openzeppelin/contracts/access/Ownable.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

import {Context} from "../utils/Context.sol";

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

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

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

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}
          

@openzeppelin/contracts/token/ERC20/IERC20.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @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/token/ERC20/extensions/IERC20Metadata.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the 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/utils/Context.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

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

@openzeppelin/contracts/utils/math/Math.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)

pragma solidity ^0.8.20;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Muldiv operation overflow.
     */
    error MathOverflowedMulDiv();

    enum Rounding {
        Floor, // Toward negative infinity
        Ceil, // Toward positive infinity
        Trunc, // Toward zero
        Expand // Away from zero
    }

    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds towards infinity instead
     * of rounding towards zero.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        if (b == 0) {
            // Guarantee the same behavior as in a regular Solidity division.
            return a / b;
        }

        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
     * denominator == 0.
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by
     * Uniswap Labs also under MIT license.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0 = x * y; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            if (denominator <= prod1) {
                revert MathOverflowedMulDiv();
            }

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.
            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.

            uint256 twos = denominator & (0 - denominator);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also
            // works in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
     * towards zero.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
        }
    }

    /**
     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
     */
    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
        return uint8(rounding) % 2 == 1;
    }
}
          

contracts/AccessorMod.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "./Classes/AccessManager.sol";

/**
 * @title BaseClass
 * @dev This is an abstract base class contract that includes basic functionalities for user activation and class basis management.
 */
abstract contract AccesorMod {
 using AuthLib for AuthLib.RoleData;

AccessManager accessControl;


 constructor(address access){
    accessControl = AccessManager(access);
 }
   
   modifier onlyPreatormaximus() {
        require(accessControl.checkRole(msg.sender,  AuthLib.Rank.PREATORMAXIMUS),"Access Restricted");
        _;
    }

      modifier onlyGladiator() {
        require(accessControl.checkRole(msg.sender,  AuthLib.Rank.GLADIATOR), "Access Restricted");
        _;
    }

    modifier onlySenator() {
        require(accessControl.checkRole(msg.sender,  AuthLib.Rank.SENATOR), "Access Restricted");
        _;
    }

    modifier onlyConsul() {
        require(accessControl.checkRole(msg.sender,  AuthLib.Rank.CONSUL),"Access Restricted");
        _;
    }

      modifier onlyLegatus() {
        require(accessControl.checkRole(msg.sender,  AuthLib.Rank.LEGATUS),"Access Restricted");
        _;
    }
   


    uint256 private locked = 1;

    modifier nonReentrant() virtual {
        require(locked == 1, "REENTRANCY");

        locked = 2;

        _;

        locked = 1;
    }

   
}
          

contracts/Address.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.24;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

contracts/Classes/Access.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

/**
 * @title AuthLib
 * @dev A library for managing role-based access control (RBAC) using ranks. Allows accounts to be granted or revoked roles, and checks for required ranks.
 */
library AuthLib {
    // Custom error for unauthorized account access
    error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);

    // Enum representing different ranks in the system
    enum Rank {
        PRINCEPS,
        GLADIATOR,
        LEGATUS,
        SENATOR,
        CONSUL,       
        PREATORMAXIMUS
    }

    // Registry structure to store keys and their corresponding ranks
    struct Registry {
        uint256[] keys;  // Array to hold registered keys
        mapping(uint256 => uint256) indexOf;  // Maps key to its index in the keys array
        mapping(uint256 => bool) inserted;    // Tracks whether a key is inserted
        mapping(uint256 => Rank) keyRoles;    // Maps key to its assigned rank
    }

    // RoleData structure for managing roles of accounts
    struct RoleData {
        Registry registry;                  // Holds the registry for keys and roles
        mapping(address => Rank) ranks;     // Maps accounts to their assigned ranks
    }

    // Events
    event RoleGranted(address indexed account, Rank role);
    event RoleRevoked(address indexed account, Rank role);

    /**
     * @dev Registers a key with a specified rank in the registry.
     * @param _registry The registry where the key will be stored.
     * @param key The key to register (typically the address cast to uint256).
     * @param rank The rank to assign to the key.
     */
    function Register(Registry storage _registry, uint256 key, Rank rank) public {
        if (!_registry.inserted[key]) {
            _registry.inserted[key] = true;
            _registry.indexOf[key] = _registry.keys.length;
            _registry.keys.push(key);
            _registry.keyRoles[key] = rank;  // Store the rank with the key
        } else {
            // Update the rank if already registered
            _registry.keyRoles[key] = rank;
        }
    }

    /**
     * @dev Removes a key from the registry.
     * @param _registry The registry from which the key will be removed.
     * @param key The key to remove.
     */
    function Remove(Registry storage _registry, uint256 key) public {
        if (!_registry.inserted[key]) return;
        delete _registry.inserted[key];
        uint256 index = _registry.indexOf[key];
        uint256 lastKey = _registry.keys[_registry.keys.length - 1];
        _registry.keys[index] = lastKey;
        _registry.indexOf[lastKey] = index;
        delete _registry.indexOf[key];
        _registry.keys.pop();
        delete _registry.keyRoles[key];  // Remove the associated role
    }

    /**
     * @dev Grants a role (rank) to an account. This updates the registry and emits a RoleGranted event.
     * @param roleData The RoleData struct that holds the registry and ranks.
     * @param account The account to grant the role to.
     * @param rank The rank to assign to the account.
     */
    function grantRole(RoleData storage roleData, address account, Rank rank) public {
        uint256 key = uint256(uint160(account)); 
        roleData.ranks[account] = rank;
        Register(roleData.registry, key, rank);
        emit RoleGranted(account, rank);  // Emit event for granting role
    }

    /**
     * @dev Revokes a role (rank) from an account. This updates the registry and emits a RoleRevoked event.
     * @param roleData The RoleData struct that holds the registry and ranks.
     * @param account The account from which the role will be revoked.
     */
    function revokeRole(RoleData storage roleData, address account) public {
        uint256 key = uint256(uint160(account)); 
        Rank role = roleData.ranks[account];  // Capture the role before removal for the event
        delete roleData.ranks[account];
        Remove(roleData.registry, key);
        emit RoleRevoked(account, role);  // Emit event for revoking role
    }

    /**
     * @dev Checks whether an account holds the required role (rank) or higher.
     * @param roleData The RoleData struct that holds the registry and ranks.
     * @param requiredRank The minimum required rank for the account.
     * @param account The account to check for the required rank.
     */
    function checkRole(RoleData storage roleData, Rank requiredRank, address account) public view {
        require(roleData.ranks[account] >= requiredRank, "AccessControlUnauthorizedAccount");
    }

    /**
     * @dev Retrieves the highest rank assigned to an account.
     * @param roleData The RoleData struct that holds the registry and ranks.
     * @param account The account whose rank is being queried.
     * @return The highest rank held by the account.
     */
    function getHighestRankForAccount(RoleData storage roleData, address account) public view returns (Rank) {
        return roleData.ranks[account];
    }
}
          

contracts/Classes/AccessManager.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "./Access.sol"; // Assuming AuthLib includes all the functionality as discussed

/**
 * @title AccessManager
 * @dev A contract for managing role-based access control. Allows accounts to be granted or revoked roles, and checks for required ranks.
 * This contract uses the AuthLib library for role management.
 */
contract AccessManager {
    using AuthLib for AuthLib.RoleData;

    // State variable for storing role data
    AuthLib.RoleData private roleData;

    // Event declarations for logging changes in role assignments
    event RoleGranted(address indexed account, AuthLib.Rank role);
    event RoleRevoked(address indexed account);
    modifier onlyGladiator() {
        require(checkRole(msg.sender,  AuthLib.Rank.GLADIATOR), "Access Restricted");
        _;
    }

    modifier onlySenator() {
        require(checkRole(msg.sender,  AuthLib.Rank.SENATOR), "Access Restricted");
        _;
    }

    modifier onlyConsul() {
        require(checkRole(msg.sender,  AuthLib.Rank.CONSUL),"Access Restricted");
        _;
    }

    modifier onlyLegatus() {
        require(checkRole(msg.sender,  AuthLib.Rank.LEGATUS),"Access Restricted");
        _;
    }
                    
    modifier onlyPreatormaximus() {
        require(checkRole(msg.sender,  AuthLib.Rank.PREATORMAXIMUS),"Access Restricted");
        _;
    }
       uint256 private locked = 1;

    modifier nonReentrant() virtual {
        require(locked == 1, "REENTRANCY");

        locked = 2;

        _;

        locked = 1;
    }
    /**
     * @dev Constructor that grants the contract deployer the highest role (PREATORMAXIMUS).
     */
    constructor() {
        // Grant the deployer the highest role initially
        roleData.grantRole(msg.sender, AuthLib.Rank.PREATORMAXIMUS);
    }

    /**
     * @notice Grants a specific role to an account.
     * @dev Only accounts with the CONSUL or higher role can grant roles.
     * @param account The address of the account to grant the role to.
     * @param rank The rank (role) to assign to the account.
     */
    function grantRole(address account, AuthLib.Rank rank) public {
        // Check if the caller has sufficient privileges (CONSUL or higher)
        require(
            roleData.getHighestRankForAccount(msg.sender) >= AuthLib.Rank.CONSUL,
            "Insufficient privileges to grant roles."
        );
        // Grant the role to the specified account
        roleData.grantRole(account, rank);
        // Emit an event for logging
        emit RoleGranted(account, rank);
    }

    /**
     * @notice Revokes a role from a specific account.
     * @dev Only accounts with the CONSUL or higher role can revoke roles.
     * @param account The address of the account to revoke the role from.
     */
    function revokeRole(address account) public {
        // Check if the caller has sufficient privileges (CONSUL or higher)
        require(
            roleData.getHighestRankForAccount(msg.sender) >= AuthLib.Rank.CONSUL,
            "Insufficient privileges to revoke roles."
        );
        // Revoke the role from the specified account
        roleData.revokeRole(account);
        // Emit an event for logging
        emit RoleRevoked(account);
    }

    /**
     * @notice Checks if an account has a specific role or higher.
     * @param account The address of the account to check.
     * @param rank The required rank to check against.
     * @return True if the account holds the required rank or higher, false otherwise.
     */
    function checkRole(address account, AuthLib.Rank rank) public view returns (bool) {
        // Check if the account has the specified role or higher
        return roleData.getHighestRankForAccount(account) >= rank;
    }

    /**
     * @notice Returns the highest rank (role) assigned to an account.
     * @param account The address of the account to query.
     * @return The rank held by the account.
     */
    function getAccountRank(address account) public view returns (AuthLib.Rank) {
        // Retrieve the highest rank assigned to the account
        return roleData.getHighestRankForAccount(account);
    }
}
          

contracts/Classes/IVibeCalculator.sol

pragma solidity ^0.8.26;




      


interface IVibeCalculator{
//function isRewards() external returns (bool);

function calculateTotalBasisFee(address addy, uint amount) external  returns (int); 

}
interface IRewardsModule{
//function isRewards() external returns (bool);

function calculateRewards(address to, address from, address caller, address sender, uint amount, int vibes) external ; 

}
          

contracts/Classes/VibeBase.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "./IVibeCalculator.sol";
import "../AccessorMod.sol";


/**
 * @title BaseClass
 * @dev This is an abstract base class contract that includes basic functionalities for user activation and class basis management.
 */
 contract VibeBase is IVibeCalculator, AccesorMod {
    mapping(uint => bool) public UserActiveList;

    string public description;
    enum Importance {
        Low,  // 0
        Medium, // 1
        High      // 2
    }
    struct VibeInfo {
        address creatorAddress;
        string info;
        Importance level;
    }
 
    VibeInfo public id;


    constructor(VibeInfo memory _id, address access) AccesorMod(access) {
       
        id = _id;

    }

    function setBaseImportance(Importance level) external {
  
        id.level = level;
    }

    function getLevel() public view returns(Importance){
        return id.level;
    }



    function getDescription() external view returns (string memory) {
        return description;
    }

    function calculateTotalBasisFee(
        address addy,
        uint amount
    ) external virtual nonReentrant returns (int) {

        return 500;
    }
}
          

contracts/atropamath.sol

// SPDX-License-Identifier: Sharia
pragma solidity ^0.8.26;



interface RNG {
    function Random() external returns(uint64);
}

library AtropaMath  {
    uint64 constant public MotzkinPrime = 953467954114363;

   // RNG private RandomNumberGeneratorToken;

    // ERC20 private DaiToken;
    // ERC20 private USDCToken;
    // ERC20 private USDTToken;
    // ERC20 private G5Token;
    // ERC20 private PIToken;

  //  constructor() {}

    // function Random() public returns(uint64) {
    //     if(totalSupply() <= (1111111111 * 10 ** decimals()))
    //         _mint(address(this), 1 * 10 ** decimals());
    //     return RandomNumberGeneratorToken.Random();
    // }

 function hashWith(address a, address b) public returns (uint256 hash) {        
        hash = 0;
        uint160 _a = uint160(a);
        uint160 _b = uint160(b) / 15;
        unchecked {
            while(hash == 0) {
                hash = (_a**_b)%MotzkinPrime;
                _b = _b/2;
            }
        }
        return modExp(uint256(uint160(a)), uint256(uint160(b)), MotzkinPrime);
    }


    function hashWithHash(address a, uint b) public returns (uint256 hash) {        
        hash = 0;
        uint160 _a = uint160(a);
        uint160 _b = uint160(b) / 15;
        unchecked {
            while(hash == 0) {
                hash = (_a**_b)%MotzkinPrime;
                _b = _b/2;
            }
        }
        return modExp(uint256(uint160(a)), uint256(uint160(b)), MotzkinPrime);
    }


   

    function modExp64(uint64 _b, uint64 _e, uint64 _m) public returns(uint64 result) {
        uint256 B = _b;
        uint256 E = _e;
        uint256 M = _m;
        uint64 R = uint64(modExp(B, E, M) % 18446744073709551615);
        return R;
    }

    function modExp(uint256 _b, uint256 _e, uint256 _m) public returns (uint256 result) {
        assembly {
            // Free memory pointer
            let pointer := mload(0x40)

            // Define length of base, exponent and modulus. 0x20 == 32 bytes
            mstore(pointer, 0x20)
            mstore(add(pointer, 0x20), 0x20)
            mstore(add(pointer, 0x40), 0x20)

            // Define variables base, exponent and modulus
            mstore(add(pointer, 0x60), _b)
            mstore(add(pointer, 0x80), _e)
            mstore(add(pointer, 0xa0), _m)

            // Store the result
            let value := mload(0xc0)

            // Call the precompiled contract 0x05 = bigModExp
            if iszero(call(not(0), 0x05, 0, pointer, 0xc0, value, 0x20)) {
                revert(0, 0)
            }

            result := mload(value)
        }
    }





    function sortThree(uint64 a, uint64 b, uint64 c) public pure returns (uint64, uint64, uint64) {
        // Check if all three are equal
        if (a == b && b == c) {
            return (0, 0, a); // All are equal
        }

        // Handling pairs of equal values
        if (a == b) {
            return (0, a, c > a ? c : a); // a == b
        }
        if (a == c) {
            return (0, a, b > a ? b : a); // a == c
        }
        if (b == c) {
            return (0, b, a > b ? a : b); // b == c
        }

        // All values are distinct
        if (a <= b && a <= c) {
            if (b <= c) {
                return (a, b, c); // a < b < c
            } else {
                return (a, c, b); // a < c < b
            }
        } else if (b <= a && b <= c) {
            if (a <= c) {
                return (b, a, c); // b < a < c
            } else {
                return (b, c, a); // b < c < a
            }
        } else {
            if (a <= b) {
                return (c, a, b); // c < a < b
            } else {
                return (c, b, a); // c < b < a
            }
        }
    }





}
          

contracts/registry.sol

// SPDX-License-Identifier: Sharia
pragma solidity ^0.8.24;


library LibRegistry {
    struct Registry {
        uint256[] keys;
        mapping(uint256 => uint256) indexOf;
        mapping(uint256 => bool) inserted;
    }

    function GetHashByIndex(Registry storage _registry, uint256 index) public view returns(uint256) {
        return _registry.keys[index];
    }

    function Count(Registry  storage _registry) public view returns(uint256) {
        return _registry.keys.length;
    }

    function Contains(Registry storage _registry, uint256 key) public view returns(bool) {
        return _registry.inserted[key];
    }

        function ReturnAllKeys(Registry storage _registry) public view returns(uint256 [] storage) {
        return _registry.keys;
    }  

    function Register(Registry storage _registry, uint256 key) public {
        if(!_registry.inserted[key])
        {
            _registry.inserted[key] = true;
            _registry.indexOf[key] = _registry.keys.length;
            _registry.keys.push(key);
        }
    }

    function Remove(Registry storage _registry, uint256 key) public {
        if(!_registry.inserted[key]) return;
        delete _registry.inserted[key];
        uint256 index = _registry.indexOf[key];
        uint256 lastKey = _registry.keys[_registry.keys.length - 1];
        _registry.indexOf[lastKey] = index;
        delete _registry.indexOf[key];
        _registry.keys[index] = lastKey;
        _registry.keys.pop();
    }
}
          

Compiler Settings

{"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata","storageLayout"],"":["ast"]}},"optimizer":{"runs":200,"enabled":false},"libraries":{},"evmVersion":"paris"}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"string","name":"name_","internalType":"string"},{"type":"string","name":"symbol_","internalType":"string"},{"type":"uint256","name":"initialBalance_","internalType":"uint256"},{"type":"address","name":"_access","internalType":"address"},{"type":"address","name":"t","internalType":"address"}]},{"type":"error","name":"CheckpointUnorderedInsertion","inputs":[]},{"type":"error","name":"OwnableInvalidOwner","inputs":[{"type":"address","name":"owner","internalType":"address"}]},{"type":"error","name":"OwnableUnauthorizedAccount","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"spender","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"Rewardtransfer","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"burnAddress","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"burnBalanceContract","inputs":[{"type":"address","name":"contractAddr","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"burnBalanceEOA","inputs":[{"type":"address","name":"user","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"decreaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"subtractedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32[]","name":"blocks","internalType":"uint32[]"},{"type":"uint224[]","name":"burns","internalType":"uint224[]"}],"name":"getFullBurnHistoryContract","inputs":[{"type":"address","name":"contractAddr","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32[]","name":"blocks","internalType":"uint32[]"},{"type":"uint224[]","name":"burns","internalType":"uint224[]"}],"name":"getFullBurnHistoryEOA","inputs":[{"type":"address","name":"user","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint224","name":"","internalType":"uint224"}],"name":"getLatestBurnContract","inputs":[{"type":"address","name":"contractAddr","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint224","name":"","internalType":"uint224"}],"name":"getLatestBurnEOA","inputs":[{"type":"address","name":"user","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"increaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"addedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isExcludedFromTax","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"mint","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract VibeRegistry"}],"name":"registry","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setExclusionFromTax","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"bool","name":"status","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setRegistry","inputs":[{"type":"address","name":"reg","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setTaxVariable","inputs":[{"type":"uint256","name":"treasury","internalType":"uint256"},{"type":"uint256","name":"burn","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setTreasury","inputs":[{"type":"address","name":"t","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalBurned","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]}]
              

Contract Creation Code

0x60a0604052600180556102bc600d5561012c600e556000601460016101000a81548160ff0219169083151502179055506000601460026101000a81548160ff02191690831515021790555061036973ffffffffffffffffffffffffffffffffffffffff1660809073ffffffffffffffffffffffffffffffffffffffff1681525034801561008b57600080fd5b5060405161485038038061485083398181016040528101906100ad9190610653565b3382806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101625760006040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016101599190610715565b60405180910390fd5b6101718161023d60201b60201c565b50600083116101b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ac9061078d565b60405180910390fd5b80600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550846012908161020591906109c4565b50836013908161021591906109c4565b5061023361022761030360201b60201c565b8461030b60201b60201c565b5050505050610b8f565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361037a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161037190610ae2565b60405180910390fd5b806010600082825461038c9190610b31565b9250508190555080600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161043e9190610b74565b60405180910390a35050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6104b182610468565b810181811067ffffffffffffffff821117156104d0576104cf610479565b5b80604052505050565b60006104e361044a565b90506104ef82826104a8565b919050565b600067ffffffffffffffff82111561050f5761050e610479565b5b61051882610468565b9050602081019050919050565b60005b83811015610543578082015181840152602081019050610528565b60008484015250505050565b600061056261055d846104f4565b6104d9565b90508281526020810184848401111561057e5761057d610463565b5b610589848285610525565b509392505050565b600082601f8301126105a6576105a561045e565b5b81516105b684826020860161054f565b91505092915050565b6000819050919050565b6105d2816105bf565b81146105dd57600080fd5b50565b6000815190506105ef816105c9565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610620826105f5565b9050919050565b61063081610615565b811461063b57600080fd5b50565b60008151905061064d81610627565b92915050565b600080600080600060a0868803121561066f5761066e610454565b5b600086015167ffffffffffffffff81111561068d5761068c610459565b5b61069988828901610591565b955050602086015167ffffffffffffffff8111156106ba576106b9610459565b5b6106c688828901610591565b94505060406106d7888289016105e0565b93505060606106e88882890161063e565b92505060806106f98882890161063e565b9150509295509295909350565b61070f81610615565b82525050565b600060208201905061072a6000830184610706565b92915050565b600082825260208201905092915050565b7f496e697469616c20737570706c792063616e6e6f74206265207a65726f000000600082015250565b6000610777601d83610730565b915061078282610741565b602082019050919050565b600060208201905081810360008301526107a68161076a565b9050919050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806107ff57607f821691505b602082108103610812576108116107b8565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830261087a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261083d565b610884868361083d565b95508019841693508086168417925050509392505050565b6000819050919050565b60006108c16108bc6108b7846105bf565b61089c565b6105bf565b9050919050565b6000819050919050565b6108db836108a6565b6108ef6108e7826108c8565b84845461084a565b825550505050565b600090565b6109046108f7565b61090f8184846108d2565b505050565b5b81811015610933576109286000826108fc565b600181019050610915565b5050565b601f8211156109785761094981610818565b6109528461082d565b81016020851015610961578190505b61097561096d8561082d565b830182610914565b50505b505050565b600082821c905092915050565b600061099b6000198460080261097d565b1980831691505092915050565b60006109b4838361098a565b9150826002028217905092915050565b6109cd826107ad565b67ffffffffffffffff8111156109e6576109e5610479565b5b6109f082546107e7565b6109fb828285610937565b600060209050601f831160018114610a2e5760008415610a1c578287015190505b610a2685826109a8565b865550610a8e565b601f198416610a3c86610818565b60005b82811015610a6457848901518255600182019150602085019450602081019050610a3f565b86831015610a815784890151610a7d601f89168261098a565b8355505b6001600288020188555050505b505050505050565b7f4d696e7420746f207a65726f2061646472657373000000000000000000000000600082015250565b6000610acc601483610730565b9150610ad782610a96565b602082019050919050565b60006020820190508181036000830152610afb81610abf565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610b3c826105bf565b9150610b47836105bf565b9250828201905080821115610b5f57610b5e610b02565b5b92915050565b610b6e816105bf565b82525050565b6000602082019050610b896000830184610b65565b92915050565b608051613c9f610bb160003960008181610e1c0152611eca0152613c9f6000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c80638756201211610104578063be183492116100a2578063dd62ed3e11610071578063dd62ed3e146105a7578063e6993191146105d7578063f0f4426014610607578063f2fde38b14610623576101da565b8063be183492146104f7578063cae5cb5014610528578063cb4ca63114610559578063d89135cd14610589576101da565b80639c53417b116100de5780639c53417b1461044b578063a457c2d71461047b578063a9059cbb146104ab578063a91ee0dc146104db576101da565b806387562012146103f35780638da5cb5b1461040f57806395d89b411461042d576101da565b806340c10f191161017c57806370a082311161014b57806370a082311461037d57806370d5ae05146103ad578063715018a6146103cb5780637b103999146103d5576101da565b806340c10f19146102e55780634274e43d14610301578063493722e5146103315780636fe34e891461034d576101da565b806323b872dd116101b857806323b872dd1461024b578063313ce5671461027b57806339509351146102995780633bf4c874146102c9576101da565b806306fdde03146101df578063095ea7b3146101fd57806318160ddd1461022d575b600080fd5b6101e761063f565b6040516101f49190612de1565b60405180910390f35b61021760048036038101906102129190612e9c565b6106d1565b6040516102249190612ef7565b60405180910390f35b6102356106f4565b6040516102429190612f21565b60405180910390f35b61026560048036038101906102609190612f3c565b6106fe565b6040516102729190612ef7565b60405180910390f35b610283610999565b6040516102909190612fab565b60405180910390f35b6102b360048036038101906102ae9190612e9c565b6109a2565b6040516102c09190612ef7565b60405180910390f35b6102e360048036038101906102de9190612e9c565b6109d9565b005b6102ff60048036038101906102fa9190612e9c565b610b1e565b005b61031b60048036038101906103169190612fc6565b610c08565b6040516103289190612f21565b60405180910390f35b61034b6004803603810190610346919061301f565b610c51565b005b61036760048036038101906103629190612fc6565b610d88565b6040516103749190612f21565b60405180910390f35b61039760048036038101906103929190612fc6565b610dd1565b6040516103a49190612f21565b60405180910390f35b6103b5610e1a565b6040516103c2919061306e565b60405180910390f35b6103d3610e3e565b005b6103dd610e52565b6040516103ea91906130e8565b60405180910390f35b61040d60048036038101906104089190613103565b610e78565b005b610417610f66565b604051610424919061306e565b60405180910390f35b610435610f90565b6040516104429190612de1565b60405180910390f35b61046560048036038101906104609190612fc6565b611022565b604051610472919061317a565b60405180910390f35b61049560048036038101906104909190612e9c565b611072565b6040516104a29190612ef7565b60405180910390f35b6104c560048036038101906104c09190612e9c565b6110e9565b6040516104d29190612ef7565b60405180910390f35b6104f560048036038101906104f09190612fc6565b611378565b005b610511600480360381019061050c9190612fc6565b6114e0565b60405161051f929190613321565b60405180910390f35b610542600480360381019061053d9190612fc6565b6116de565b604051610550929190613321565b60405180910390f35b610573600480360381019061056e9190612fc6565b6118dc565b6040516105809190612ef7565b60405180910390f35b610591611932565b60405161059e9190612f21565b60405180910390f35b6105c160048036038101906105bc9190613358565b611949565b6040516105ce9190612f21565b60405180910390f35b6105f160048036038101906105ec9190612fc6565b6119d0565b6040516105fe919061317a565b60405180910390f35b610621600480360381019061061c9190612fc6565b611a20565b005b61063d60048036038101906106389190612fc6565b611b40565b005b60606012805461064e906133c7565b80601f016020809104026020016040519081016040528092919081815260200182805461067a906133c7565b80156106c75780601f1061069c576101008083540402835291602001916106c7565b820191906000526020600020905b8154815290600101906020018083116106aa57829003601f168201915b5050505050905090565b6000806106dc611bc6565b90506106e9818585611bce565b600191505092915050565b6000601054905090565b60006001805414610744576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073b90613444565b60405180910390fd5b60026001819055506000610756611bc6565b9050610763858285611d97565b600080601660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663640562b1878932878a6040518663ffffffff1660e01b81526004016107c9959493929190613464565b60408051808303816000875af11580156107e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080b9190613502565b915091506000821380156108695750601560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b80156108bf5750601560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b1561097957600061271083836108d59190613571565b6108df91906135e2565b90506000811115610977576000612710600d54836108fd9190613571565b61090791906135e2565b9050600081836109179190613613565b9050600082111561092f5761092e8a600084611e23565b5b6000811115610966576109658a600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683611e23565b5b82846109729190613613565b935050505b505b610984878783611e23565b60019350505050600180819055509392505050565b60006012905090565b6000806109ad611bc6565b90506109ce8185856109bf8589611949565b6109c99190613647565b611bce565b600191505092915050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323a3ad723360046040518363ffffffff1660e01b8152600401610a359291906136f2565b602060405180830381865afa158015610a52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a769190613730565b610ab5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aac906137a9565b60405180910390fd5b6001805414610af9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af090613444565b60405180910390fd5b6002600181905550610b13610b0c611bc6565b8383611e23565b600180819055505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323a3ad723360046040518363ffffffff1660e01b8152600401610b7a9291906136f2565b602060405180830381865afa158015610b97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbb9190613730565b610bfa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf1906137a9565b60405180910390fd5b610c0482826121b8565b5050565b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323a3ad723360036040518363ffffffff1660e01b8152600401610cad9291906136f2565b602060405180830381865afa158015610cca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cee9190613730565b610d2d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d24906137a9565b60405180910390fd5b80601560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b610e466122f7565b610e50600061237e565b565b601660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323a3ad723360046040518363ffffffff1660e01b8152600401610ed49291906136f2565b602060405180830381865afa158015610ef1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f159190613730565b610f54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4b906137a9565b60405180910390fd5b80600d8190555081600e819055505050565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060138054610f9f906133c7565b80601f0160208091040260200160405190810160405280929190818152602001828054610fcb906133c7565b80156110185780601f10610fed57610100808354040283529160200191611018565b820191906000526020600020905b815481529060010190602001808311610ffb57829003601f168201915b5050505050905090565b600061106b600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612444565b9050919050565b60008061107d611bc6565b9050600061108b8286611949565b9050838110156110d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110c790613815565b60405180910390fd5b6110dd8286868403611bce565b60019250505092915050565b6000600180541461112f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112690613444565b60405180910390fd5b60026001819055506000611141611bc6565b9050600080601660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663640562b1878532338a6040518663ffffffff1660e01b81526004016111a9959493929190613464565b60408051808303816000875af11580156111c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111eb9190613502565b915091506000821380156112495750601560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b801561129f5750601560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b1561135957600061271083836112b59190613571565b6112bf91906135e2565b90506000811115611357576000612710600d54836112dd9190613571565b6112e791906135e2565b9050600081836112f79190613613565b9050600082111561130f5761130e86600084611e23565b5b60008111156113465761134586600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683611e23565b5b82846113529190613613565b935050505b505b611364838783611e23565b600193505050506001808190555092915050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323a3ad723360036040518363ffffffff1660e01b81526004016113d49291906136f2565b602060405180830381865afa1580156113f1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114159190613730565b611454576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161144b906137a9565b60405180910390fd5b61145d816124ae565b61149c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611493906138a7565b60405180910390fd5b80601660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6060806000600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561159a57602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff168152602001906004019060208260030104928301926001038202915080841161155d5790505b505050505090506000815167ffffffffffffffff8111156115be576115bd6138c7565b5b6040519080825280602002602001820160405280156115ec5781602001602082028036833780820191505090505b50905060005b82518110156116d057611666838281518110611611576116106138f6565b5b6020026020010151600a60008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206124c190919063ffffffff16565b828281518110611679576116786138f6565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152505080806001019150506115f2565b508181935093505050915091565b6060806000600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561179857602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff168152602001906004019060208260030104928301926001038202915080841161175b5790505b505050505090506000815167ffffffffffffffff8111156117bc576117bb6138c7565b5b6040519080825280602002602001820160405280156117ea5781602001602082028036833780820191505090505b50905060005b82518110156118ce5761186483828151811061180f5761180e6138f6565b5b6020026020010151600960008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206124c190919063ffffffff16565b828281518110611877576118766138f6565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152505080806001019150506117f0565b508181935093505050915091565b6000601560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6000600c54600b546119449190613647565b905090565b6000600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000611a19600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612444565b9050919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323a3ad723360046040518363ffffffff1660e01b8152600401611a7c9291906136f2565b602060405180830381865afa158015611a99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611abd9190613730565b611afc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611af3906137a9565b60405180910390fd5b80600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611b486122f7565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611bba5760006040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401611bb1919061306e565b60405180910390fd5b611bc38161237e565b50565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611c3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c3490613971565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611cac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ca3906139dd565b60405180910390fd5b80600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051611d8a9190612f21565b60405180910390a3505050565b6000611da38484611949565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611e1d5781811015611e0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e0690613a49565b60405180910390fd5b611e1c8484848403611bce565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611e92576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e8990613ab5565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161480611f1857507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b1561203257611f26836124ae565b15611fa95780600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f7a9190613647565b9250508190555080600c6000828254611f939190613647565b92505081905550611fa48382612541565b612023565b80600860003273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611ff89190613647565b9250508190555080600b60008282546120119190613647565b925050819055506120223282612681565b5b61202d83826127c1565b6121b3565b6000600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050818110156120b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120b090613b21565b60405180910390fd5b818103600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516121a99190612f21565b60405180910390a3505b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612227576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161221e90613b8d565b60405180910390fd5b80601060008282546122399190613647565b9250508190555080600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516122eb9190612f21565b60405180910390a35050565b6122ff611bc6565b73ffffffffffffffffffffffffffffffffffffffff1661231d610f66565b73ffffffffffffffffffffffffffffffffffffffff161461237c57612340611bc6565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401612373919061306e565b60405180910390fd5b565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008082600001805490509050600081146124a3576124728360000160018361246d9190613613565b612909565b60000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166124a6565b60005b915050919050565b600080823b905060008111915050919050565b6000808360000180549050905060006124e0856000018560008561291e565b90506000811461253457612503856000016001836124fe9190613613565b612909565b60000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612537565b60005b9250505092915050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600082826125939190613bad565b905060004390506125ed8183600a60008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206129919092919063ffffffff16565b5050600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190806001815401808255809150506001900390600052602060002090600891828204019190066004029091909190916101000a81548163ffffffff021916908363ffffffff1602179055505050505050565b6000600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600082826126d39190613bad565b9050600043905061272d8183600960008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206129919092919063ffffffff16565b5050600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190806001815401808255809150506001900390600052602060002090600891828204019190066004029091909190916101000a81548163ffffffff021916908363ffffffff1602179055505050505050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015612848576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161283f90613c49565b60405180910390fd5b818103600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081601060008282540392505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516128fc9190612f21565b60405180910390a3505050565b60008260005281602060002001905092915050565b60005b8183101561298657600061293584846129ae565b90508463ffffffff166129488783612909565b60000160009054906101000a900463ffffffff1663ffffffff16111561297057809250612980565b60018161297d9190613647565b93505b50612921565b819050949350505050565b6000806129a28560000185856129d4565b91509150935093915050565b600060028284186129bf91906135e2565b8284166129cc9190613647565b905092915050565b6000806000858054905090506000811115612c61576000612a01876001846129fc9190613613565b612909565b6040518060400160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152505090508563ffffffff16816000015163ffffffff161115612aec576040517f2520601d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8563ffffffff16816000015163ffffffff1603612b705784612b1a88600185612b159190613613565b612909565b60000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550612c50565b8660405180604001604052808863ffffffff168152602001877bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b806020015185935093505050612d49565b8560405180604001604052808763ffffffff168152602001867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550505060008492509250505b935093915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612d8b578082015181840152602081019050612d70565b60008484015250505050565b6000601f19601f8301169050919050565b6000612db382612d51565b612dbd8185612d5c565b9350612dcd818560208601612d6d565b612dd681612d97565b840191505092915050565b60006020820190508181036000830152612dfb8184612da8565b905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612e3382612e08565b9050919050565b612e4381612e28565b8114612e4e57600080fd5b50565b600081359050612e6081612e3a565b92915050565b6000819050919050565b612e7981612e66565b8114612e8457600080fd5b50565b600081359050612e9681612e70565b92915050565b60008060408385031215612eb357612eb2612e03565b5b6000612ec185828601612e51565b9250506020612ed285828601612e87565b9150509250929050565b60008115159050919050565b612ef181612edc565b82525050565b6000602082019050612f0c6000830184612ee8565b92915050565b612f1b81612e66565b82525050565b6000602082019050612f366000830184612f12565b92915050565b600080600060608486031215612f5557612f54612e03565b5b6000612f6386828701612e51565b9350506020612f7486828701612e51565b9250506040612f8586828701612e87565b9150509250925092565b600060ff82169050919050565b612fa581612f8f565b82525050565b6000602082019050612fc06000830184612f9c565b92915050565b600060208284031215612fdc57612fdb612e03565b5b6000612fea84828501612e51565b91505092915050565b612ffc81612edc565b811461300757600080fd5b50565b60008135905061301981612ff3565b92915050565b6000806040838503121561303657613035612e03565b5b600061304485828601612e51565b92505060206130558582860161300a565b9150509250929050565b61306881612e28565b82525050565b6000602082019050613083600083018461305f565b92915050565b6000819050919050565b60006130ae6130a96130a484612e08565b613089565b612e08565b9050919050565b60006130c082613093565b9050919050565b60006130d2826130b5565b9050919050565b6130e2816130c7565b82525050565b60006020820190506130fd60008301846130d9565b92915050565b6000806040838503121561311a57613119612e03565b5b600061312885828601612e87565b925050602061313985828601612e87565b9150509250929050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b61317481613143565b82525050565b600060208201905061318f600083018461316b565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600063ffffffff82169050919050565b6131da816131c1565b82525050565b60006131ec83836131d1565b60208301905092915050565b6000602082019050919050565b600061321082613195565b61321a81856131a0565b9350613225836131b1565b8060005b8381101561325657815161323d88826131e0565b9750613248836131f8565b925050600181019050613229565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61329881613143565b82525050565b60006132aa838361328f565b60208301905092915050565b6000602082019050919050565b60006132ce82613263565b6132d8818561326e565b93506132e38361327f565b8060005b838110156133145781516132fb888261329e565b9750613306836132b6565b9250506001810190506132e7565b5085935050505092915050565b6000604082019050818103600083015261333b8185613205565b9050818103602083015261334f81846132c3565b90509392505050565b6000806040838503121561336f5761336e612e03565b5b600061337d85828601612e51565b925050602061338e85828601612e51565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806133df57607f821691505b6020821081036133f2576133f1613398565b5b50919050565b7f5245454e5452414e435900000000000000000000000000000000000000000000600082015250565b600061342e600a83612d5c565b9150613439826133f8565b602082019050919050565b6000602082019050818103600083015261345d81613421565b9050919050565b600060a082019050613479600083018861305f565b613486602083018761305f565b613493604083018661305f565b6134a0606083018561305f565b6134ad6080830184612f12565b9695505050505050565b6000819050919050565b6134ca816134b7565b81146134d557600080fd5b50565b6000815190506134e7816134c1565b92915050565b6000815190506134fc81612e70565b92915050565b6000806040838503121561351957613518612e03565b5b6000613527858286016134d8565b9250506020613538858286016134ed565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061357c82612e66565b915061358783612e66565b925082820261359581612e66565b915082820484148315176135ac576135ab613542565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006135ed82612e66565b91506135f883612e66565b925082613608576136076135b3565b5b828204905092915050565b600061361e82612e66565b915061362983612e66565b925082820390508181111561364157613640613542565b5b92915050565b600061365282612e66565b915061365d83612e66565b925082820190508082111561367557613674613542565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600681106136bb576136ba61367b565b5b50565b60008190506136cc826136aa565b919050565b60006136dc826136be565b9050919050565b6136ec816136d1565b82525050565b6000604082019050613707600083018561305f565b61371460208301846136e3565b9392505050565b60008151905061372a81612ff3565b92915050565b60006020828403121561374657613745612e03565b5b60006137548482850161371b565b91505092915050565b7f4163636573732052657374726963746564000000000000000000000000000000600082015250565b6000613793601183612d5c565b915061379e8261375d565b602082019050919050565b600060208201905081810360008301526137c281613786565b9050919050565b7f44656372656173656420616c6c6f77616e63652062656c6f77207a65726f0000600082015250565b60006137ff601e83612d5c565b915061380a826137c9565b602082019050919050565b6000602082019050818103600083015261382e816137f2565b9050919050565b7f50726f76696465642061646472657373206973206e6f74206120636f6e74726160008201527f6374000000000000000000000000000000000000000000000000000000000000602082015250565b6000613891602283612d5c565b915061389c82613835565b604082019050919050565b600060208201905081810360008301526138c081613884565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f417070726f76652066726f6d207a65726f206164647265737300000000000000600082015250565b600061395b601983612d5c565b915061396682613925565b602082019050919050565b6000602082019050818103600083015261398a8161394e565b9050919050565b7f417070726f766520746f207a65726f2061646472657373000000000000000000600082015250565b60006139c7601783612d5c565b91506139d282613991565b602082019050919050565b600060208201905081810360008301526139f6816139ba565b9050919050565b7f496e73756666696369656e7420616c6c6f77616e636500000000000000000000600082015250565b6000613a33601683612d5c565b9150613a3e826139fd565b602082019050919050565b60006020820190508181036000830152613a6281613a26565b9050919050565b7f5472616e736665722066726f6d207a65726f2061646472657373000000000000600082015250565b6000613a9f601a83612d5c565b9150613aaa82613a69565b602082019050919050565b60006020820190508181036000830152613ace81613a92565b9050919050565b7f5472616e7366657220616d6f756e7420657863656564732062616c616e636500600082015250565b6000613b0b601f83612d5c565b9150613b1682613ad5565b602082019050919050565b60006020820190508181036000830152613b3a81613afe565b9050919050565b7f4d696e7420746f207a65726f2061646472657373000000000000000000000000600082015250565b6000613b77601483612d5c565b9150613b8282613b41565b602082019050919050565b60006020820190508181036000830152613ba681613b6a565b9050919050565b6000613bb882613143565b9150613bc383613143565b925082820190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811115613bf757613bf6613542565b5b92915050565b7f4275726e20616d6f756e7420657863656564732062616c616e63650000000000600082015250565b6000613c33601b83612d5c565b9150613c3e82613bfd565b602082019050919050565b60006020820190508181036000830152613c6281613c26565b905091905056fea2646970667358221220bcd58db043af6115737612c62b8e91eefa677eb705676283a5c41e15bc77dfbb64736f6c634300081a003300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000052b7d2dcc80cd2e4000000000000000000000000000000cb13ca54a9744afa2586e6232b94a58cf9b5e25c0000000000000000000000003246f31ad1b00991965d7a68aef694c4464d89eb00000000000000000000000000000000000000000000000000000000000000145855534420566962726174696c6520417373657400000000000000000000000000000000000000000000000000000000000000000000000000000000000000045855534400000000000000000000000000000000000000000000000000000000

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106101da5760003560e01c80638756201211610104578063be183492116100a2578063dd62ed3e11610071578063dd62ed3e146105a7578063e6993191146105d7578063f0f4426014610607578063f2fde38b14610623576101da565b8063be183492146104f7578063cae5cb5014610528578063cb4ca63114610559578063d89135cd14610589576101da565b80639c53417b116100de5780639c53417b1461044b578063a457c2d71461047b578063a9059cbb146104ab578063a91ee0dc146104db576101da565b806387562012146103f35780638da5cb5b1461040f57806395d89b411461042d576101da565b806340c10f191161017c57806370a082311161014b57806370a082311461037d57806370d5ae05146103ad578063715018a6146103cb5780637b103999146103d5576101da565b806340c10f19146102e55780634274e43d14610301578063493722e5146103315780636fe34e891461034d576101da565b806323b872dd116101b857806323b872dd1461024b578063313ce5671461027b57806339509351146102995780633bf4c874146102c9576101da565b806306fdde03146101df578063095ea7b3146101fd57806318160ddd1461022d575b600080fd5b6101e761063f565b6040516101f49190612de1565b60405180910390f35b61021760048036038101906102129190612e9c565b6106d1565b6040516102249190612ef7565b60405180910390f35b6102356106f4565b6040516102429190612f21565b60405180910390f35b61026560048036038101906102609190612f3c565b6106fe565b6040516102729190612ef7565b60405180910390f35b610283610999565b6040516102909190612fab565b60405180910390f35b6102b360048036038101906102ae9190612e9c565b6109a2565b6040516102c09190612ef7565b60405180910390f35b6102e360048036038101906102de9190612e9c565b6109d9565b005b6102ff60048036038101906102fa9190612e9c565b610b1e565b005b61031b60048036038101906103169190612fc6565b610c08565b6040516103289190612f21565b60405180910390f35b61034b6004803603810190610346919061301f565b610c51565b005b61036760048036038101906103629190612fc6565b610d88565b6040516103749190612f21565b60405180910390f35b61039760048036038101906103929190612fc6565b610dd1565b6040516103a49190612f21565b60405180910390f35b6103b5610e1a565b6040516103c2919061306e565b60405180910390f35b6103d3610e3e565b005b6103dd610e52565b6040516103ea91906130e8565b60405180910390f35b61040d60048036038101906104089190613103565b610e78565b005b610417610f66565b604051610424919061306e565b60405180910390f35b610435610f90565b6040516104429190612de1565b60405180910390f35b61046560048036038101906104609190612fc6565b611022565b604051610472919061317a565b60405180910390f35b61049560048036038101906104909190612e9c565b611072565b6040516104a29190612ef7565b60405180910390f35b6104c560048036038101906104c09190612e9c565b6110e9565b6040516104d29190612ef7565b60405180910390f35b6104f560048036038101906104f09190612fc6565b611378565b005b610511600480360381019061050c9190612fc6565b6114e0565b60405161051f929190613321565b60405180910390f35b610542600480360381019061053d9190612fc6565b6116de565b604051610550929190613321565b60405180910390f35b610573600480360381019061056e9190612fc6565b6118dc565b6040516105809190612ef7565b60405180910390f35b610591611932565b60405161059e9190612f21565b60405180910390f35b6105c160048036038101906105bc9190613358565b611949565b6040516105ce9190612f21565b60405180910390f35b6105f160048036038101906105ec9190612fc6565b6119d0565b6040516105fe919061317a565b60405180910390f35b610621600480360381019061061c9190612fc6565b611a20565b005b61063d60048036038101906106389190612fc6565b611b40565b005b60606012805461064e906133c7565b80601f016020809104026020016040519081016040528092919081815260200182805461067a906133c7565b80156106c75780601f1061069c576101008083540402835291602001916106c7565b820191906000526020600020905b8154815290600101906020018083116106aa57829003601f168201915b5050505050905090565b6000806106dc611bc6565b90506106e9818585611bce565b600191505092915050565b6000601054905090565b60006001805414610744576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073b90613444565b60405180910390fd5b60026001819055506000610756611bc6565b9050610763858285611d97565b600080601660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663640562b1878932878a6040518663ffffffff1660e01b81526004016107c9959493929190613464565b60408051808303816000875af11580156107e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080b9190613502565b915091506000821380156108695750601560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b80156108bf5750601560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b1561097957600061271083836108d59190613571565b6108df91906135e2565b90506000811115610977576000612710600d54836108fd9190613571565b61090791906135e2565b9050600081836109179190613613565b9050600082111561092f5761092e8a600084611e23565b5b6000811115610966576109658a600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683611e23565b5b82846109729190613613565b935050505b505b610984878783611e23565b60019350505050600180819055509392505050565b60006012905090565b6000806109ad611bc6565b90506109ce8185856109bf8589611949565b6109c99190613647565b611bce565b600191505092915050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323a3ad723360046040518363ffffffff1660e01b8152600401610a359291906136f2565b602060405180830381865afa158015610a52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a769190613730565b610ab5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aac906137a9565b60405180910390fd5b6001805414610af9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af090613444565b60405180910390fd5b6002600181905550610b13610b0c611bc6565b8383611e23565b600180819055505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323a3ad723360046040518363ffffffff1660e01b8152600401610b7a9291906136f2565b602060405180830381865afa158015610b97573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbb9190613730565b610bfa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf1906137a9565b60405180910390fd5b610c0482826121b8565b5050565b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323a3ad723360036040518363ffffffff1660e01b8152600401610cad9291906136f2565b602060405180830381865afa158015610cca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cee9190613730565b610d2d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d24906137a9565b60405180910390fd5b80601560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6000600760008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b7f000000000000000000000000000000000000000000000000000000000000036981565b610e466122f7565b610e50600061237e565b565b601660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323a3ad723360046040518363ffffffff1660e01b8152600401610ed49291906136f2565b602060405180830381865afa158015610ef1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f159190613730565b610f54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4b906137a9565b60405180910390fd5b80600d8190555081600e819055505050565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060138054610f9f906133c7565b80601f0160208091040260200160405190810160405280929190818152602001828054610fcb906133c7565b80156110185780601f10610fed57610100808354040283529160200191611018565b820191906000526020600020905b815481529060010190602001808311610ffb57829003601f168201915b5050505050905090565b600061106b600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612444565b9050919050565b60008061107d611bc6565b9050600061108b8286611949565b9050838110156110d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110c790613815565b60405180910390fd5b6110dd8286868403611bce565b60019250505092915050565b6000600180541461112f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112690613444565b60405180910390fd5b60026001819055506000611141611bc6565b9050600080601660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663640562b1878532338a6040518663ffffffff1660e01b81526004016111a9959493929190613464565b60408051808303816000875af11580156111c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111eb9190613502565b915091506000821380156112495750601560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b801561129f5750601560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b1561135957600061271083836112b59190613571565b6112bf91906135e2565b90506000811115611357576000612710600d54836112dd9190613571565b6112e791906135e2565b9050600081836112f79190613613565b9050600082111561130f5761130e86600084611e23565b5b60008111156113465761134586600f60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683611e23565b5b82846113529190613613565b935050505b505b611364838783611e23565b600193505050506001808190555092915050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323a3ad723360036040518363ffffffff1660e01b81526004016113d49291906136f2565b602060405180830381865afa1580156113f1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114159190613730565b611454576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161144b906137a9565b60405180910390fd5b61145d816124ae565b61149c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611493906138a7565b60405180910390fd5b80601660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6060806000600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561159a57602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff168152602001906004019060208260030104928301926001038202915080841161155d5790505b505050505090506000815167ffffffffffffffff8111156115be576115bd6138c7565b5b6040519080825280602002602001820160405280156115ec5781602001602082028036833780820191505090505b50905060005b82518110156116d057611666838281518110611611576116106138f6565b5b6020026020010151600a60008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206124c190919063ffffffff16565b828281518110611679576116786138f6565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152505080806001019150506115f2565b508181935093505050915091565b6060806000600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561179857602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff168152602001906004019060208260030104928301926001038202915080841161175b5790505b505050505090506000815167ffffffffffffffff8111156117bc576117bb6138c7565b5b6040519080825280602002602001820160405280156117ea5781602001602082028036833780820191505090505b50905060005b82518110156118ce5761186483828151811061180f5761180e6138f6565b5b6020026020010151600960008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206124c190919063ffffffff16565b828281518110611877576118766138f6565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152505080806001019150506117f0565b508181935093505050915091565b6000601560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6000600c54600b546119449190613647565b905090565b6000600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000611a19600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612444565b9050919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323a3ad723360046040518363ffffffff1660e01b8152600401611a7c9291906136f2565b602060405180830381865afa158015611a99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611abd9190613730565b611afc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611af3906137a9565b60405180910390fd5b80600f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611b486122f7565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611bba5760006040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401611bb1919061306e565b60405180910390fd5b611bc38161237e565b50565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611c3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c3490613971565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611cac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ca3906139dd565b60405180910390fd5b80600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051611d8a9190612f21565b60405180910390a3505050565b6000611da38484611949565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611e1d5781811015611e0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e0690613a49565b60405180910390fd5b611e1c8484848403611bce565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611e92576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e8990613ab5565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161480611f1857507f000000000000000000000000000000000000000000000000000000000000036973ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b1561203257611f26836124ae565b15611fa95780600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f7a9190613647565b9250508190555080600c6000828254611f939190613647565b92505081905550611fa48382612541565b612023565b80600860003273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611ff89190613647565b9250508190555080600b60008282546120119190613647565b925050819055506120223282612681565b5b61202d83826127c1565b6121b3565b6000600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050818110156120b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120b090613b21565b60405180910390fd5b818103600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516121a99190612f21565b60405180910390a3505b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612227576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161221e90613b8d565b60405180910390fd5b80601060008282546122399190613647565b9250508190555080600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516122eb9190612f21565b60405180910390a35050565b6122ff611bc6565b73ffffffffffffffffffffffffffffffffffffffff1661231d610f66565b73ffffffffffffffffffffffffffffffffffffffff161461237c57612340611bc6565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401612373919061306e565b60405180910390fd5b565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008082600001805490509050600081146124a3576124728360000160018361246d9190613613565b612909565b60000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166124a6565b60005b915050919050565b600080823b905060008111915050919050565b6000808360000180549050905060006124e0856000018560008561291e565b90506000811461253457612503856000016001836124fe9190613613565b612909565b60000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612537565b60005b9250505092915050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600082826125939190613bad565b905060004390506125ed8183600a60008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206129919092919063ffffffff16565b5050600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190806001815401808255809150506001900390600052602060002090600891828204019190066004029091909190916101000a81548163ffffffff021916908363ffffffff1602179055505050505050565b6000600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600082826126d39190613bad565b9050600043905061272d8183600960008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206129919092919063ffffffff16565b5050600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190806001815401808255809150506001900390600052602060002090600891828204019190066004029091909190916101000a81548163ffffffff021916908363ffffffff1602179055505050505050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015612848576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161283f90613c49565b60405180910390fd5b818103600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081601060008282540392505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516128fc9190612f21565b60405180910390a3505050565b60008260005281602060002001905092915050565b60005b8183101561298657600061293584846129ae565b90508463ffffffff166129488783612909565b60000160009054906101000a900463ffffffff1663ffffffff16111561297057809250612980565b60018161297d9190613647565b93505b50612921565b819050949350505050565b6000806129a28560000185856129d4565b91509150935093915050565b600060028284186129bf91906135e2565b8284166129cc9190613647565b905092915050565b6000806000858054905090506000811115612c61576000612a01876001846129fc9190613613565b612909565b6040518060400160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152505090508563ffffffff16816000015163ffffffff161115612aec576040517f2520601d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8563ffffffff16816000015163ffffffff1603612b705784612b1a88600185612b159190613613565b612909565b60000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550612c50565b8660405180604001604052808863ffffffff168152602001877bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b806020015185935093505050612d49565b8560405180604001604052808763ffffffff168152602001867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550505060008492509250505b935093915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612d8b578082015181840152602081019050612d70565b60008484015250505050565b6000601f19601f8301169050919050565b6000612db382612d51565b612dbd8185612d5c565b9350612dcd818560208601612d6d565b612dd681612d97565b840191505092915050565b60006020820190508181036000830152612dfb8184612da8565b905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612e3382612e08565b9050919050565b612e4381612e28565b8114612e4e57600080fd5b50565b600081359050612e6081612e3a565b92915050565b6000819050919050565b612e7981612e66565b8114612e8457600080fd5b50565b600081359050612e9681612e70565b92915050565b60008060408385031215612eb357612eb2612e03565b5b6000612ec185828601612e51565b9250506020612ed285828601612e87565b9150509250929050565b60008115159050919050565b612ef181612edc565b82525050565b6000602082019050612f0c6000830184612ee8565b92915050565b612f1b81612e66565b82525050565b6000602082019050612f366000830184612f12565b92915050565b600080600060608486031215612f5557612f54612e03565b5b6000612f6386828701612e51565b9350506020612f7486828701612e51565b9250506040612f8586828701612e87565b9150509250925092565b600060ff82169050919050565b612fa581612f8f565b82525050565b6000602082019050612fc06000830184612f9c565b92915050565b600060208284031215612fdc57612fdb612e03565b5b6000612fea84828501612e51565b91505092915050565b612ffc81612edc565b811461300757600080fd5b50565b60008135905061301981612ff3565b92915050565b6000806040838503121561303657613035612e03565b5b600061304485828601612e51565b92505060206130558582860161300a565b9150509250929050565b61306881612e28565b82525050565b6000602082019050613083600083018461305f565b92915050565b6000819050919050565b60006130ae6130a96130a484612e08565b613089565b612e08565b9050919050565b60006130c082613093565b9050919050565b60006130d2826130b5565b9050919050565b6130e2816130c7565b82525050565b60006020820190506130fd60008301846130d9565b92915050565b6000806040838503121561311a57613119612e03565b5b600061312885828601612e87565b925050602061313985828601612e87565b9150509250929050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b61317481613143565b82525050565b600060208201905061318f600083018461316b565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600063ffffffff82169050919050565b6131da816131c1565b82525050565b60006131ec83836131d1565b60208301905092915050565b6000602082019050919050565b600061321082613195565b61321a81856131a0565b9350613225836131b1565b8060005b8381101561325657815161323d88826131e0565b9750613248836131f8565b925050600181019050613229565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61329881613143565b82525050565b60006132aa838361328f565b60208301905092915050565b6000602082019050919050565b60006132ce82613263565b6132d8818561326e565b93506132e38361327f565b8060005b838110156133145781516132fb888261329e565b9750613306836132b6565b9250506001810190506132e7565b5085935050505092915050565b6000604082019050818103600083015261333b8185613205565b9050818103602083015261334f81846132c3565b90509392505050565b6000806040838503121561336f5761336e612e03565b5b600061337d85828601612e51565b925050602061338e85828601612e51565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806133df57607f821691505b6020821081036133f2576133f1613398565b5b50919050565b7f5245454e5452414e435900000000000000000000000000000000000000000000600082015250565b600061342e600a83612d5c565b9150613439826133f8565b602082019050919050565b6000602082019050818103600083015261345d81613421565b9050919050565b600060a082019050613479600083018861305f565b613486602083018761305f565b613493604083018661305f565b6134a0606083018561305f565b6134ad6080830184612f12565b9695505050505050565b6000819050919050565b6134ca816134b7565b81146134d557600080fd5b50565b6000815190506134e7816134c1565b92915050565b6000815190506134fc81612e70565b92915050565b6000806040838503121561351957613518612e03565b5b6000613527858286016134d8565b9250506020613538858286016134ed565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061357c82612e66565b915061358783612e66565b925082820261359581612e66565b915082820484148315176135ac576135ab613542565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006135ed82612e66565b91506135f883612e66565b925082613608576136076135b3565b5b828204905092915050565b600061361e82612e66565b915061362983612e66565b925082820390508181111561364157613640613542565b5b92915050565b600061365282612e66565b915061365d83612e66565b925082820190508082111561367557613674613542565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600681106136bb576136ba61367b565b5b50565b60008190506136cc826136aa565b919050565b60006136dc826136be565b9050919050565b6136ec816136d1565b82525050565b6000604082019050613707600083018561305f565b61371460208301846136e3565b9392505050565b60008151905061372a81612ff3565b92915050565b60006020828403121561374657613745612e03565b5b60006137548482850161371b565b91505092915050565b7f4163636573732052657374726963746564000000000000000000000000000000600082015250565b6000613793601183612d5c565b915061379e8261375d565b602082019050919050565b600060208201905081810360008301526137c281613786565b9050919050565b7f44656372656173656420616c6c6f77616e63652062656c6f77207a65726f0000600082015250565b60006137ff601e83612d5c565b915061380a826137c9565b602082019050919050565b6000602082019050818103600083015261382e816137f2565b9050919050565b7f50726f76696465642061646472657373206973206e6f74206120636f6e74726160008201527f6374000000000000000000000000000000000000000000000000000000000000602082015250565b6000613891602283612d5c565b915061389c82613835565b604082019050919050565b600060208201905081810360008301526138c081613884565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f417070726f76652066726f6d207a65726f206164647265737300000000000000600082015250565b600061395b601983612d5c565b915061396682613925565b602082019050919050565b6000602082019050818103600083015261398a8161394e565b9050919050565b7f417070726f766520746f207a65726f2061646472657373000000000000000000600082015250565b60006139c7601783612d5c565b91506139d282613991565b602082019050919050565b600060208201905081810360008301526139f6816139ba565b9050919050565b7f496e73756666696369656e7420616c6c6f77616e636500000000000000000000600082015250565b6000613a33601683612d5c565b9150613a3e826139fd565b602082019050919050565b60006020820190508181036000830152613a6281613a26565b9050919050565b7f5472616e736665722066726f6d207a65726f2061646472657373000000000000600082015250565b6000613a9f601a83612d5c565b9150613aaa82613a69565b602082019050919050565b60006020820190508181036000830152613ace81613a92565b9050919050565b7f5472616e7366657220616d6f756e7420657863656564732062616c616e636500600082015250565b6000613b0b601f83612d5c565b9150613b1682613ad5565b602082019050919050565b60006020820190508181036000830152613b3a81613afe565b9050919050565b7f4d696e7420746f207a65726f2061646472657373000000000000000000000000600082015250565b6000613b77601483612d5c565b9150613b8282613b41565b602082019050919050565b60006020820190508181036000830152613ba681613b6a565b9050919050565b6000613bb882613143565b9150613bc383613143565b925082820190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811115613bf757613bf6613542565b5b92915050565b7f4275726e20616d6f756e7420657863656564732062616c616e63650000000000600082015250565b6000613c33601b83612d5c565b9150613c3e82613bfd565b602082019050919050565b60006020820190508181036000830152613c6281613c26565b905091905056fea2646970667358221220bcd58db043af6115737612c62b8e91eefa677eb705676283a5c41e15bc77dfbb64736f6c634300081a0033