Contract 0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea21

Txn Hash Method
Block
From
To
Value [Txn Fee]
0x664b0bac55a2230a11ed587dbb08b4c49b055f28a00d612367d3705c864f8b34Withdraw RFLSH281027902023-03-30 18:34:006 hrs 6 mins ago0x3aac2d9672cd0e080bf5e770fef9d2fc4e237865 IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.006640006858 27.2816825
0x3825d61c82749a6f13da34b896bce6e60be650c54f9c6f50f62b032e06012dc3Withdraw RFLSH280951232023-03-30 14:17:1910 hrs 23 mins ago0x410c26f2614ae78ddda5d140e7a95ac4aa343629 IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.0024386095 26.5
0x73effa6184425216e055d1ea718bca7cd5cc3f5e5c0cf61bd7fa0a7eab387499Withdraw RFLSH280940362023-03-30 13:41:0910 hrs 59 mins ago0xa50ff6ad20adc10998e33f52b63d71f26c34874a IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.00484602679 29.563365
0x3a40f608bf913bc4428c338dcbb8d03926253a1b05be9cf17915255ee87db1d8Withdraw RFLSH280907232023-03-30 11:49:0212 hrs 51 mins ago0xee650f5599bd48f27b29b254a4c45322a755c6b4 IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.012165938 26.5
0x35788369d0e0090e67d7c13bffabc62c16335128c422fb4c2057bae98a6aa29dWithdraw RFLSH280851602023-03-30 8:41:1615 hrs 59 mins ago0xa97d767f49a9939aa07d16ae38a7d8f55584f5d4 IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.0023383335 26.5
0xed1f3b3146c557b4907329d87dfd69ebe12e44c24af253b4f283fd103e56ab40Approve280721462023-03-30 1:21:0523 hrs 19 mins ago0xe958db62b7ecd202c0880bd5248cdda3ce0255c4 IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.001246772 26.5
0x8d71133fb4f50ed869fcca01f5ed6bc8f9cdb3c3f9b0dd27e87157d350c48e7aWithdraw RFLSH280636412023-03-29 20:32:211 day 4 hrs ago0x043237c314d2ad73358389ac6654c7f78121d184 IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.003341175 25
0x5ab68fa1c30ad442f2a437416b0f687674532ce69d6d67d35cb0d67ed97dec11Withdraw RFLSH280611792023-03-29 19:09:151 day 5 hrs ago0xf3db2ebdb1a0b779ca82b2c7d69db2757443f58f IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.0029399895 26.5
0x7223b429fd8b01d326aef33f50dc9807030f9c35c7ed8f2e78c5984392f8472bWithdraw RFLSH280609722023-03-29 19:02:211 day 5 hrs ago0xa97d767f49a9939aa07d16ae38a7d8f55584f5d4 IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.0030402655 26.5
0x8125275c076e7e1a6e590f0e91434743bce71f8497b5dd9704ce4e45baa71eecWithdraw RFLSH280516272023-03-29 13:41:361 day 10 hrs ago0x6ec6875f2e9958f64df8f05d123dcfa3abdf3bb8 IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.0038425 26.5
0x2144b4a94dfc68bc1b137d03c77d0b96f09c0dba579e53e4c37a5df5bd5a9737Withdraw RFLSH280467802023-03-29 10:54:371 day 13 hrs ago0x4f13f1bdd91f8dd693eb0c0cdcd6da69c14ac617 IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.0037421975 26.5
0x979ff7b3a9d5ffbe9a9b8cb7e52ea50c22e5b7f32e89c917664e65a17edbb480Approve280450872023-03-29 9:56:281 day 14 hrs ago0x8250f597b4afcd1aace5fcdb7694b353218af5d2 IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.00124158692 26.41
0x2f67fd0291a470f36dfdf4d00ac0cb2568275707516860f23785b2cf0588b9ffWithdraw RFLSH280305672023-03-29 1:31:441 day 23 hrs ago0xf523120d8310c004ab35654dc08bb9b4b2f83361 IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.0031405415 26.5
0xc41903166a8f620cb10088185d59560634de454c60b178074f6f122fc67db738Withdraw RFLSH280190052023-03-28 18:51:022 days 5 hrs ago0x5641881027cb278e46f63ca9cd5ce579e7c5dfea IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.0029399895 26.5
0x48af4db68760bbf41993683aab9fffda108a9542109302304ef88c3e519f5846Withdraw RFLSH280187112023-03-28 18:41:342 days 5 hrs ago0x85e6cc88f3055b589eb1d4030863be2cfcc0763e IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.006958446 31
0x64aae86a0aec6093ccc6646b04ce81d6e380504517af1d7a685cee04713dcbf1Withdraw RFLSH280132942023-03-28 15:33:302 days 9 hrs ago0x3f885599d634451abfd91ccef5bd9872c6385e8c IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.011965386 26.5
0xd840f5eb028a1ac266681ac88f5a501ed7c10d92c9e809545b5f6bdaeaff70cdApprove280104862023-03-28 13:56:282 days 10 hrs ago0x206815261f480a98498a7f7554356ff3d7fb303f IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.0012455 26.5
0x85c6815f1a3fd7161a4dbdf2c205235e8b06a9c22aa1e0b244435ac08d85554aApprove280094022023-03-28 13:19:102 days 11 hrs ago0x9dc7a4a68eeb093d7fe08b7793ff8569db421b59 IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.001246454 26.5
0xedb5a492312a365fa718984b9c750a2ca390ff6c67b7bb7ce3c0ed0d5d5de80fWithdraw RFLSH280090772023-03-28 13:07:592 days 11 hrs ago0x9dc7a4a68eeb093d7fe08b7793ff8569db421b59 IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.0023383335 26.5
0xf07b5a7bf517f06dcabe19b660a8ae108facc92fd82f3ef4b9df9f3a38e2fabbWithdraw RFLSH280088992023-03-28 13:01:472 days 11 hrs ago0x9dc7a4a68eeb093d7fe08b7793ff8569db421b59 IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.0133210995 26.5
0xfc0ba17df0afbe19482952f83b137928a89a6e646504d253befbe14ee1aa707aWithdraw RFLSH279919742023-03-28 3:26:432 days 21 hrs ago0x325409632bccffac706d378a2eca57cafa21ab11 IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.007069376346 26.95067
0xd2360a2e6f460556cfa946a9b5463ab880e9f9727fae4e5e62420d2089e03e6aWithdraw RFLSH279908682023-03-28 2:47:372 days 21 hrs ago0x256f20440f1978bc6c1d4c97b4c5311f186e2a33 IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.003084068268 26.8818
0xd3556f89cbbe43f0095c68819ee980951ec1445df2bb58cbd68cf3ad9e1e0458Withdraw RFLSH279904812023-03-28 2:34:122 days 22 hrs ago0xc2493150727198a001fcb1a5f35fb477d506959d IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.0035416455 26.5
0x03243fc7782b046b7dc58fee8fb57d663576c1b3c05043ff0e0d35fad5d172b5Withdraw RFLSH279817952023-03-27 21:33:513 days 3 hrs ago0xc2787ec3f1bbd5a0bd1423850e94c9446b48e2d0 IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.004043052 26.5
0xed8ade7a5224eed30514fa14d414d709328ac01437eec7c1bb0eba6e407263fdApprove279781132023-03-27 19:27:543 days 5 hrs ago0xd042ca73589241a25585823b3f34b42936e61462 IN  0x19ebbcf77a62cb6df9c23c4a7abb6920a72bea210 AVAX0.0012899623 27.425
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Flesh

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 14 : Flesh.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/utils/math/Math.sol";

import "./RottingSpeed.sol";

// rFLSH interface
interface IRottenFlesh is IERC20 {
    function mint(address to, uint256 amount) external;
}

/// @custom:security-contact [email protected]
contract Flesh is ERC20, ERC20Burnable, Pausable, AccessControl {
    event WithdrewRottenFlesh(
        uint256 timestamp,
        address sender,
        uint256 amount
    );

    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant FREEZER_ROLE = keccak256("FREEZER_ROLE");

    /**
     @notice Above this number of days, FLSH won't rot anymore.
     User will have to unstake then stake again to continue to earn rewards.
     */
    uint256 public maxRottenPeriod = 180;

    IRottenFlesh private _rottenFlesh;
    RottingSpeed private _rottingSpeed;

    bool public areTransfersEnabled;

    uint256 public rottingInterval = 1 days;

    mapping(address => uint256) private _timers;

    mapping(address => bool) private _wlAddresses;

    /* ********************************** */
    /*            Constructor             */
    /* ********************************** */

    constructor(address rottenFlesh, address rottingSpeed)
        ERC20("Flesh", "FLSH")
    {
        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _grantRole(MINTER_ROLE, msg.sender);
        _grantRole(FREEZER_ROLE, msg.sender);

        _rottenFlesh = IRottenFlesh(rottenFlesh);
        _rottingSpeed = RottingSpeed(rottingSpeed);
    }

    /* ********************************** */
    /*             Modifiers              */
    /* ********************************** */

    modifier onlyWLAddress(address to) {
        if (!areTransfersEnabled) {
            require(
                _wlAddresses[msg.sender] || _wlAddresses[to],
                "FLSH: from address and to address aren't allowed to transfer"
            );
        }
        _;
    }

    /* ********************************** */
    /*               Mint                 */
    /* ********************************** */

    function mint(address to, uint256 amount)
        public
        onlyRole(MINTER_ROLE)
        whenNotPaused
    {
        uint256 _rottenFleshToWithdraw = rottenFleshToWithdraw(to);
        if (_rottenFleshToWithdraw > 0) {
            _withdrawRFLSH(to, _rottenFleshToWithdraw);
        }
        _mint(to, amount);
    }

    function _mint(address account, uint256 amount) internal virtual override {
        if (!hasRole(FREEZER_ROLE, account)) {
            if (super.balanceOf(account) == 0 || _timers[account] == 0) {
                _timers[account] = block.timestamp;
            }
        }

        super._mint(account, amount);
    }

    function withdrawRFLSH() external whenNotPaused {
        uint256 _rottenFleshToWithdraw = rottenFleshToWithdraw(msg.sender);

        require(_rottenFleshToWithdraw > 0, "No rFLSH to withdraw");

        _withdrawRFLSH(msg.sender, _rottenFleshToWithdraw);

        emit WithdrewRottenFlesh(
            block.timestamp,
            msg.sender,
            _rottenFleshToWithdraw
        );
    }

    /// @notice Mints the amount of rFLSH a user is eligible to.
    /// This method also refreshes user's true FLSH balance
    function _withdrawRFLSH(address account, uint256 _rottenFleshToWithdraw)
        internal
    {
        super._burn(account, _rottenFleshToWithdraw);
        _rottenFlesh.mint(account, _rottenFleshToWithdraw);

        if (
            !hasRole(FREEZER_ROLE, account) &&
            // equivalent of balanceOf(account) in this case
            // but super.balanceOf(account) method is more efficient
            super.balanceOf(account) > 0
        ) {
            _timers[account] = block.timestamp;
        } else {
            _timers[account] = 0;
        }
    }

    /* ********************************** */
    /*               Burn                 */
    /* ********************************** */

    function burn(uint256 amount) public override whenNotPaused {
        require(
            balanceOf(msg.sender) >= amount,
            "FLSH: burn amount exceeds balance"
        );

        uint256 _rottenFleshToWithdraw = rottenFleshToWithdraw(msg.sender);
        if (_rottenFleshToWithdraw > 0) {
            _withdrawRFLSH(msg.sender, _rottenFleshToWithdraw);
        }

        // Reset rotting timer if balance comes to 0
        if (super.balanceOf(msg.sender) == amount) {
            _timers[msg.sender] = 0;
        }

        super._burn(msg.sender, amount);
    }

    function burnSelf(uint256 amount) external onlyRole(DEFAULT_ADMIN_ROLE) {
        super._burn(address(this), amount);
    }

    /* ********************************** */
    /*              Transfer              */
    /* ********************************** */

    function transfer(address to, uint256 amount)
        public
        virtual
        override
        onlyWLAddress(to)
        whenNotPaused
        returns (bool)
    {
        _transfer(msg.sender, to, amount);
        return true;
    }

    /// @notice Transfers an amount FLSH from an address to another
    /// @dev It inherits the ERC20 default `_transfer` method.
    /// @param from address transfering the FLSH
    /// @param to address receiving the FLSH
    /// @param amount amount of FLSH transfering
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override onlyWLAddress(to) whenNotPaused {
        require(
            balanceOf(from) >= amount,
            "FLSH: transfer amount exceeds balance"
        );

        uint256 _rottenFleshToWithdrawFrom = rottenFleshToWithdraw(from);
        if (_rottenFleshToWithdrawFrom > 0) {
            _withdrawRFLSH(from, _rottenFleshToWithdrawFrom);
        }
        // Reset rotting timer of `from` if balance comes to 0
        if (!hasRole(FREEZER_ROLE, from)) {
            if (super.balanceOf(from) == amount) {
                _timers[from] = 0;
            }
        }

        uint256 _rottenFleshToWithdrawTo = rottenFleshToWithdraw(to);
        if (_rottenFleshToWithdrawTo > 0) {
            _withdrawRFLSH(to, _rottenFleshToWithdrawTo);
        }
        // Update rotting timer of `to` if balance was 0
        if (!hasRole(FREEZER_ROLE, to)) {
            if (super.balanceOf(to) == 0) {
                _timers[to] = block.timestamp;
            }
        }

        super._transfer(from, to, amount);
    }

    function withdraw() external onlyRole(DEFAULT_ADMIN_ROLE) {
        require(address(this).balance > 0, "Nothing to withdraw");
        payable(msg.sender).transfer(address(this).balance);
    }

    /* ********************************** */
    /*              Getters               */
    /* ********************************** */

    /// @notice Returns the amount of not rotten FLSH a user has based on the time it takes for FLSH to rotten
    /// @dev this methods overrides the ERC20 default one to fake the amount of the token a user has
    /// This is a read method, therefore the real amount in the contract doesn't change here
    /// @param account the wallet address of a user
    /// @return balance the amount of fresh FLSH (not rotten) an account has
    function balanceOf(address account)
        public
        view
        virtual
        override
        returns (uint256 balance)
    {
        balance = super.balanceOf(account);

        if (!hasRole(FREEZER_ROLE, account)) {
            if (_timers[account] > 0) {
                // Elapsed time for a given account and a given interval
                uint256 secondsTimeElapsed = Math.max(
                    0,
                    Math.min(
                        maxRottenPeriod * 1 days,
                        block.timestamp - _timers[account]
                    )
                );
                uint256 timeElapsed = secondsTimeElapsed / rottingInterval;

                for (uint256 i = 0; i < timeElapsed; i++) {
                    balance *= uint256(
                        _percentageDenominator() -
                            _rottingSpeed.totalRottingForAccount(account)
                    );
                    balance /= uint256(_percentageDenominator());

                    // We consider that below 0.01, your FLSH amount will be as much as zero
                    if (balance < 10000000000000000) {
                        balance = 0;
                        break;
                    }
                }

                uint256 currentDayBalance = balance *
                    (secondsTimeElapsed % rottingInterval);
                currentDayBalance *= _rottingSpeed.totalRottingForAccount(
                    account
                );
                currentDayBalance /= uint256(_percentageDenominator());
                currentDayBalance /= rottingInterval;
                balance -= currentDayBalance;
            }
        }
    }

    /// @notice Returns the amount rotten flesh available to withdraw
    /// @param account the wallet address of a user
    /// @return balance the amount of rotten flesh an account can withdraw
    function rottenFleshToWithdraw(address account)
        public
        view
        returns (uint256 balance)
    {
        balance = super.balanceOf(account) - balanceOf(account);
    }

    /// @dev The denominator with which to interpret ratios as percentages.
    /// Defaults to 10000 so ratios are expressed in basis points, but may be customized by an override.
    function _percentageDenominator() internal pure virtual returns (uint96) {
        return 10000;
    }

    /// @notice Checks whether an address is allow to transfer FLSH to/from another address or not
    /// @param _address the address we want to check
    /// @return bool true if `_address` is whitelisted for transfers, false otherwise
    function isWhitelistedForTransfers(address _address)
        external
        view
        returns (bool)
    {
        return _wlAddresses[_address];
    }

    /* ********************************** */
    /*              Setters               */
    /* ********************************** */

    function setAreTransfersEnabled(bool _areTransfersEnabled)
        external
        onlyRole(DEFAULT_ADMIN_ROLE)
    {
        areTransfersEnabled = _areTransfersEnabled;
    }

    function addWLAddress(address[] calldata addresses)
        external
        onlyRole(DEFAULT_ADMIN_ROLE)
    {
        for (uint256 i = 0; i < addresses.length; i++) {
            _wlAddresses[addresses[i]] = true;
        }
    }

    function removeWLAddress(address[] calldata addresses)
        external
        onlyRole(DEFAULT_ADMIN_ROLE)
    {
        for (uint256 i = 0; i < addresses.length; i++) {
            _wlAddresses[addresses[i]] = false;
        }
    }

    function setRottingInterval(uint256 _rottingInterval)
        external
        onlyRole(DEFAULT_ADMIN_ROLE)
    {
        rottingInterval = _rottingInterval;
    }

    function setRottenFleshContract(address rottenFlesh)
        external
        onlyRole(DEFAULT_ADMIN_ROLE)
    {
        _rottenFlesh = IRottenFlesh(rottenFlesh);
    }

    function setRottingSpeedContract(address rottingSpeed)
        external
        onlyRole(DEFAULT_ADMIN_ROLE)
    {
        _rottingSpeed = RottingSpeed(rottingSpeed);
    }

    function setMaxRottenPeriod(uint256 _maxRottenPeriod)
        external
        onlyRole(DEFAULT_ADMIN_ROLE)
    {
        maxRottenPeriod = _maxRottenPeriod;
    }

    /* ********************************** */
    /*               Pauser               */
    /* ********************************** */

    function pause() public onlyRole(DEFAULT_ADMIN_ROLE) {
        _pause();
    }

    function unpause() public onlyRole(DEFAULT_ADMIN_ROLE) {
        _unpause();
    }
}

File 2 of 14 : RottingSpeed.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/utils/math/Math.sol";

/// @custom:security-contact [email protected]
contract RottingSpeed is AccessControl {
    event EarnedRottingSpeedBonus(
        uint256 timestamp,
        address sender,
        uint96 rottingSpeedBonus,
        uint256 rottingSpeedEndBonus
    );

    uint96 public constant MIN_ROTTEN_SPEED = 100;
    // Max 3 different rottingSpeed bonuses with different end timestamps
    uint256 public constant MAX_ROTTEN_BONUSES = 3;

    bytes32 public constant ROTTEN_ROLE = keccak256("ROTTEN_ROLE");

    struct RottingSpeedExpiration {
        uint96 rottingSpeed;
        uint256 endTimestamp;
    }

    mapping(address => RottingSpeedExpiration[MAX_ROTTEN_BONUSES])
        public rottingSpeedForAccount;

    /* ********************************** */
    /*            Constructor             */
    /* ********************************** */

    constructor() {
        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _grantRole(ROTTEN_ROLE, msg.sender);
    }

    /* ********************************** */
    /*              Getters               */
    /* ********************************** */

    function totalRottingForAccount(address account)
        public
        view
        returns (uint96 rottingSpeed)
    {
        rottingSpeed = MIN_ROTTEN_SPEED;
        for (uint256 i = 0; i < MAX_ROTTEN_BONUSES; i++) {
            if (
                rottingSpeedForAccount[account][i].endTimestamp >
                block.timestamp
            ) {
                rottingSpeed += rottingSpeedForAccount[account][i].rottingSpeed;
            }
        }
        return rottingSpeed;
    }

    /* ********************************** */
    /*              Setters               */
    /* ********************************** */

    function setRottingSpeedExpiration(
        RottingSpeedExpiration memory _rottingSpeed,
        address account
    ) public onlyRole(ROTTEN_ROLE) {
        uint256 i = 0;
        while (i < MAX_ROTTEN_BONUSES) {
            if (
                rottingSpeedForAccount[account][i].endTimestamp <
                block.timestamp ||
                rottingSpeedForAccount[account][i].endTimestamp == 0
            ) {
                rottingSpeedForAccount[account][i] = _rottingSpeed;
                emit EarnedRottingSpeedBonus(
                    block.timestamp,
                    msg.sender,
                    _rottingSpeed.rottingSpeed,
                    _rottingSpeed.endTimestamp
                );
                return;
            }
            i += 1;
        }

        require(
            i < MAX_ROTTEN_BONUSES,
            "RottingSpeed: can't add a rottingSpeed bonus, already full"
        );
    }

    function overrideRottingSpeedExpirations(
        RottingSpeedExpiration[3] memory _rottingSpeeds,
        address account
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        for (uint256 i = 0; i < _rottingSpeeds.length; i++) {
            rottingSpeedForAccount[account][i] = _rottingSpeeds[i];
        }
    }
}

File 3 of 14 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @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 up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a / b + (a % b == 0 ? 0 : 1);
    }
}

File 4 of 14 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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

File 5 of 14 : ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

File 6 of 14 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

File 7 of 14 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

File 8 of 14 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";

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

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

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

File 9 of 14 : ERC20Burnable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)

pragma solidity ^0.8.0;

import "../ERC20.sol";
import "../../../utils/Context.sol";

/**
 * @dev Extension of {ERC20} that allows token holders to destroy both their own
 * tokens and those that they have an allowance for, in a way that can be
 * recognized off-chain (via event analysis).
 */
abstract contract ERC20Burnable is Context, ERC20 {
    /**
     * @dev Destroys `amount` tokens from the caller.
     *
     * See {ERC20-_burn}.
     */
    function burn(uint256 amount) public virtual {
        _burn(_msgSender(), amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, deducting from the caller's
     * allowance.
     *
     * See {ERC20-_burn} and {ERC20-allowance}.
     *
     * Requirements:
     *
     * - the caller must have allowance for ``accounts``'s tokens of at least
     * `amount`.
     */
    function burnFrom(address account, uint256 amount) public virtual {
        _spendAllowance(account, _msgSender(), amount);
        _burn(account, amount);
    }
}

File 10 of 14 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @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 amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

File 11 of 14 : ERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;

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

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

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

        return true;
    }

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

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _balances[to] += amount;

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

File 12 of 14 : Pausable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

File 13 of 14 : IAccessControl.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

File 14 of 14 : AccessControl.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (access/AccessControl.sol)

pragma solidity ^0.8.0;

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

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

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

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

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

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

    /**
     * @dev Revert with a standard message if `_msgSender()` is missing `role`.
     * Overriding this function changes the behavior of the {onlyRole} modifier.
     *
     * Format of the revert message is described in {_checkRole}.
     *
     * _Available since v4.6._
     */
    function _checkRole(bytes32 role) internal view virtual {
        _checkRole(role, _msgSender());
    }

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

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

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

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

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

        _revokeRole(role, account);
    }

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

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

    /**
     * @dev Grants `role` to `account`.
     *
     * Internal function without access restriction.
     */
    function _grantRole(bytes32 role, address account) internal virtual {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * Internal function without access restriction.
     */
    function _revokeRole(bytes32 role, address account) internal virtual {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}

Settings
{
  "remappings": [],
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "evmVersion": "london",
  "libraries": {},
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"rottenFlesh","type":"address"},{"internalType":"address","name":"rottingSpeed","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrewRottenFlesh","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FREEZER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"}],"name":"addWLAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"areTransfersEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnSelf","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"isWhitelistedForTransfers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxRottenPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"}],"name":"removeWLAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"rottenFleshToWithdraw","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rottingInterval","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_areTransfersEnabled","type":"bool"}],"name":"setAreTransfersEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxRottenPeriod","type":"uint256"}],"name":"setMaxRottenPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"rottenFlesh","type":"address"}],"name":"setRottenFleshContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rottingInterval","type":"uint256"}],"name":"setRottingInterval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"rottingSpeed","type":"address"}],"name":"setRottingSpeedContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawRFLSH","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405260b460075562015180600a553480156200001d57600080fd5b50604051620047be380380620047be8339818101604052810190620000439190620003c2565b6040518060400160405280600581526020017f466c6573680000000000000000000000000000000000000000000000000000008152506040518060400160405280600481526020017f464c5348000000000000000000000000000000000000000000000000000000008152508160039081620000c0919062000683565b508060049081620000d2919062000683565b5050506000600560006101000a81548160ff021916908315150217905550620001056000801b33620001f360201b60201c565b620001377f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633620001f360201b60201c565b620001697f92de27771f92d6942691d73358b3a4673e4880de8356f8f2cf452be87e02d36333620001f360201b60201c565b81600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050506200076a565b620002058282620002e560201b60201c565b620002e15760016006600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550620002866200035060201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b60006006600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600033905090565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200038a826200035d565b9050919050565b6200039c816200037d565b8114620003a857600080fd5b50565b600081519050620003bc8162000391565b92915050565b60008060408385031215620003dc57620003db62000358565b5b6000620003ec85828601620003ab565b9250506020620003ff85828601620003ab565b9150509250929050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200048b57607f821691505b602082108103620004a157620004a062000443565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026200050b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620004cc565b620005178683620004cc565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620005646200055e62000558846200052f565b62000539565b6200052f565b9050919050565b6000819050919050565b620005808362000543565b620005986200058f826200056b565b848454620004d9565b825550505050565b600090565b620005af620005a0565b620005bc81848462000575565b505050565b5b81811015620005e457620005d8600082620005a5565b600181019050620005c2565b5050565b601f8211156200063357620005fd81620004a7565b6200060884620004bc565b8101602085101562000618578190505b620006306200062785620004bc565b830182620005c1565b50505b505050565b600082821c905092915050565b6000620006586000198460080262000638565b1980831691505092915050565b600062000673838362000645565b9150826002028217905092915050565b6200068e8262000409565b67ffffffffffffffff811115620006aa57620006a962000414565b5b620006b6825462000472565b620006c3828285620005e8565b600060209050601f831160018114620006fb5760008415620006e6578287015190505b620006f2858262000665565b86555062000762565b601f1984166200070b86620004a7565b60005b8281101562000735578489015182556001820191506020850194506020810190506200070e565b8683101562000755578489015162000751601f89168262000645565b8355505b6001600288020188555050505b505050505050565b614044806200077a6000396000f3fe608060405234801561001057600080fd5b50600436106102535760003560e01c80634db3bd5f11610146578063a9059cbb116100c3578063d547741f11610087578063d547741f146106d4578063d9e18069146106f0578063dd62ed3e1461070e578063e18b0a181461073e578063ebaee6761461075a578063f3811fe01461077657610253565b8063a9059cbb1461061e578063ad3823611461064e578063b8b12a1e1461067e578063b982b5a11461069a578063d5391393146106b657610253565b80638456cb591161010a5780638456cb591461057857806391d148541461058257806395d89b41146105b2578063a217fddf146105d0578063a457c2d7146105ee57610253565b80634db3bd5f146104d45780635c975abb146104f057806362a06ccc1461050e57806370a082311461052c57806379cc67901461055c57610253565b80632f2ff15d116101d45780633ccfd60b116101985780633ccfd60b1461046c5780633f4ba83a1461047657806340c10f191461048057806341f411ee1461049c57806342966c68146104b857610253565b80632f2ff15d146103c8578063313ce567146103e457806336568abe14610402578063379ef1951461041e578063395093511461043c57610253565b80630c24ade71161021b5780630c24ade7146102fe57806318160ddd1461032e57806323b872dd1461034c578063248a9ca31461037c57806328e0bda7146103ac57610253565b806301ffc9a7146102585780630360fcd91461028857806306a85f0f1461029257806306fdde03146102b0578063095ea7b3146102ce575b600080fd5b610272600480360381019061026d9190612c51565b610792565b60405161027f9190612c99565b60405180910390f35b61029061080c565b005b61029a6108ec565b6040516102a79190612ccd565b60405180910390f35b6102b8610910565b6040516102c59190612d78565b60405180910390f35b6102e860048036038101906102e39190612e2e565b6109a2565b6040516102f59190612c99565b60405180910390f35b61031860048036038101906103139190612e6e565b6109c5565b6040516103259190612c99565b60405180910390f35b610336610a1b565b6040516103439190612eaa565b60405180910390f35b61036660048036038101906103619190612ec5565b610a25565b6040516103739190612c99565b60405180910390f35b61039660048036038101906103919190612f44565b610a54565b6040516103a39190612ccd565b60405180910390f35b6103c660048036038101906103c19190612f71565b610a74565b005b6103e260048036038101906103dd9190612f9e565b610a8c565b005b6103ec610aad565b6040516103f99190612ffa565b60405180910390f35b61041c60048036038101906104179190612f9e565b610ab6565b005b610426610b39565b6040516104339190612c99565b60405180910390f35b61045660048036038101906104519190612e2e565b610b4c565b6040516104639190612c99565b60405180910390f35b610474610b83565b005b61047e610c1d565b005b61049a60048036038101906104959190612e2e565b610c35565b005b6104b660048036038101906104b19190612e6e565b610cd8565b005b6104d260048036038101906104cd9190612f71565b610d2a565b005b6104ee60048036038101906104e99190613041565b610e41565b005b6104f8610e6c565b6040516105059190612c99565b60405180910390f35b610516610e83565b6040516105239190612eaa565b60405180910390f35b61054660048036038101906105419190612e6e565b610e89565b6040516105539190612eaa565b60405180910390f35b61057660048036038101906105719190612e2e565b6111d2565b005b6105806111f2565b005b61059c60048036038101906105979190612f9e565b61120a565b6040516105a99190612c99565b60405180910390f35b6105ba611275565b6040516105c79190612d78565b60405180910390f35b6105d8611307565b6040516105e59190612ccd565b60405180910390f35b61060860048036038101906106039190612e2e565b61130e565b6040516106159190612c99565b60405180910390f35b61063860048036038101906106339190612e2e565b611385565b6040516106459190612c99565b60405180910390f35b61066860048036038101906106639190612e6e565b6114db565b6040516106759190612eaa565b60405180910390f35b61069860048036038101906106939190612f71565b611500565b005b6106b460048036038101906106af9190612f71565b61151b565b005b6106be611533565b6040516106cb9190612ccd565b60405180910390f35b6106ee60048036038101906106e99190612f9e565b611557565b005b6106f8611578565b6040516107059190612eaa565b60405180910390f35b6107286004803603810190610723919061306e565b61157e565b6040516107359190612eaa565b60405180910390f35b61075860048036038101906107539190613113565b611605565b005b610774600480360381019061076f9190612e6e565b6116b8565b005b610790600480360381019061078b9190613113565b61170a565b005b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806108055750610804826117bd565b5b9050919050565b610814610e6c565b15610854576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161084b906131ac565b60405180910390fd5b600061085f336114db565b9050600081116108a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161089b90613218565b60405180910390fd5b6108ae3382611827565b7fe9cad759ddf30738edbe19eafa8326efe249c5b5a3cc1fd421ac75b7c26f1a924233836040516108e193929190613247565b60405180910390a150565b7f92de27771f92d6942691d73358b3a4673e4880de8356f8f2cf452be87e02d36381565b60606003805461091f906132ad565b80601f016020809104026020016040519081016040528092919081815260200182805461094b906132ad565b80156109985780601f1061096d57610100808354040283529160200191610998565b820191906000526020600020905b81548152906001019060200180831161097b57829003601f168201915b5050505050905090565b6000806109ad611997565b90506109ba81858561199f565b600191505092915050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6000600254905090565b600080610a30611997565b9050610a3d858285611b68565b610a48858585611bf4565b60019150509392505050565b600060066000838152602001908152602001600020600101549050919050565b6000801b610a8181611eda565b816007819055505050565b610a9582610a54565b610a9e81611eda565b610aa88383611eee565b505050565b60006012905090565b610abe611997565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b2290613350565b60405180910390fd5b610b358282611fcf565b5050565b600960149054906101000a900460ff1681565b600080610b57611997565b9050610b78818585610b69858961157e565b610b73919061339f565b61199f565b600191505092915050565b6000801b610b9081611eda565b60004711610bd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bca9061341f565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015610c19573d6000803e3d6000fd5b5050565b6000801b610c2a81611eda565b610c326120b1565b50565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610c5f81611eda565b610c67610e6c565b15610ca7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c9e906131ac565b60405180910390fd5b6000610cb2846114db565b90506000811115610cc857610cc78482611827565b5b610cd28484612153565b50505050565b6000801b610ce581611eda565b81600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b610d32610e6c565b15610d72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d69906131ac565b60405180910390fd5b80610d7c33610e89565b1015610dbd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db4906134b1565b60405180910390fd5b6000610dc8336114db565b90506000811115610dde57610ddd3382611827565b5b81610de833612230565b03610e33576000600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b610e3d3383612278565b5050565b6000801b610e4e81611eda565b81600960146101000a81548160ff0219169083151502179055505050565b6000600560009054906101000a900460ff16905090565b600a5481565b6000610e9482612230565b9050610ec07f92de27771f92d6942691d73358b3a4673e4880de8356f8f2cf452be87e02d3638361120a565b6111cd576000600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205411156111cc576000610f7c6000610f7762015180600754610f2791906134d1565b600b60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205442610f729190613513565b61244e565b612467565b90506000600a5482610f8e9190613576565b905060005b818110156110b257600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637f376c50866040518263ffffffff1660e01b8152600401610ff691906135a7565b602060405180830381865afa158015611013573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110379190613606565b61103f612481565b6110499190613633565b6bffffffffffffffffffffffff168461106291906134d1565b935061106c612481565b6bffffffffffffffffffffffff16846110859190613576565b9350662386f26fc1000084101561109f57600093506110b2565b80806110aa90613673565b915050610f93565b506000600a54836110c391906136bb565b846110ce91906134d1565b9050600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637f376c50866040518263ffffffff1660e01b815260040161112b91906135a7565b602060405180830381865afa158015611148573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116c9190613606565b6bffffffffffffffffffffffff168161118591906134d1565b905061118f612481565b6bffffffffffffffffffffffff16816111a89190613576565b9050600a54816111b89190613576565b905080846111c69190613513565b93505050505b5b919050565b6111e4826111de611997565b83611b68565b6111ee8282612278565b5050565b6000801b6111ff81611eda565b61120761248b565b50565b60006006600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060048054611284906132ad565b80601f01602080910402602001604051908101604052809291908181526020018280546112b0906132ad565b80156112fd5780601f106112d2576101008083540402835291602001916112fd565b820191906000526020600020905b8154815290600101906020018083116112e057829003601f168201915b5050505050905090565b6000801b81565b600080611319611997565b90506000611327828661157e565b90508381101561136c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113639061375e565b60405180910390fd5b611379828686840361199f565b60019250505092915050565b600082600960149054906101000a900460ff1661147d57600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff168061143d5750600c60008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b61147c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611473906137f0565b60405180910390fd5b5b611485610e6c565b156114c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114bc906131ac565b60405180910390fd5b6114d0338585611bf4565b600191505092915050565b60006114e682610e89565b6114ef83612230565b6114f99190613513565b9050919050565b6000801b61150d81611eda565b6115173083612278565b5050565b6000801b61152881611eda565b81600a819055505050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b61156082610a54565b61156981611eda565b6115738383611fcf565b505050565b60075481565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000801b61161281611eda565b60005b838390508110156116b2576001600c600086868581811061163957611638613810565b5b905060200201602081019061164e9190612e6e565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555080806116aa90613673565b915050611615565b50505050565b6000801b6116c581611eda565b81600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000801b61171781611eda565b60005b838390508110156117b7576000600c600086868581811061173e5761173d613810565b5b90506020020160208101906117539190612e6e565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555080806117af90613673565b91505061171a565b50505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6118318282612278565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1983836040518363ffffffff1660e01b815260040161188e92919061383f565b600060405180830381600087803b1580156118a857600080fd5b505af11580156118bc573d6000803e3d6000fd5b505050506118ea7f92de27771f92d6942691d73358b3a4673e4880de8356f8f2cf452be87e02d3638361120a565b1580156118ff575060006118fd83612230565b115b1561194d5742600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611993565b6000600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b5050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611a0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a05906138da565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611a7d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a749061396c565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051611b5b9190612eaa565b60405180910390a3505050565b6000611b74848461157e565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611bee5781811015611be0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bd7906139d8565b60405180910390fd5b611bed848484840361199f565b5b50505050565b81600960149054906101000a900460ff16611cea57600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1680611caa5750600c60008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b611ce9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce0906137f0565b60405180910390fd5b5b611cf2610e6c565b15611d32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d29906131ac565b60405180910390fd5b81611d3c85610e89565b1015611d7d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7490613a6a565b60405180910390fd5b6000611d88856114db565b90506000811115611d9e57611d9d8582611827565b5b611dc87f92de27771f92d6942691d73358b3a4673e4880de8356f8f2cf452be87e02d3638661120a565b611e225782611dd686612230565b03611e21576000600b60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b5b6000611e2d856114db565b90506000811115611e4357611e428582611827565b5b611e6d7f92de27771f92d6942691d73358b3a4673e4880de8356f8f2cf452be87e02d3638661120a565b611ec7576000611e7c86612230565b03611ec65742600b60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b5b611ed286868661252e565b505050505050565b611eeb81611ee6611997565b6127ad565b50565b611ef8828261120a565b611fcb5760016006600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611f70611997565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b611fd9828261120a565b156120ad5760006006600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550612052611997565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b6120b9610e6c565b6120f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120ef90613ad6565b60405180910390fd5b6000600560006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61213c611997565b60405161214991906135a7565b60405180910390a1565b61217d7f92de27771f92d6942691d73358b3a4673e4880de8356f8f2cf452be87e02d3638361120a565b61222257600061218c83612230565b14806121d757506000600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054145b156122215742600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b5b61222c828261284a565b5050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036122e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122de90613b68565b60405180910390fd5b6122f3826000836129a9565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015612379576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161237090613bfa565b60405180910390fd5b8181036000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600260008282546123d09190613513565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516124359190612eaa565b60405180910390a3612449836000846129ae565b505050565b600081831061245d578161245f565b825b905092915050565b6000818310156124775781612479565b825b905092915050565b6000612710905090565b612493610e6c565b156124d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124ca906131ac565b60405180910390fd5b6001600560006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612517611997565b60405161252491906135a7565b60405180910390a1565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361259d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161259490613c8c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361260c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161260390613d1e565b60405180910390fd5b6126178383836129a9565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561269d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161269490613db0565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612730919061339f565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516127949190612eaa565b60405180910390a36127a78484846129ae565b50505050565b6127b7828261120a565b612846576127dc8173ffffffffffffffffffffffffffffffffffffffff1660146129b3565b6127ea8360001c60206129b3565b6040516020016127fb929190613ea4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161283d9190612d78565b60405180910390fd5b5050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036128b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128b090613f2a565b60405180910390fd5b6128c5600083836129a9565b80600260008282546128d7919061339f565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461292c919061339f565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516129919190612eaa565b60405180910390a36129a5600083836129ae565b5050565b505050565b505050565b6060600060028360026129c691906134d1565b6129d0919061339f565b67ffffffffffffffff8111156129e9576129e8613f4a565b5b6040519080825280601f01601f191660200182016040528015612a1b5781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612a5357612a52613810565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612ab757612ab6613810565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002612af791906134d1565b612b01919061339f565b90505b6001811115612ba1577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110612b4357612b42613810565b5b1a60f81b828281518110612b5a57612b59613810565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c945080612b9a90613f79565b9050612b04565b5060008414612be5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bdc90613fee565b60405180910390fd5b8091505092915050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612c2e81612bf9565b8114612c3957600080fd5b50565b600081359050612c4b81612c25565b92915050565b600060208284031215612c6757612c66612bef565b5b6000612c7584828501612c3c565b91505092915050565b60008115159050919050565b612c9381612c7e565b82525050565b6000602082019050612cae6000830184612c8a565b92915050565b6000819050919050565b612cc781612cb4565b82525050565b6000602082019050612ce26000830184612cbe565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612d22578082015181840152602081019050612d07565b60008484015250505050565b6000601f19601f8301169050919050565b6000612d4a82612ce8565b612d548185612cf3565b9350612d64818560208601612d04565b612d6d81612d2e565b840191505092915050565b60006020820190508181036000830152612d928184612d3f565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612dc582612d9a565b9050919050565b612dd581612dba565b8114612de057600080fd5b50565b600081359050612df281612dcc565b92915050565b6000819050919050565b612e0b81612df8565b8114612e1657600080fd5b50565b600081359050612e2881612e02565b92915050565b60008060408385031215612e4557612e44612bef565b5b6000612e5385828601612de3565b9250506020612e6485828601612e19565b9150509250929050565b600060208284031215612e8457612e83612bef565b5b6000612e9284828501612de3565b91505092915050565b612ea481612df8565b82525050565b6000602082019050612ebf6000830184612e9b565b92915050565b600080600060608486031215612ede57612edd612bef565b5b6000612eec86828701612de3565b9350506020612efd86828701612de3565b9250506040612f0e86828701612e19565b9150509250925092565b612f2181612cb4565b8114612f2c57600080fd5b50565b600081359050612f3e81612f18565b92915050565b600060208284031215612f5a57612f59612bef565b5b6000612f6884828501612f2f565b91505092915050565b600060208284031215612f8757612f86612bef565b5b6000612f9584828501612e19565b91505092915050565b60008060408385031215612fb557612fb4612bef565b5b6000612fc385828601612f2f565b9250506020612fd485828601612de3565b9150509250929050565b600060ff82169050919050565b612ff481612fde565b82525050565b600060208201905061300f6000830184612feb565b92915050565b61301e81612c7e565b811461302957600080fd5b50565b60008135905061303b81613015565b92915050565b60006020828403121561305757613056612bef565b5b60006130658482850161302c565b91505092915050565b6000806040838503121561308557613084612bef565b5b600061309385828601612de3565b92505060206130a485828601612de3565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f8401126130d3576130d26130ae565b5b8235905067ffffffffffffffff8111156130f0576130ef6130b3565b5b60208301915083602082028301111561310c5761310b6130b8565b5b9250929050565b6000806020838503121561312a57613129612bef565b5b600083013567ffffffffffffffff81111561314857613147612bf4565b5b613154858286016130bd565b92509250509250929050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b6000613196601083612cf3565b91506131a182613160565b602082019050919050565b600060208201905081810360008301526131c581613189565b9050919050565b7f4e6f2072464c534820746f207769746864726177000000000000000000000000600082015250565b6000613202601483612cf3565b915061320d826131cc565b602082019050919050565b60006020820190508181036000830152613231816131f5565b9050919050565b61324181612dba565b82525050565b600060608201905061325c6000830186612e9b565b6132696020830185613238565b6132766040830184612e9b565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806132c557607f821691505b6020821081036132d8576132d761327e565b5b50919050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b600061333a602f83612cf3565b9150613345826132de565b604082019050919050565b600060208201905081810360008301526133698161332d565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006133aa82612df8565b91506133b583612df8565b92508282019050808211156133cd576133cc613370565b5b92915050565b7f4e6f7468696e6720746f20776974686472617700000000000000000000000000600082015250565b6000613409601383612cf3565b9150613414826133d3565b602082019050919050565b60006020820190508181036000830152613438816133fc565b9050919050565b7f464c53483a206275726e20616d6f756e7420657863656564732062616c616e6360008201527f6500000000000000000000000000000000000000000000000000000000000000602082015250565b600061349b602183612cf3565b91506134a68261343f565b604082019050919050565b600060208201905081810360008301526134ca8161348e565b9050919050565b60006134dc82612df8565b91506134e783612df8565b92508282026134f581612df8565b9150828204841483151761350c5761350b613370565b5b5092915050565b600061351e82612df8565b915061352983612df8565b925082820390508181111561354157613540613370565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061358182612df8565b915061358c83612df8565b92508261359c5761359b613547565b5b828204905092915050565b60006020820190506135bc6000830184613238565b92915050565b60006bffffffffffffffffffffffff82169050919050565b6135e3816135c2565b81146135ee57600080fd5b50565b600081519050613600816135da565b92915050565b60006020828403121561361c5761361b612bef565b5b600061362a848285016135f1565b91505092915050565b600061363e826135c2565b9150613649836135c2565b925082820390506bffffffffffffffffffffffff81111561366d5761366c613370565b5b92915050565b600061367e82612df8565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036136b0576136af613370565b5b600182019050919050565b60006136c682612df8565b91506136d183612df8565b9250826136e1576136e0613547565b5b828206905092915050565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b6000613748602583612cf3565b9150613753826136ec565b604082019050919050565b600060208201905081810360008301526137778161373b565b9050919050565b7f464c53483a2066726f6d206164647265737320616e6420746f2061646472657360008201527f73206172656e277420616c6c6f77656420746f207472616e7366657200000000602082015250565b60006137da603c83612cf3565b91506137e58261377e565b604082019050919050565b60006020820190508181036000830152613809816137cd565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006040820190506138546000830185613238565b6138616020830184612e9b565b9392505050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006138c4602483612cf3565b91506138cf82613868565b604082019050919050565b600060208201905081810360008301526138f3816138b7565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b6000613956602283612cf3565b9150613961826138fa565b604082019050919050565b6000602082019050818103600083015261398581613949565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b60006139c2601d83612cf3565b91506139cd8261398c565b602082019050919050565b600060208201905081810360008301526139f1816139b5565b9050919050565b7f464c53483a207472616e7366657220616d6f756e74206578636565647320626160008201527f6c616e6365000000000000000000000000000000000000000000000000000000602082015250565b6000613a54602583612cf3565b9150613a5f826139f8565b604082019050919050565b60006020820190508181036000830152613a8381613a47565b9050919050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b6000613ac0601483612cf3565b9150613acb82613a8a565b602082019050919050565b60006020820190508181036000830152613aef81613ab3565b9050919050565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b6000613b52602183612cf3565b9150613b5d82613af6565b604082019050919050565b60006020820190508181036000830152613b8181613b45565b9050919050565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b6000613be4602283612cf3565b9150613bef82613b88565b604082019050919050565b60006020820190508181036000830152613c1381613bd7565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b6000613c76602583612cf3565b9150613c8182613c1a565b604082019050919050565b60006020820190508181036000830152613ca581613c69565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b6000613d08602383612cf3565b9150613d1382613cac565b604082019050919050565b60006020820190508181036000830152613d3781613cfb565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b6000613d9a602683612cf3565b9150613da582613d3e565b604082019050919050565b60006020820190508181036000830152613dc981613d8d565b9050919050565b600081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b6000613e11601783613dd0565b9150613e1c82613ddb565b601782019050919050565b6000613e3282612ce8565b613e3c8185613dd0565b9350613e4c818560208601612d04565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b6000613e8e601183613dd0565b9150613e9982613e58565b601182019050919050565b6000613eaf82613e04565b9150613ebb8285613e27565b9150613ec682613e81565b9150613ed28284613e27565b91508190509392505050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6000613f14601f83612cf3565b9150613f1f82613ede565b602082019050919050565b60006020820190508181036000830152613f4381613f07565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000613f8482612df8565b915060008203613f9757613f96613370565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b6000613fd8602083612cf3565b9150613fe382613fa2565b602082019050919050565b6000602082019050818103600083015261400781613fcb565b905091905056fea2646970667358221220ef97e1a58994dcec0d828399e2647d3d75d99dcc8a51d95c19a1c33d3ad137ef64736f6c6343000811003300000000000000000000000090a491ea34699daae943346c5e97611bb58c3a75000000000000000000000000acabbb66d4ac47220e7ba14203728ab4437c435e

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

00000000000000000000000090a491ea34699daae943346c5e97611bb58c3a75000000000000000000000000acabbb66d4ac47220e7ba14203728ab4437c435e

-----Decoded View---------------
Arg [0] : rottenFlesh (address): 0x90a491ea34699daae943346c5e97611bb58c3a75
Arg [1] : rottingSpeed (address): 0xacabbb66d4ac47220e7ba14203728ab4437c435e

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000090a491ea34699daae943346c5e97611bb58c3a75
Arg [1] : 000000000000000000000000acabbb66d4ac47220e7ba14203728ab4437c435e


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.