false
false
0

Contract Address Details

0x8577D2D50827bCE2EC1dc9Cf9F1199826781D5AF

Contract Name
Supply
Creator
0x4598a6–d10d29 at 0x198b2c–dcbdb6
Balance
0 FLR
Tokens
Fetching tokens...
Transactions
15 Transactions
Transfers
0 Transfers
Gas Used
2,491,892
Last Balance Update
22911653
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
Supply




Optimization enabled
true
Compiler version
v0.7.6+commit.7338295f




Optimization runs
200
Verified at
2022-07-13T21:13:34.401918Z

Constructor Arguments

0000000000000000000000004598a6c05910ab914f0cbaaca1911cd337d10d29000000000000000000000000baf89d873d198ff78e72d2745b01cba3c6e5be6b0000000000000000000000000000000000000001431e0fae6d7217caa00000000000000000000000000000000000000000000000dbb8481a7362102da000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000

Arg [0] (address) : 0x4598a6c05910ab914f0cbaaca1911cd337d10d29
Arg [1] (address) : 0xbaf89d873d198ff78e72d2745b01cba3c6e5be6b
Arg [2] (uint256) : 100000000000000000000000000000
Arg [3] (uint256) : 68000000000000000000000000000
Arg [4] (address[]) : []

              

./contracts/inflation/implementation/Supply.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;

import "../interface/IISupply.sol";
import "../../tokenPools/interface/IITokenPool.sol";
import "../../token/lib/CheckPointHistory.sol";
import "../../token/lib/CheckPointHistoryCache.sol";
import "../../governance/implementation/Governed.sol";
import "../../addressUpdater/implementation/AddressUpdatable.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";


/**
 * @title Supply contract
 * @notice This contract maintains and computes various native token supply totals.
 **/

contract Supply is IISupply, Governed, AddressUpdatable {
    using CheckPointHistory for CheckPointHistory.CheckPointHistoryState;
    using CheckPointHistoryCache for CheckPointHistoryCache.CacheState;
    using SafeMath for uint256;

    address payable private constant BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD;
    
    struct SupplyData {
        IITokenPool tokenPool;
        uint256 totalLockedWei;
        uint256 totalInflationAuthorizedWei;
        uint256 totalClaimedWei;
    }

    string internal constant ERR_INFLATION_ONLY = "inflation only";
    string internal constant ERR_TOKEN_POOL_ALREADY_ADDED = "token pool already added";
    string internal constant ERR_INITIAL_GENESIS_AMOUNT_ZERO = "initial genesis amount zero";

    CheckPointHistory.CheckPointHistoryState private circulatingSupplyWei;
    CheckPointHistoryCache.CacheState private circulatingSupplyWeiCache;

    uint256 immutable public initialGenesisAmountWei;
    uint256 immutable public totalExcludedSupplyWei; // Foundation supply, distribution treasury, team escrow
    uint256 public distributedExcludedSupplyWei;
    uint256 public totalLockedWei; // Amounts temporary locked and not considered in the inflatable supply
    uint256 public totalInflationAuthorizedWei;
    uint256 public totalClaimedWei;

    SupplyData[] public tokenPools;

    address public inflation;

    // balance of burn address at last check - needed for updating circulating supply
    uint256 private burnAddressBalance;

    // events
    event AuthorizedInflationUpdateError(uint256 actual, uint256 expected);

    modifier onlyInflation {
        require(msg.sender == inflation, ERR_INFLATION_ONLY);
        _;
    }

    constructor(
        address _governance,
        address _addressUpdater,
        uint256 _initialGenesisAmountWei,
        uint256 _totalExcludedSupplyWei,
        IITokenPool[] memory _tokenPools
    )
        Governed(_governance) AddressUpdatable(_addressUpdater)
    {
        require(_initialGenesisAmountWei > 0, ERR_INITIAL_GENESIS_AMOUNT_ZERO);
        initialGenesisAmountWei = _initialGenesisAmountWei;
        totalExcludedSupplyWei = _totalExcludedSupplyWei;

        _increaseCirculatingSupply(_initialGenesisAmountWei.sub(_totalExcludedSupplyWei));

        for (uint256 i = 0; i < _tokenPools.length; i++) {
            _addTokenPool(_tokenPools[i]);
        }

        _updateCirculatingSupply(BURN_ADDRESS);
    }

    /**
     * @notice Updates circulating supply
     * @dev Also updates the burn address amount
    */
    function updateCirculatingSupply() external override onlyInflation {
        _updateCirculatingSupply(BURN_ADDRESS);
    }

    /**
     * @notice Updates authorized inflation and circulating supply - emits event if error
     * @param _inflationAuthorizedWei               Authorized inflation
     * @dev Also updates the burn address amount
    */
    function updateAuthorizedInflationAndCirculatingSupply(
            uint256 _inflationAuthorizedWei
    )
        external override
        onlyInflation 
    {
        // Save old total inflation authorized value to compare with after update.
        uint256 oldTotalInflationAuthorizedWei = totalInflationAuthorizedWei;
        
        _updateCirculatingSupply(BURN_ADDRESS);
        
        // Check if new authorized inflation was distributed and updated correctly.
        if (totalInflationAuthorizedWei != oldTotalInflationAuthorizedWei.add(_inflationAuthorizedWei)) {
            emit AuthorizedInflationUpdateError(totalInflationAuthorizedWei - oldTotalInflationAuthorizedWei,
                _inflationAuthorizedWei);
        }
    }

    /**
     * @notice Adds token pool so it can call updateTokenPoolDistributedAmount method when 
        some tokens are distributed
     * @param _tokenPool                            Token pool address
     * @param _increaseDistributedSupplyByAmountWei If token pool was given initial supply from excluded supply, 
        increase distributed value by this amount
     */
    function addTokenPool(
        IITokenPool _tokenPool,
        uint256 _increaseDistributedSupplyByAmountWei
    )
        external
        onlyGovernance
    {
        _increaseDistributedSupply(_increaseDistributedSupplyByAmountWei);
        _addTokenPool(_tokenPool);
        _updateCirculatingSupply(BURN_ADDRESS);
    }

    /**
     * @notice Increase distributed supply when excluded funds are released to a token pool or team members
     * @param _amountWei                            Amount to increase by
     */
    function increaseDistributedSupply(uint256 _amountWei) external onlyGovernance {
        _increaseDistributedSupply(_amountWei);
        _updateCirculatingSupply(BURN_ADDRESS);
    }

    /**
     * @notice Descrease distributed supply if excluded funds are no longer locked to a token pool
     * @param _amountWei                            Amount to decrease by
     */
    function decreaseDistributedSupply(uint256 _amountWei) external onlyGovernance {
        distributedExcludedSupplyWei = distributedExcludedSupplyWei.sub(_amountWei);
        _decreaseCirculatingSupply(_amountWei);
        _updateCirculatingSupply(BURN_ADDRESS);
    }
    
    /**
     * @notice Get approximate circulating supply for given block number from cache - only past block
     * @param _blockNumber                          Block number
     * @return _circulatingSupplyWei Return approximate circulating supply for last known block <= _blockNumber
    */
    function getCirculatingSupplyAtCached(
        uint256 _blockNumber
    )
        external override 
        returns(uint256 _circulatingSupplyWei)
    {
        // use cache only for the past (the value will never change)
        require(_blockNumber < block.number, "Can only be used for past blocks");
        (_circulatingSupplyWei,) = circulatingSupplyWeiCache.valueAt(circulatingSupplyWei, _blockNumber);
    }
    
    /**
     * @notice Get approximate circulating supply for given block number
     * @param _blockNumber                          Block number
     * @return _circulatingSupplyWei Return approximate circulating supply for last known block <= _blockNumber
    */
    function getCirculatingSupplyAt(
        uint256 _blockNumber
    )
        external view override 
        returns(uint256 _circulatingSupplyWei)
    {
        return circulatingSupplyWei.valueAt(_blockNumber);
    }

    /**
     * @notice Get total inflatable balance (initial genesis amount + total claimed - total excluded/locked amount)
     * @return _inflatableBalanceWei Return inflatable balance
    */
    function getInflatableBalance() external view override returns(uint256 _inflatableBalanceWei) {
        return initialGenesisAmountWei
            .add(totalClaimedWei)
            .sub(totalExcludedSupplyWei.sub(distributedExcludedSupplyWei))
            .sub(totalLockedWei);
    }

    /**
     * Return the burn address (a constant).
     */
    function burnAddress() external pure returns (address payable) {
        return BURN_ADDRESS;
    }

    /**
     * @notice Implementation of the AddressUpdatable abstract method.
     */
    function _updateContractAddresses(
        bytes32[] memory _contractNameHashes,
        address[] memory _contractAddresses
    )
        internal override
    {
        inflation = _getContractAddress(_contractNameHashes, _contractAddresses, "Inflation");
    }

    function _increaseCirculatingSupply(uint256 _increaseBy) internal {
        circulatingSupplyWei.writeValue(circulatingSupplyWei.valueAtNow().add(_increaseBy));
    }

    function _decreaseCirculatingSupply(uint256 _descreaseBy) internal {
        circulatingSupplyWei.writeValue(circulatingSupplyWei.valueAtNow().sub(_descreaseBy));
    }

    function _updateCirculatingSupply(address _burnAddress) internal {
        uint256 len = tokenPools.length;
        for (uint256 i = 0; i < len; i++) {
            SupplyData storage data = tokenPools[i];

            uint256 newTotalLockedWei;
            uint256 newTotalInflationAuthorizedWei;
            uint256 newTotalClaimedWei;
            
            (newTotalLockedWei, newTotalInflationAuthorizedWei, newTotalClaimedWei) = 
                data.tokenPool.getTokenPoolSupplyData();
            assert(newTotalLockedWei.add(newTotalInflationAuthorizedWei) >= newTotalClaimedWei);
            
            // updates total inflation authorized with daily authorized inflation
            uint256 dailyInflationAuthorizedWei = newTotalInflationAuthorizedWei.sub(data.totalInflationAuthorizedWei);
            totalInflationAuthorizedWei = totalInflationAuthorizedWei.add(dailyInflationAuthorizedWei);

            // updates circulating supply
            uint256 claimChange = newTotalClaimedWei.sub(data.totalClaimedWei);
            _increaseCirculatingSupply(claimChange);
            totalClaimedWei = totalClaimedWei.add(claimChange);
            if (newTotalLockedWei >= data.totalLockedWei) {
                uint256 lockChange = newTotalLockedWei - data.totalLockedWei;
                _decreaseCirculatingSupply(lockChange);
                totalLockedWei = totalLockedWei.add(lockChange);
            } else {
                // if founds are unlocked, they are returned to excluded amount
                uint256 lockChange = data.totalLockedWei - newTotalLockedWei;
                distributedExcludedSupplyWei = distributedExcludedSupplyWei.sub(lockChange);
                totalLockedWei = totalLockedWei.sub(lockChange);
            }

            // update data
            data.totalLockedWei = newTotalLockedWei;
            data.totalInflationAuthorizedWei = newTotalInflationAuthorizedWei;
            data.totalClaimedWei = newTotalClaimedWei;
        }

        _updateBurnAddressAmount(_burnAddress);
    }

    function _updateBurnAddressAmount(address _burnAddress) internal {
        uint256 newBalance = _burnAddress.balance;
        _decreaseCirculatingSupply(newBalance.sub(burnAddressBalance));
        burnAddressBalance = newBalance;
    }

    function _addTokenPool(IITokenPool _tokenPool) internal {
        uint256 len = tokenPools.length;
        for (uint256 i = 0; i < len; i++) {
            if (_tokenPool == tokenPools[i].tokenPool) {
                revert(ERR_TOKEN_POOL_ALREADY_ADDED);
            }
        }
        tokenPools.push();
        tokenPools[len].tokenPool = _tokenPool;
    }
    
    function _increaseDistributedSupply(uint256 _amountWei) internal {
        assert(totalExcludedSupplyWei.sub(distributedExcludedSupplyWei) >= _amountWei);
        _increaseCirculatingSupply(_amountWei);
        distributedExcludedSupplyWei = distributedExcludedSupplyWei.add(_amountWei);
    }
}
        

./contracts/addressUpdater/implementation/AddressUpdatable.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;

import "../interface/IIAddressUpdatable.sol";


abstract contract AddressUpdatable is IIAddressUpdatable {

    // https://docs.soliditylang.org/en/v0.8.7/contracts.html#constant-and-immutable-state-variables
    // No storage slot is allocated
    bytes32 internal constant ADDRESS_STORAGE_POSITION = 
        keccak256("flare.diamond.AddressUpdatable.ADDRESS_STORAGE_POSITION");

    modifier onlyAddressUpdater() {
        require (msg.sender == getAddressUpdater(), "only address updater");
        _;
    }

    constructor(address _addressUpdater) {
        setAddressUpdaterValue(_addressUpdater);
    }

    function getAddressUpdater() public view returns (address _addressUpdater) {
        // Only direct constants are allowed in inline assembly, so we assign it here
        bytes32 position = ADDRESS_STORAGE_POSITION;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            _addressUpdater := sload(position)
        }
    }

    /**
     * @notice external method called from AddressUpdater only
     */
    function updateContractAddresses(
        bytes32[] memory _contractNameHashes,
        address[] memory _contractAddresses
    )
        external override
        onlyAddressUpdater
    {
        // update addressUpdater address
        setAddressUpdaterValue(_getContractAddress(_contractNameHashes, _contractAddresses, "AddressUpdater"));
        // update all other addresses
        _updateContractAddresses(_contractNameHashes, _contractAddresses);
    }

    /**
     * @notice virtual method that a contract extending AddressUpdatable must implement
     */
    function _updateContractAddresses(
        bytes32[] memory _contractNameHashes,
        address[] memory _contractAddresses
    ) internal virtual;

    /**
     * @notice helper method to get contract address
     * @dev it reverts if contract name does not exist
     */
    function _getContractAddress(
        bytes32[] memory _nameHashes,
        address[] memory _addresses,
        string memory _nameToFind
    )
        internal pure
        returns(address)
    {
        bytes32 nameHash = keccak256(abi.encode(_nameToFind));
        address a = address(0);
        for (uint256 i = 0; i < _nameHashes.length; i++) {
            if (nameHash == _nameHashes[i]) {
                a = _addresses[i];
                break;
            }
        }
        require(a != address(0), "address zero");
        return a;
    }

    function setAddressUpdaterValue(address _addressUpdater) internal {
        // Only direct constants are allowed in inline assembly, so we assign it here
        bytes32 position = ADDRESS_STORAGE_POSITION;
        // solhint-disable-next-line no-inline-assembly  
        assembly {
            sstore(position, _addressUpdater)
        }
    }
}
          

./contracts/addressUpdater/interface/IIAddressUpdatable.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;


interface IIAddressUpdatable {
    /**
     * @notice Updates contract addresses - should be called only from AddressUpdater contract
     * @param _contractNameHashes       list of keccak256(abi.encode(...)) contract names
     * @param _contractAddresses        list of contract addresses corresponding to the contract names
     */
    function updateContractAddresses(
        bytes32[] memory _contractNameHashes,
        address[] memory _contractAddresses
        ) external;
}
          

./contracts/governance/implementation/Governed.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;

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


/**
 * @title Governed
 * @dev For deployed, governed contracts, enforce a non-zero address at create time.
 **/
contract Governed is GovernedBase {
    constructor(address _governance) GovernedBase(_governance) {
        require(_governance != address(0), "_governance zero");
    }
}
          

./contracts/governance/implementation/GovernedBase.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;

import "../../userInterfaces/IGovernanceSettings.sol";


/**
 * @title Governed Base
 * @notice This abstract base class defines behaviors for a governed contract.
 * @dev This class is abstract so that specific behaviors can be defined for the constructor.
 *   Contracts should not be left ungoverned, but not all contract will have a constructor
 *   (for example those pre-defined in genesis).
 **/
abstract contract GovernedBase {
    struct TimelockedCall {
        uint256 allowedAfterTimestamp;
        bytes encodedCall;
    }
    
    // solhint-disable-next-line const-name-snakecase
    IGovernanceSettings public constant governanceSettings = 
        IGovernanceSettings(0x1000000000000000000000000000000000000007);

    address private initialGovernance;

    bool private initialised;
    
    bool public productionMode;
    
    bool private executing;
    
    mapping(bytes4 => TimelockedCall) public timelockedCalls;
    
    event GovernanceCallTimelocked(bytes4 selector, uint256 allowedAfterTimestamp, bytes encodedCall);
    event TimelockedGovernanceCallExecuted(bytes4 selector, uint256 timestamp);
    event TimelockedGovernanceCallCanceled(bytes4 selector, uint256 timestamp);
    
    event GovernanceInitialised(address initialGovernance);
    event GovernedProductionModeEntered(address governanceSettings);
    
    modifier onlyGovernance {
        if (executing || !productionMode) {
            _beforeExecute();
            _;
        } else {
            _recordTimelockedCall(msg.data);
        }
    }
    
    modifier onlyImmediateGovernance () {
        _checkOnlyGovernance();
        _;
    }

    constructor(address _initialGovernance) {
        if (_initialGovernance != address(0)) {
            initialise(_initialGovernance);
        }
    }

    /**
     * @notice Execute the timelocked governance calls once the timelock period expires.
     * @dev Only executor can call this method.
     * @param _selector The method selector (only one timelocked call per method is stored).
     */
    function executeGovernanceCall(bytes4 _selector) external {
        require(governanceSettings.isExecutor(msg.sender), "only executor");
        TimelockedCall storage call = timelockedCalls[_selector];
        require(call.allowedAfterTimestamp != 0, "timelock: invalid selector");
        require(block.timestamp >= call.allowedAfterTimestamp, "timelock: not allowed yet");
        bytes memory encodedCall = call.encodedCall;
        delete timelockedCalls[_selector];
        executing = true;
        //solhint-disable-next-line avoid-low-level-calls
        (bool success,) = address(this).call(encodedCall);
        executing = false;
        emit TimelockedGovernanceCallExecuted(_selector, block.timestamp);
        _passReturnOrRevert(success);
    }
    
    /**
     * Cancel a timelocked governance call before it has been executed.
     * @dev Only governance can call this method.
     * @param _selector The method selector.
     */
    function cancelGovernanceCall(bytes4 _selector) external onlyImmediateGovernance {
        require(timelockedCalls[_selector].allowedAfterTimestamp != 0, "timelock: invalid selector");
        emit TimelockedGovernanceCallCanceled(_selector, block.timestamp);
        delete timelockedCalls[_selector];
    }
    
    /**
     * Enter the production mode after all the initial governance settings have been set.
     * This enables timelocks and the governance is afterwards obtained by calling 
     * governanceSettings.getGovernanceAddress(). 
     */
    function switchToProductionMode() external {
        _checkOnlyGovernance();
        require(!productionMode, "already in production mode");
        initialGovernance = address(0);
        productionMode = true;
        emit GovernedProductionModeEntered(address(governanceSettings));
    }

    /**
     * @notice Initialize the governance address if not first initialized.
     */
    function initialise(address _initialGovernance) public virtual {
        require(initialised == false, "initialised != false");
        initialised = true;
        initialGovernance = _initialGovernance;
        emit GovernanceInitialised(_initialGovernance);
    }
    
    /**
     * Returns the current effective governance address.
     */
    function governance() public view returns (address) {
        return productionMode ? governanceSettings.getGovernanceAddress() : initialGovernance;
    }

    function _beforeExecute() private {
        if (executing) {
            // can only be run from executeGovernanceCall(), where we check that only executor can call
            // make sure nothing else gets executed, even in case of reentrancy
            assert(msg.sender == address(this));
            executing = false;
        } else {
            // must be called with: productionMode=false
            // must check governance in this case
            _checkOnlyGovernance();
        }
    }

    function _recordTimelockedCall(bytes calldata _data) private {
        _checkOnlyGovernance();
        bytes4 selector;
        //solhint-disable-next-line no-inline-assembly
        assembly {
            selector := calldataload(_data.offset)
        }
        uint256 timelock = governanceSettings.getTimelock();
        uint256 allowedAt = block.timestamp + timelock;
        timelockedCalls[selector] = TimelockedCall({
            allowedAfterTimestamp: allowedAt,
            encodedCall: _data
        });
        emit GovernanceCallTimelocked(selector, allowedAt, _data);
    }
    
    function _checkOnlyGovernance() private view {
        require(msg.sender == governance(), "only governance");
    }
    
    function _passReturnOrRevert(bool _success) private pure {
        // pass exact return or revert data - needs to be done in assembly
        //solhint-disable-next-line no-inline-assembly
        assembly {
            let size := returndatasize()
            let ptr := mload(0x40)
            mstore(0x40, add(ptr, size))
            returndatacopy(ptr, 0, size)
            if _success {
                return(ptr, size)
            }
            revert(ptr, size)
        }
    }
}
          

./contracts/inflation/interface/IISupply.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;


interface IISupply {

    /**
     * @notice Updates circulating supply
     * @dev Also updates the burn address amount
    */
    function updateCirculatingSupply() external;

    /**
     * @notice Updates authorized inflation and circulating supply - emits event if error
     * @param _inflationAuthorizedWei               Authorized inflation
     * @dev Also updates the burn address amount
    */
    function updateAuthorizedInflationAndCirculatingSupply(uint256 _inflationAuthorizedWei) external;

    /**
     * @notice Get approximate circulating supply for given block number from cache - only past block
     * @param _blockNumber                          Block number
     * @return _circulatingSupplyWei Return approximate circulating supply for last known block <= _blockNumber
    */
    function getCirculatingSupplyAtCached(uint256 _blockNumber) external returns(uint256 _circulatingSupplyWei);

    /**
     * @notice Get approximate circulating supply for given block number
     * @param _blockNumber                          Block number
     * @return _circulatingSupplyWei Return approximate circulating supply for last known block <= _blockNumber
    */
    function getCirculatingSupplyAt(uint256 _blockNumber) external view returns(uint256 _circulatingSupplyWei);

    /**
     * @notice Get total inflatable balance (initial genesis amount + total authorized inflation)
     * @return _inflatableBalanceWei Return inflatable balance
    */
    function getInflatableBalance() external view returns(uint256 _inflatableBalanceWei);
}
          

./contracts/token/lib/CheckPointHistory.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;

import "@openzeppelin/contracts/math/Math.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/SafeCast.sol";


/**
 * @title Check Point History library
 * @notice A contract to manage checkpoints as of a given block.
 * @dev Store value history by block number with detachable state.
 **/
library CheckPointHistory {
    using SafeMath for uint256;
    using SafeCast for uint256;

    /**
     * @dev `CheckPoint` is the structure that attaches a block number to a
     *  given value; the block number attached is the one that last changed the
     *  value
     **/
    struct CheckPoint {
        // `value` is the amount of tokens at a specific block number
        uint192 value;
        // `fromBlock` is the block number that the value was generated from
        uint64 fromBlock;
    }

    struct CheckPointHistoryState {
        // `checkpoints` is an array that tracks values at non-contiguous block numbers
        mapping(uint256 => CheckPoint) checkpoints;
        // `checkpoints` before `startIndex` have been deleted
        // INVARIANT: checkpoints.endIndex == 0 || startIndex < checkpoints.endIndex      (strict!)
        // startIndex and endIndex are both less then fromBlock, so 64 bits is enough
        uint64 startIndex;
        // the index AFTER last
        uint64 endIndex;
    }

    /**
     * @notice Binary search of _checkpoints array.
     * @param _checkpoints An array of CheckPoint to search.
     * @param _startIndex Smallest possible index to be returned.
     * @param _blockNumber The block number to search for.
     */
    function _indexOfGreatestBlockLessThan(
        mapping(uint256 => CheckPoint) storage _checkpoints, 
        uint256 _startIndex,
        uint256 _endIndex,
        uint256 _blockNumber
    )
        private view 
        returns (uint256 index)
    {
        // Binary search of the value by given block number in the array
        uint256 min = _startIndex;
        uint256 max = _endIndex.sub(1);
        while (max > min) {
            uint256 mid = (max.add(min).add(1)).div(2);
            if (_checkpoints[mid].fromBlock <= _blockNumber) {
                min = mid;
            } else {
                max = mid.sub(1);
            }
        }
        return min;
    }

    /**
     * @notice Queries the value at a specific `_blockNumber`
     * @param _self A CheckPointHistoryState instance to manage.
     * @param _blockNumber The block number of the value active at that time
     * @return _value The value at `_blockNumber`     
     **/
    function valueAt(
        CheckPointHistoryState storage _self, 
        uint256 _blockNumber
    )
        internal view 
        returns (uint256 _value)
    {
        uint256 historyCount = _self.endIndex;

        // No _checkpoints, return 0
        if (historyCount == 0) return 0;

        // Shortcut for the actual value (extra optimized for current block, to save one storage read)
        // historyCount - 1 is safe, since historyCount != 0
        if (_blockNumber >= block.number || _blockNumber >= _self.checkpoints[historyCount - 1].fromBlock) {
            return _self.checkpoints[historyCount - 1].value;
        }
        
        // guard values at start    
        uint256 startIndex = _self.startIndex;
        if (_blockNumber < _self.checkpoints[startIndex].fromBlock) {
            // reading data before `startIndex` is only safe before first cleanup
            require(startIndex == 0, "CheckPointHistory: reading from cleaned-up block");
            return 0;
        }

        // Find the block with number less than or equal to block given
        uint256 index = _indexOfGreatestBlockLessThan(_self.checkpoints, startIndex, _self.endIndex, _blockNumber);

        return _self.checkpoints[index].value;
    }

    /**
     * @notice Queries the value at `block.number`
     * @param _self A CheckPointHistoryState instance to manage.
     * @return _value The value at `block.number`
     **/
    function valueAtNow(CheckPointHistoryState storage _self) internal view returns (uint256 _value) {
        uint256 historyCount = _self.endIndex;
        // No _checkpoints, return 0
        if (historyCount == 0) return 0;
        // Return last value
        return _self.checkpoints[historyCount - 1].value;
    }

    /**
     * @notice Writes the value at the current block.
     * @param _self A CheckPointHistoryState instance to manage.
     * @param _value Value to write.
     **/
    function writeValue(
        CheckPointHistoryState storage _self, 
        uint256 _value
    )
        internal
    {
        uint256 historyCount = _self.endIndex;
        if (historyCount == 0) {
            // checkpoints array empty, push new CheckPoint
            _self.checkpoints[0] = 
                CheckPoint({ fromBlock: block.number.toUint64(), value: _toUint192(_value) });
            _self.endIndex = 1;
        } else {
            // historyCount - 1 is safe, since historyCount != 0
            CheckPoint storage lastCheckpoint = _self.checkpoints[historyCount - 1];
            uint256 lastBlock = lastCheckpoint.fromBlock;
            // slither-disable-next-line incorrect-equality
            if (block.number == lastBlock) {
                // If last check point is the current block, just update
                lastCheckpoint.value = _toUint192(_value);
            } else {
                // we should never have future blocks in history
                assert (block.number > lastBlock);
                // push new CheckPoint
                _self.checkpoints[historyCount] = 
                    CheckPoint({ fromBlock: block.number.toUint64(), value: _toUint192(_value) });
                _self.endIndex = uint64(historyCount + 1);  // 64 bit safe, because historyCount <= block.number
            }
        }
    }
    
    /**
     * Delete at most `_count` of the oldest checkpoints.
     * At least one checkpoint at or before `_cleanupBlockNumber` will remain 
     * (unless the history was empty to start with).
     */    
    function cleanupOldCheckpoints(
        CheckPointHistoryState storage _self, 
        uint256 _count,
        uint256 _cleanupBlockNumber
    )
        internal
        returns (uint256)
    {
        if (_cleanupBlockNumber == 0) return 0;   // optimization for when cleaning is not enabled
        uint256 length = _self.endIndex;
        if (length == 0) return 0;
        uint256 startIndex = _self.startIndex;
        // length - 1 is safe, since length != 0 (check above)
        uint256 endIndex = Math.min(startIndex.add(_count), length - 1);    // last element can never be deleted
        uint256 index = startIndex;
        // we can delete `checkpoint[index]` while the next checkpoint is at `_cleanupBlockNumber` or before
        while (index < endIndex && _self.checkpoints[index + 1].fromBlock <= _cleanupBlockNumber) {
            delete _self.checkpoints[index];
            index++;
        }
        if (index > startIndex) {   // index is the first not deleted index
            _self.startIndex = index.toUint64();
        }
        return index - startIndex;  // safe: index >= startIndex at start and then increases
    }

    // SafeCast lib is missing cast to uint192    
    function _toUint192(uint256 _value) internal pure returns (uint192) {
        require(_value < 2**192, "value doesn't fit in 192 bits");
        return uint192(_value);
    }
}
          

./contracts/token/lib/CheckPointHistoryCache.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;

import "@openzeppelin/contracts/math/SafeMath.sol";
import "./CheckPointHistory.sol";


library CheckPointHistoryCache {
    using SafeMath for uint256;
    using CheckPointHistory for CheckPointHistory.CheckPointHistoryState;
    
    struct CacheState {
        // mapping blockNumber => (value + 1)
        mapping(uint256 => uint256) cache;
    }
    
    function valueAt(
        CacheState storage _self,
        CheckPointHistory.CheckPointHistoryState storage _checkPointHistory,
        uint256 _blockNumber
    )
        internal returns (uint256 _value, bool _cacheCreated)
    {
        // is it in cache?
        uint256 cachedValue = _self.cache[_blockNumber];
        if (cachedValue != 0) {
            return (cachedValue - 1, false);    // safe, cachedValue != 0
        }
        // read from _checkPointHistory
        uint256 historyValue = _checkPointHistory.valueAt(_blockNumber);
        _self.cache[_blockNumber] = historyValue.add(1);  // store to cache (add 1 to differentiate from empty)
        return (historyValue, true);
    }
    
    function deleteAt(
        CacheState storage _self,
        uint256 _blockNumber
    )
        internal returns (uint256 _deleted)
    {
        if (_self.cache[_blockNumber] != 0) {
            _self.cache[_blockNumber] = 0;
            return 1;
        }
        return 0;
    }
}
          

./contracts/tokenPools/interface/IITokenPool.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;

interface IITokenPool {

    /**
     * @notice Return token pool supply data
     * @return _lockedFundsWei                  Funds that are intentionally locked in the token pool 
     * and not part of circulating supply
     * @return _totalInflationAuthorizedWei     Total inflation authorized amount (wei)
     * @return _totalClaimedWei                 Total claimed amount (wei)
     */
    function getTokenPoolSupplyData() external returns (
        uint256 _lockedFundsWei,
        uint256 _totalInflationAuthorizedWei,
        uint256 _totalClaimedWei
    );
}
          

./contracts/userInterfaces/IGovernanceSettings.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;


/**
 * A special contract that holds Flare governance address.
 * This contract enables updating governance address and timelock only by hard forking the network,
 * meaning only by updating validator code.
 */
interface IGovernanceSettings {
    /**
     * Get the governance account address.
     * The governance address can only be changed by a hardfork.
     */
    function getGovernanceAddress() external view returns (address);
    
    /**
     * Get the time in seconds that must pass between a governance call and execution.
     * The timelock value can only be changed by a hardfork.
     */
    function getTimelock() external view returns (uint256);
    
    /**
     * Get the addresses of the accounts that are allowed to execute the timelocked governance calls
     * once the timelock period expires.
     * Executors can be changed without a hardfork, via a normal governance call.
     */
    function getExecutors() external view returns (address[] memory);
    
    /**
     * Check whether an address is one of the executors.
     */
    function isExecutor(address _address) external view returns (bool);
}
          

@openzeppelin/contracts/math/Math.sol

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <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, so we distribute
        return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
    }
}
          

@openzeppelin/contracts/math/SafeMath.sol

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

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

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

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

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

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: modulo by zero");
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        return a - b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a % b;
    }
}
          

@openzeppelin/contracts/utils/SafeCast.sol

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;


/**
 * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
 * checks.
 *
 * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
 * easily result in undesired exploitation or bugs, since developers usually
 * assume that overflows raise errors. `SafeCast` restores this intuition by
 * reverting the transaction when such an operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 *
 * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
 * all math on `uint256` and `int256` and then downcasting.
 */
library SafeCast {

    /**
     * @dev Returns the downcasted uint128 from uint256, reverting on
     * overflow (when the input is greater than largest uint128).
     *
     * Counterpart to Solidity's `uint128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     */
    function toUint128(uint256 value) internal pure returns (uint128) {
        require(value < 2**128, "SafeCast: value doesn\'t fit in 128 bits");
        return uint128(value);
    }

    /**
     * @dev Returns the downcasted uint64 from uint256, reverting on
     * overflow (when the input is greater than largest uint64).
     *
     * Counterpart to Solidity's `uint64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     */
    function toUint64(uint256 value) internal pure returns (uint64) {
        require(value < 2**64, "SafeCast: value doesn\'t fit in 64 bits");
        return uint64(value);
    }

    /**
     * @dev Returns the downcasted uint32 from uint256, reverting on
     * overflow (when the input is greater than largest uint32).
     *
     * Counterpart to Solidity's `uint32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     */
    function toUint32(uint256 value) internal pure returns (uint32) {
        require(value < 2**32, "SafeCast: value doesn\'t fit in 32 bits");
        return uint32(value);
    }

    /**
     * @dev Returns the downcasted uint16 from uint256, reverting on
     * overflow (when the input is greater than largest uint16).
     *
     * Counterpart to Solidity's `uint16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     */
    function toUint16(uint256 value) internal pure returns (uint16) {
        require(value < 2**16, "SafeCast: value doesn\'t fit in 16 bits");
        return uint16(value);
    }

    /**
     * @dev Returns the downcasted uint8 from uint256, reverting on
     * overflow (when the input is greater than largest uint8).
     *
     * Counterpart to Solidity's `uint8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits.
     */
    function toUint8(uint256 value) internal pure returns (uint8) {
        require(value < 2**8, "SafeCast: value doesn\'t fit in 8 bits");
        return uint8(value);
    }

    /**
     * @dev Converts a signed int256 into an unsigned uint256.
     *
     * Requirements:
     *
     * - input must be greater than or equal to 0.
     */
    function toUint256(int256 value) internal pure returns (uint256) {
        require(value >= 0, "SafeCast: value must be positive");
        return uint256(value);
    }

    /**
     * @dev Returns the downcasted int128 from int256, reverting on
     * overflow (when the input is less than smallest int128 or
     * greater than largest int128).
     *
     * Counterpart to Solidity's `int128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     *
     * _Available since v3.1._
     */
    function toInt128(int256 value) internal pure returns (int128) {
        require(value >= -2**127 && value < 2**127, "SafeCast: value doesn\'t fit in 128 bits");
        return int128(value);
    }

    /**
     * @dev Returns the downcasted int64 from int256, reverting on
     * overflow (when the input is less than smallest int64 or
     * greater than largest int64).
     *
     * Counterpart to Solidity's `int64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     *
     * _Available since v3.1._
     */
    function toInt64(int256 value) internal pure returns (int64) {
        require(value >= -2**63 && value < 2**63, "SafeCast: value doesn\'t fit in 64 bits");
        return int64(value);
    }

    /**
     * @dev Returns the downcasted int32 from int256, reverting on
     * overflow (when the input is less than smallest int32 or
     * greater than largest int32).
     *
     * Counterpart to Solidity's `int32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     *
     * _Available since v3.1._
     */
    function toInt32(int256 value) internal pure returns (int32) {
        require(value >= -2**31 && value < 2**31, "SafeCast: value doesn\'t fit in 32 bits");
        return int32(value);
    }

    /**
     * @dev Returns the downcasted int16 from int256, reverting on
     * overflow (when the input is less than smallest int16 or
     * greater than largest int16).
     *
     * Counterpart to Solidity's `int16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     *
     * _Available since v3.1._
     */
    function toInt16(int256 value) internal pure returns (int16) {
        require(value >= -2**15 && value < 2**15, "SafeCast: value doesn\'t fit in 16 bits");
        return int16(value);
    }

    /**
     * @dev Returns the downcasted int8 from int256, reverting on
     * overflow (when the input is less than smallest int8 or
     * greater than largest int8).
     *
     * Counterpart to Solidity's `int8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits.
     *
     * _Available since v3.1._
     */
    function toInt8(int256 value) internal pure returns (int8) {
        require(value >= -2**7 && value < 2**7, "SafeCast: value doesn\'t fit in 8 bits");
        return int8(value);
    }

    /**
     * @dev Converts an unsigned uint256 into a signed int256.
     *
     * Requirements:
     *
     * - input must be less than or equal to maxInt256.
     */
    function toInt256(uint256 value) internal pure returns (int256) {
        require(value < 2**255, "SafeCast: value doesn't fit in an int256");
        return int256(value);
    }
}
          

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_governance","internalType":"address"},{"type":"address","name":"_addressUpdater","internalType":"address"},{"type":"uint256","name":"_initialGenesisAmountWei","internalType":"uint256"},{"type":"uint256","name":"_totalExcludedSupplyWei","internalType":"uint256"},{"type":"address[]","name":"_tokenPools","internalType":"contract IITokenPool[]"}]},{"type":"event","name":"AuthorizedInflationUpdateError","inputs":[{"type":"uint256","name":"actual","internalType":"uint256","indexed":false},{"type":"uint256","name":"expected","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"GovernanceCallTimelocked","inputs":[{"type":"bytes4","name":"selector","internalType":"bytes4","indexed":false},{"type":"uint256","name":"allowedAfterTimestamp","internalType":"uint256","indexed":false},{"type":"bytes","name":"encodedCall","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"GovernanceInitialised","inputs":[{"type":"address","name":"initialGovernance","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"GovernedProductionModeEntered","inputs":[{"type":"address","name":"governanceSettings","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"TimelockedGovernanceCallCanceled","inputs":[{"type":"bytes4","name":"selector","internalType":"bytes4","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TimelockedGovernanceCallExecuted","inputs":[{"type":"bytes4","name":"selector","internalType":"bytes4","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addTokenPool","inputs":[{"type":"address","name":"_tokenPool","internalType":"contract IITokenPool"},{"type":"uint256","name":"_increaseDistributedSupplyByAmountWei","internalType":"uint256"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"address","name":"","internalType":"address payable"}],"name":"burnAddress","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cancelGovernanceCall","inputs":[{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"decreaseDistributedSupply","inputs":[{"type":"uint256","name":"_amountWei","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"distributedExcludedSupplyWei","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"executeGovernanceCall","inputs":[{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"_addressUpdater","internalType":"address"}],"name":"getAddressUpdater","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"_circulatingSupplyWei","internalType":"uint256"}],"name":"getCirculatingSupplyAt","inputs":[{"type":"uint256","name":"_blockNumber","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"_circulatingSupplyWei","internalType":"uint256"}],"name":"getCirculatingSupplyAtCached","inputs":[{"type":"uint256","name":"_blockNumber","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"_inflatableBalanceWei","internalType":"uint256"}],"name":"getInflatableBalance","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"governance","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IGovernanceSettings"}],"name":"governanceSettings","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"increaseDistributedSupply","inputs":[{"type":"uint256","name":"_amountWei","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"inflation","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"initialGenesisAmountWei","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialise","inputs":[{"type":"address","name":"_initialGovernance","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"productionMode","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"switchToProductionMode","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"allowedAfterTimestamp","internalType":"uint256"},{"type":"bytes","name":"encodedCall","internalType":"bytes"}],"name":"timelockedCalls","inputs":[{"type":"bytes4","name":"","internalType":"bytes4"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"tokenPool","internalType":"contract IITokenPool"},{"type":"uint256","name":"totalLockedWei","internalType":"uint256"},{"type":"uint256","name":"totalInflationAuthorizedWei","internalType":"uint256"},{"type":"uint256","name":"totalClaimedWei","internalType":"uint256"}],"name":"tokenPools","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalClaimedWei","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalExcludedSupplyWei","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalInflationAuthorizedWei","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalLockedWei","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateAuthorizedInflationAndCirculatingSupply","inputs":[{"type":"uint256","name":"_inflationAuthorizedWei","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateCirculatingSupply","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateContractAddresses","inputs":[{"type":"bytes32[]","name":"_contractNameHashes","internalType":"bytes32[]"},{"type":"address[]","name":"_contractAddresses","internalType":"address[]"}]}]
              

Contract Creation Code

0x60c06040523480156200001157600080fd5b5060405162002c3838038062002c38833981810160405260a08110156200003757600080fd5b81516020830151604080850151606086015160808701805193519597949692959194919392820192846401000000008211156200007357600080fd5b9083019060208201858111156200008957600080fd5b8251866020820283011164010000000082111715620000a757600080fd5b82525081516020918201928201910280838360005b83811015620000d6578181015183820152602001620000bc565b5050505090500160405250505083858060006001600160a01b0316816001600160a01b0316146200010c576200010c81620002ab565b506001600160a01b0381166200015c576040805162461bcd60e51b815260206004820152601060248201526f5f676f7665726e616e6365207a65726f60801b604482015290519081900360640190fd5b5062000168816200036e565b5060408051808201909152601b81527f696e697469616c2067656e6573697320616d6f756e74207a65726f00000000006020820152836200022a5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015620001ee578181015183820152602001620001d4565b50505050905090810190601f1680156200021c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50608083905260a08290526200025762000251848462000392602090811b620011df17901c565b620003f0565b60005b81518110156200029257620002898282815181106200027557fe5b60200260200101516200043d60201b60201c565b6001016200025a565b50620002a061dead62000552565b505050505062000b52565b600054600160a01b900460ff16156200030b576040805162461bcd60e51b815260206004820152601460248201527f696e697469616c6973656420213d2066616c7365000000000000000000000000604482015290519081900360640190fd5b60008054600160a01b60ff60a01b19909116176001600160a01b0319166001600160a01b03831690811790915560408051918252517f9789733827840833afc031fb2ef9ab6894271f77bad2085687cf4ae5c7bee4db916020908290030190a150565b7f714f205b2abd25bef1d06a1af944e38c113fe6160375c4e1d6d5cf28848e771955565b600082821115620003ea576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6200043a62000424826200041060026200078460201b620012411760201c565b620007d660201b6200128a1790919060201c565b60026200083860201b620012eb1790919060201c565b50565b60095460005b818110156200050257600981815481106200045a57fe5b60009182526020909120600490910201546001600160a01b0384811691161415620004f957604080518082018252601881527f746f6b656e20706f6f6c20616c726561647920616464656400000000000000006020808301918252925162461bcd60e51b81526004810193845282516024820152825192939283926044909201919080838360008315620001ee578181015183820152602001620001d4565b60010162000443565b50600980546001018082556000829052839190839081106200052057fe5b6000918252602090912060049091020180546001600160a01b0319166001600160a01b03929092169190911790555050565b60095460005b8181101562000774576000600982815481106200057157fe5b600091825260208220600491820201805460408051632dafdbbf60e01b81529051929550849384936001600160a01b0390931692632dafdbbf92808301926060929182900301818787803b158015620005c957600080fd5b505af1158015620005de573d6000803e3d6000fd5b505050506040513d6060811015620005f557600080fd5b508051602080830151604090930151919550919350915081906200062690859085906200128a620007d6821b17901c565b10156200062f57fe5b60006200064f8560020154846200039260201b620011df1790919060201c565b90506200066d81600754620007d660201b6200128a1790919060201c565b6007819055506000620006938660030154846200039260201b620011df1790919060201c565b9050620006a081620003f0565b620006bc81600854620007d660201b6200128a1790919060201c565b60085560018601548510620007035760018601548503620006dd8162000a39565b620006f981600654620007d660201b6200128a1790919060201c565b6006555062000751565b60008587600101540390506200072a816005546200039260201b620011df1790919060201c565b6005819055506200074c816006546200039260201b620011df1790919060201c565b600655505b505060018085019390935560028401919091556003909201919091550162000558565b50620007808262000a6d565b5050565b60018101546000906801000000000000000090046001600160401b031680620007b2576000915050620007d1565b600019016000908152602083905260409020546001600160c01b031690505b919050565b60008282018381101562000831576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b60018201546801000000000000000090046001600160401b0316806200090f576040518060400160405280620008748462000aa860201b60201c565b6001600160c01b03168152602001620008984362000b0760201b620014b11760201c565b6001600160401b03908116909152600080805260208681526040909120835181549490920151909216600160c01b026001600160c01b039182166001600160c01b03199094169390931716919091179055600183018054600160401b600160801b0319166801000000000000000017905562000a34565b600019810160009081526020849052604090208054600160c01b90046001600160401b0316438114156200096957620009488462000aa8565b82546001600160c01b0319166001600160c01b039190911617825562000a31565b8043116200097357fe5b60405180604001604052806200098f8662000aa860201b60201c565b6001600160c01b03168152602001620009b34362000b0760201b620014b11760201c565b6001600160401b039081169091526000858152602088815260409091208351815494909201518316600160c01b026001600160c01b039283166001600160c01b03199095169490941790911692909217909155600180870180549186019092166801000000000000000002600160401b600160801b03199091161790555b50505b505050565b6200043a620004248262000a5960026200078460201b620012411760201c565b6200039260201b620011df1790919060201c565b6000816001600160a01b031631905062000aa262000a9c600b54836200039260201b620011df1790919060201c565b62000a39565b600b5550565b6000600160c01b821062000b03576040805162461bcd60e51b815260206004820152601d60248201527f76616c756520646f65736e27742066697420696e203139322062697473000000604482015290519081900360640190fd5b5090565b600068010000000000000000821062000b035760405162461bcd60e51b815260040180806020018281038252602681526020018062002c126026913960400191505060405180910390fd5b60805160a05161208d62000b856000398061067b52806110a75280611c3f5250806106b15280611020525061208d6000f3fe608060405234801561001057600080fd5b50600436106101a85760003560e01c806374e6310e116100f9578063d0c1c39311610097578063e17f212e11610071578063e17f212e1461055c578063e433f81814610578578063efcf7eb214610580578063f5a98383146105ac576101a8565b8063d0c1c3931461051a578063d9330e6314610522578063df3d9b731461053f576101a8565b8063a2420e20116100d3578063a2420e20146103c6578063b00c0b76146103e3578063be0522e01461050a578063bfebbd2614610512576101a8565b806374e6310e146102f25780639d6a890f146103985780639f71043e146103be576101a8565b80635267a15d116101665780636159b0a3116101405780636159b0a31461029e57806362354e03146102bb57806367fc4029146102c357806370d5ae05146102ea576101a8565b80635267a15d1461024b5780635aa6e6751461026f5780635ff2707914610277576101a8565b8062c0f916146101ad578063037b0890146101fa578063099eea62146102295780631b73b4cb1461023157806332ae2927146102395780633c8c461c14610241575b600080fd5b6101ca600480360360208110156101c357600080fd5b50356105b4565b604080516001600160a01b0390951685526020850193909352838301919091526060830152519081900360800190f35b6102176004803603602081101561021057600080fd5b50356105f8565b60408051918252519081900360200190f35b610217610662565b610217610668565b6102176106e1565b6102496106e7565b005b6102536107b1565b604080516001600160a01b039092168252519081900360200190f35b6102536107d6565b6102496004803603602081101561028d57600080fd5b50356001600160e01b03191661086a565b610249600480360360208110156102b457600080fd5b5035610bbf565b610253610c25565b610249600480360360208110156102d957600080fd5b50356001600160e01b031916610c30565b610253610d18565b6103196004803603602081101561030857600080fd5b50356001600160e01b031916610d1e565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561035c578181015183820152602001610344565b50505050905090810190601f1680156103895780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b610249600480360360208110156103ae57600080fd5b50356001600160a01b0316610dc4565b610217610e7d565b610249600480360360208110156103dc57600080fd5b5035610e83565b610249600480360360408110156103f957600080fd5b81019060208101813564010000000081111561041457600080fd5b82018360208201111561042657600080fd5b8035906020019184602083028401116401000000008311171561044857600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561049857600080fd5b8201836020820111156104aa57600080fd5b803590602001918460208302840111640100000000831117156104cc57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610f68945050505050565b61025361100f565b61021761101e565b610217611042565b6102176004803603602081101561053857600080fd5b5035611048565b6102496004803603602081101561055557600080fd5b503561105d565b610564611095565b604080519115158252519081900360200190f35b6102176110a5565b6102496004803603604081101561059657600080fd5b506001600160a01b0381351690602001356110c9565b610249611125565b600981815481106105c457600080fd5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169350919084565b600043821061064e576040805162461bcd60e51b815260206004820181905260248201527f43616e206f6e6c79206265207573656420666f72207061737420626c6f636b73604482015290519081900360640190fd5b61065b60046002846114f9565b5092915050565b60055481565b60006106dc6006546106d66106a86005547f00000000000000000000000000000000000000000000000000000000000000006111df90919063ffffffff16565b6008546106d6907f00000000000000000000000000000000000000000000000000000000000000009061128a565b906111df565b905090565b60065481565b600a5460408051808201909152600e81526d696e666c6174696f6e206f6e6c7960901b6020820152906001600160a01b031633146107a35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610768578181015183820152602001610750565b50505050905090810190601f1680156107955780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506107af61dead611557565b565b7f714f205b2abd25bef1d06a1af944e38c113fe6160375c4e1d6d5cf28848e77195490565b60008054600160a81b900460ff166107f9576000546001600160a01b03166106dc565b60076001609c1b016001600160a01b031663732524946040518163ffffffff1660e01b815260040160206040518083038186803b15801561083957600080fd5b505afa15801561084d573d6000803e3d6000fd5b505050506040513d602081101561086357600080fd5b5051905090565b60408051630debfda360e41b8152336004820152905160076001609c1b019163debfda30916024808301926020929190829003018186803b1580156108ae57600080fd5b505afa1580156108c2573d6000803e3d6000fd5b505050506040513d60208110156108d857600080fd5b505161091b576040805162461bcd60e51b815260206004820152600d60248201526c37b7363c9032bc32b1baba37b960991b604482015290519081900360640190fd5b6001600160e01b0319811660009081526001602052604090208054610987576040805162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f72000000000000604482015290519081900360640190fd5b80544210156109dd576040805162461bcd60e51b815260206004820152601960248201527f74696d656c6f636b3a206e6f7420616c6c6f7765642079657400000000000000604482015290519081900360640190fd5b6000816001018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a775780601f10610a4c57610100808354040283529160200191610a77565b820191906000526020600020905b815481529060010190602001808311610a5a57829003601f168201915b5050506001600160e01b0319861660009081526001602081905260408220828155949550909250610aab9150830182611f24565b50506000805460ff60b01b1916600160b01b178155604051825130918491819060208401908083835b60208310610af35780518252601f199092019160209182019101610ad4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610b55576040519150601f19603f3d011682016040523d82523d6000602084013e610b5a565b606091505b50506000805460ff60b01b19169055604080516001600160e01b03198716815242602082015281519293507fa7326b57fc9cfe267aaea5e7f0b01757154d265620a0585819416ee9ddd2c438929081900390910190a1610bb981611701565b50505050565b600054600160b01b900460ff1680610be15750600054600160a81b900460ff16155b15610c1757610bee61171e565b600554610bfb90826111df565b600555610c0781611753565b610c1261dead611557565b610c22565b610c2260003661176c565b50565b60076001609c1b0181565b610c386118ef565b6001600160e01b03198116600090815260016020526040902054610ca3576040805162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f72000000000000604482015290519081900360640190fd5b604080516001600160e01b03198316815242602082015281517f7735b2391c38a81419c513e30ca578db7158eadd7101511b23e221c654d19cf8929181900390910190a16001600160e01b03198116600090815260016020819052604082208281559190610d1390830182611f24565b505050565b61dead90565b600160208181526000928352604092839020805481840180548651600296821615610100026000190190911695909504601f81018590048502860185019096528585529094919392909190830182828015610dba5780601f10610d8f57610100808354040283529160200191610dba565b820191906000526020600020905b815481529060010190602001808311610d9d57829003601f168201915b5050505050905082565b600054600160a01b900460ff1615610e1a576040805162461bcd60e51b8152602060048201526014602482015273696e697469616c6973656420213d2066616c736560601b604482015290519081900360640190fd5b60008054600160a01b60ff60a01b19909116176001600160a01b0319166001600160a01b03831690811790915560408051918252517f9789733827840833afc031fb2ef9ab6894271f77bad2085687cf4ae5c7bee4db916020908290030190a150565b60085481565b600a5460408051808201909152600e81526d696e666c6174696f6e206f6e6c7960901b6020820152906001600160a01b03163314610f025760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610768578181015183820152602001610750565b50600754610f1161dead611557565b610f1b818361128a565b60075414610f6457600754604080519183900382526020820184905280517feeb8970a03ae6e5930263b6b2553da66b8e20080d79a3f33c139e5855574eb739281900390910190a15b5050565b610f706107b1565b6001600160a01b0316336001600160a01b031614610fcc576040805162461bcd60e51b815260206004820152601460248201527337b7363c9030b2323932b9b9903ab83230ba32b960611b604482015290519081900360640190fd5b61100561100083836040518060400160405280600e81526020016d20b2323932b9b9aab83230ba32b960911b81525061194e565b611a7b565b610f648282611a9f565b600a546001600160a01b031681565b7f000000000000000000000000000000000000000000000000000000000000000081565b60075481565b6000611055600283611aef565b90505b919050565b600054600160b01b900460ff168061107f5750600054600160a81b900460ff16155b15610c175761108c61171e565b610c0781611c36565b600054600160a81b900460ff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b600054600160b01b900460ff16806110eb5750600054600160a81b900460ff16155b1561111a576110f861171e565b61110181611c36565b61110a82611c90565b61111561dead611557565b610f64565b610f6460003661176c565b61112d6118ef565b600054600160a81b900460ff161561118c576040805162461bcd60e51b815260206004820152601a60248201527f616c726561647920696e2070726f64756374696f6e206d6f6465000000000000604482015290519081900360640190fd5b60008054600161ff0160a01b031916600160a81b1790556040805160076001609c1b01815290517f83af113638b5422f9e977cebc0aaf0eaf2188eb9a8baae7f9d46c42b33a1560c9181900360200190a1565b600082821115611236576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b508082035b92915050565b6001810154600090600160401b900467ffffffffffffffff1680611269576000915050611058565b6000190160009081526020929092525060409020546001600160c01b031690565b6000828201838110156112e4576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001820154600160401b900467ffffffffffffffff16806113a457604051806040016040528061131a84611d9e565b6001600160c01b03168152602001611331436114b1565b67ffffffffffffffff908116909152600080805260208681526040909120835181549490920151909216600160c01b026001600160c01b039182166001600160c01b0319909416939093171691909117905560018301805467ffffffffffffffff60401b1916600160401b179055610d13565b600019810160009081526020849052604090208054600160c01b900467ffffffffffffffff16438114156113fb576113db84611d9e565b82546001600160c01b0319166001600160c01b03919091161782556114aa565b80431161140457fe5b604051806040016040528061141886611d9e565b6001600160c01b0316815260200161142f436114b1565b67ffffffffffffffff9081169091526000858152602088815260409091208351815494909201518316600160c01b026001600160c01b039283166001600160c01b0319909516949094179091169290921790915560018087018054918601909216600160401b0267ffffffffffffffff60401b199091161790555b5050505050565b6000600160401b82106114f55760405162461bcd60e51b81526004018080602001828103825260268152602001806120026026913960400191505060405180910390fd5b5090565b6000818152602084905260408120548190801561151f576000190191506000905061154f565b600061152b8686611aef565b905061153881600161128a565b600086815260208990526040902055925060019150505b935093915050565b60095460005b818110156116f75760006009828154811061157457fe5b600091825260208220600491820201805460408051632dafdbbf60e01b81529051929550849384936001600160a01b0390931692632dafdbbf92808301926060929182900301818787803b1580156115cb57600080fd5b505af11580156115df573d6000803e3d6000fd5b505050506040513d60608110156115f557600080fd5b5080516020820151604090920151909450909250905080611616848461128a565b101561161e57fe5b60006116378560020154846111df90919063ffffffff16565b600754909150611647908261128a565b600755600385015460009061165d9084906111df565b905061166881611df8565b600854611675908261128a565b600855600186015485106116a9576001860154850361169381611753565b6006546116a0908261128a565b600655506116d5565b600186015460055490869003906116c090826111df565b6005556006546116d090826111df565b600655505b505060018085019390935560028401919091556003909201919091550161155d565b50610f6482611e0f565b3d604051818101604052816000823e821561171a578181f35b8181fd5b600054600160b01b900460ff161561174b5733301461173957fe5b6000805460ff60b01b191690556107af565b6107af6118ef565b610c22611764826106d66002611241565b6002906112eb565b6117746118ef565b600082359050600060076001609c1b016001600160a01b0316636221a54b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156117bc57600080fd5b505afa1580156117d0573d6000803e3d6000fd5b505050506040513d60208110156117e657600080fd5b505160408051808201825242830180825282516020601f89018190048102820181019094528781529394509290918281019190889088908190840183828082843760009201829052509390945250506001600160e01b0319861681526001602081815260409092208451815584830151805191945061186a93928501920190611f68565b509050507fed948300a3694aa01d4a6b258bfd664350193d770c0b51f8387277f6d83ea3b68382878760405180856001600160e01b0319168152602001848152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f191690920182900397509095505050505050a15050505050565b6118f76107d6565b6001600160a01b0316336001600160a01b0316146107af576040805162461bcd60e51b815260206004820152600f60248201526e6f6e6c7920676f7665726e616e636560881b604482015290519081900360640190fd5b600080826040516020018080602001828103825283818151815260200191508051906020019080838360005b8381101561199257818101518382015260200161197a565b50505050905090810190601f1680156119bf5780820380516001836020036101000a031916815260200191505b50925050506040516020818303038152906040528051906020012090506000805b8651811015611a27578681815181106119f557fe5b6020026020010151831415611a1f57858181518110611a1057fe5b60200260200101519150611a27565b6001016119e0565b506001600160a01b038116611a72576040805162461bcd60e51b815260206004820152600c60248201526b61646472657373207a65726f60a01b604482015290519081900360640190fd5b95945050505050565b7f714f205b2abd25bef1d06a1af944e38c113fe6160375c4e1d6d5cf28848e771955565b611acb82826040518060400160405280600981526020016824b7333630ba34b7b760b91b81525061194e565b600a80546001600160a01b0319166001600160a01b03929092169190911790555050565b6001820154600090600160401b900467ffffffffffffffff1680611b1757600091505061123b565b4383101580611b4a57506000198101600090815260208590526040902054600160c01b900467ffffffffffffffff168310155b15611b7257600019016000908152602084905260409020546001600160c01b0316905061123b565b600184015467ffffffffffffffff9081166000818152602087905260409020549091600160c01b90910416841015611bec578015611be15760405162461bcd60e51b81526004018080602001828103825260308152602001806120286030913960400191505060405180910390fd5b60009250505061123b565b6001850154600090611c139087908490600160401b900467ffffffffffffffff1688611e38565b6000908152602087905260409020546001600160c01b0316935050505092915050565b80611c6c6005547f00000000000000000000000000000000000000000000000000000000000000006111df90919063ffffffff16565b1015611c7457fe5b611c7d81611df8565b600554611c8a908261128a565b60055550565b60095460005b81811015611d4f5760098181548110611cab57fe5b60009182526020909120600490910201546001600160a01b0384811691161415611d4757604080518082018252601881527f746f6b656e20706f6f6c20616c726561647920616464656400000000000000006020808301918252925162461bcd60e51b81526004810193845282516024820152825192939283926044909201919080838360008315610768578181015183820152602001610750565b600101611c96565b5060098054600101808255600082905283919083908110611d6c57fe5b6000918252602090912060049091020180546001600160a01b0319166001600160a01b03929092169190911790555050565b6000600160c01b82106114f5576040805162461bcd60e51b815260206004820152601d60248201527f76616c756520646f65736e27742066697420696e203139322062697473000000604482015290519081900360640190fd5b610c2261176482611e096002611241565b9061128a565b600b546001600160a01b0382163190611e3290611e2d9083906111df565b611753565b600b5550565b60008381611e478560016111df565b90505b81811115611eb3576000611e6e6002611e686001611e09868861128a565b90611ebd565b600081815260208a90526040902054909150600160c01b900467ffffffffffffffff168510611e9f57809250611ead565b611eaa8160016111df565b91505b50611e4a565b5095945050505050565b6000808211611f13576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381611f1c57fe5b049392505050565b50805460018160011615610100020316600290046000825580601f10611f4a5750610c22565b601f016020900490600052602060002090810190610c229190611fec565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282611f9e5760008555611fe4565b82601f10611fb757805160ff1916838001178555611fe4565b82800160010185558215611fe4579182015b82811115611fe4578251825591602001919060010190611fc9565b506114f59291505b5b808211156114f55760008155600101611fed56fe53616665436173743a2076616c756520646f65736e27742066697420696e2036342062697473436865636b506f696e74486973746f72793a2072656164696e672066726f6d20636c65616e65642d757020626c6f636ba2646970667358221220aaf4c1eb2a9a67dcf6d9cd51620eb7944fc17609f87f60d10d6d6084d54ba66e64736f6c6343000706003353616665436173743a2076616c756520646f65736e27742066697420696e20363420626974730000000000000000000000004598a6c05910ab914f0cbaaca1911cd337d10d29000000000000000000000000baf89d873d198ff78e72d2745b01cba3c6e5be6b0000000000000000000000000000000000000001431e0fae6d7217caa00000000000000000000000000000000000000000000000dbb8481a7362102da000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106101a85760003560e01c806374e6310e116100f9578063d0c1c39311610097578063e17f212e11610071578063e17f212e1461055c578063e433f81814610578578063efcf7eb214610580578063f5a98383146105ac576101a8565b8063d0c1c3931461051a578063d9330e6314610522578063df3d9b731461053f576101a8565b8063a2420e20116100d3578063a2420e20146103c6578063b00c0b76146103e3578063be0522e01461050a578063bfebbd2614610512576101a8565b806374e6310e146102f25780639d6a890f146103985780639f71043e146103be576101a8565b80635267a15d116101665780636159b0a3116101405780636159b0a31461029e57806362354e03146102bb57806367fc4029146102c357806370d5ae05146102ea576101a8565b80635267a15d1461024b5780635aa6e6751461026f5780635ff2707914610277576101a8565b8062c0f916146101ad578063037b0890146101fa578063099eea62146102295780631b73b4cb1461023157806332ae2927146102395780633c8c461c14610241575b600080fd5b6101ca600480360360208110156101c357600080fd5b50356105b4565b604080516001600160a01b0390951685526020850193909352838301919091526060830152519081900360800190f35b6102176004803603602081101561021057600080fd5b50356105f8565b60408051918252519081900360200190f35b610217610662565b610217610668565b6102176106e1565b6102496106e7565b005b6102536107b1565b604080516001600160a01b039092168252519081900360200190f35b6102536107d6565b6102496004803603602081101561028d57600080fd5b50356001600160e01b03191661086a565b610249600480360360208110156102b457600080fd5b5035610bbf565b610253610c25565b610249600480360360208110156102d957600080fd5b50356001600160e01b031916610c30565b610253610d18565b6103196004803603602081101561030857600080fd5b50356001600160e01b031916610d1e565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561035c578181015183820152602001610344565b50505050905090810190601f1680156103895780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b610249600480360360208110156103ae57600080fd5b50356001600160a01b0316610dc4565b610217610e7d565b610249600480360360208110156103dc57600080fd5b5035610e83565b610249600480360360408110156103f957600080fd5b81019060208101813564010000000081111561041457600080fd5b82018360208201111561042657600080fd5b8035906020019184602083028401116401000000008311171561044857600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561049857600080fd5b8201836020820111156104aa57600080fd5b803590602001918460208302840111640100000000831117156104cc57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610f68945050505050565b61025361100f565b61021761101e565b610217611042565b6102176004803603602081101561053857600080fd5b5035611048565b6102496004803603602081101561055557600080fd5b503561105d565b610564611095565b604080519115158252519081900360200190f35b6102176110a5565b6102496004803603604081101561059657600080fd5b506001600160a01b0381351690602001356110c9565b610249611125565b600981815481106105c457600080fd5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169350919084565b600043821061064e576040805162461bcd60e51b815260206004820181905260248201527f43616e206f6e6c79206265207573656420666f72207061737420626c6f636b73604482015290519081900360640190fd5b61065b60046002846114f9565b5092915050565b60055481565b60006106dc6006546106d66106a86005547f0000000000000000000000000000000000000000dbb8481a7362102da00000006111df90919063ffffffff16565b6008546106d6907f0000000000000000000000000000000000000001431e0fae6d7217caa00000009061128a565b906111df565b905090565b60065481565b600a5460408051808201909152600e81526d696e666c6174696f6e206f6e6c7960901b6020820152906001600160a01b031633146107a35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610768578181015183820152602001610750565b50505050905090810190601f1680156107955780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506107af61dead611557565b565b7f714f205b2abd25bef1d06a1af944e38c113fe6160375c4e1d6d5cf28848e77195490565b60008054600160a81b900460ff166107f9576000546001600160a01b03166106dc565b60076001609c1b016001600160a01b031663732524946040518163ffffffff1660e01b815260040160206040518083038186803b15801561083957600080fd5b505afa15801561084d573d6000803e3d6000fd5b505050506040513d602081101561086357600080fd5b5051905090565b60408051630debfda360e41b8152336004820152905160076001609c1b019163debfda30916024808301926020929190829003018186803b1580156108ae57600080fd5b505afa1580156108c2573d6000803e3d6000fd5b505050506040513d60208110156108d857600080fd5b505161091b576040805162461bcd60e51b815260206004820152600d60248201526c37b7363c9032bc32b1baba37b960991b604482015290519081900360640190fd5b6001600160e01b0319811660009081526001602052604090208054610987576040805162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f72000000000000604482015290519081900360640190fd5b80544210156109dd576040805162461bcd60e51b815260206004820152601960248201527f74696d656c6f636b3a206e6f7420616c6c6f7765642079657400000000000000604482015290519081900360640190fd5b6000816001018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a775780601f10610a4c57610100808354040283529160200191610a77565b820191906000526020600020905b815481529060010190602001808311610a5a57829003601f168201915b5050506001600160e01b0319861660009081526001602081905260408220828155949550909250610aab9150830182611f24565b50506000805460ff60b01b1916600160b01b178155604051825130918491819060208401908083835b60208310610af35780518252601f199092019160209182019101610ad4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610b55576040519150601f19603f3d011682016040523d82523d6000602084013e610b5a565b606091505b50506000805460ff60b01b19169055604080516001600160e01b03198716815242602082015281519293507fa7326b57fc9cfe267aaea5e7f0b01757154d265620a0585819416ee9ddd2c438929081900390910190a1610bb981611701565b50505050565b600054600160b01b900460ff1680610be15750600054600160a81b900460ff16155b15610c1757610bee61171e565b600554610bfb90826111df565b600555610c0781611753565b610c1261dead611557565b610c22565b610c2260003661176c565b50565b60076001609c1b0181565b610c386118ef565b6001600160e01b03198116600090815260016020526040902054610ca3576040805162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f72000000000000604482015290519081900360640190fd5b604080516001600160e01b03198316815242602082015281517f7735b2391c38a81419c513e30ca578db7158eadd7101511b23e221c654d19cf8929181900390910190a16001600160e01b03198116600090815260016020819052604082208281559190610d1390830182611f24565b505050565b61dead90565b600160208181526000928352604092839020805481840180548651600296821615610100026000190190911695909504601f81018590048502860185019096528585529094919392909190830182828015610dba5780601f10610d8f57610100808354040283529160200191610dba565b820191906000526020600020905b815481529060010190602001808311610d9d57829003601f168201915b5050505050905082565b600054600160a01b900460ff1615610e1a576040805162461bcd60e51b8152602060048201526014602482015273696e697469616c6973656420213d2066616c736560601b604482015290519081900360640190fd5b60008054600160a01b60ff60a01b19909116176001600160a01b0319166001600160a01b03831690811790915560408051918252517f9789733827840833afc031fb2ef9ab6894271f77bad2085687cf4ae5c7bee4db916020908290030190a150565b60085481565b600a5460408051808201909152600e81526d696e666c6174696f6e206f6e6c7960901b6020820152906001600160a01b03163314610f025760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610768578181015183820152602001610750565b50600754610f1161dead611557565b610f1b818361128a565b60075414610f6457600754604080519183900382526020820184905280517feeb8970a03ae6e5930263b6b2553da66b8e20080d79a3f33c139e5855574eb739281900390910190a15b5050565b610f706107b1565b6001600160a01b0316336001600160a01b031614610fcc576040805162461bcd60e51b815260206004820152601460248201527337b7363c9030b2323932b9b9903ab83230ba32b960611b604482015290519081900360640190fd5b61100561100083836040518060400160405280600e81526020016d20b2323932b9b9aab83230ba32b960911b81525061194e565b611a7b565b610f648282611a9f565b600a546001600160a01b031681565b7f0000000000000000000000000000000000000001431e0fae6d7217caa000000081565b60075481565b6000611055600283611aef565b90505b919050565b600054600160b01b900460ff168061107f5750600054600160a81b900460ff16155b15610c175761108c61171e565b610c0781611c36565b600054600160a81b900460ff1681565b7f0000000000000000000000000000000000000000dbb8481a7362102da000000081565b600054600160b01b900460ff16806110eb5750600054600160a81b900460ff16155b1561111a576110f861171e565b61110181611c36565b61110a82611c90565b61111561dead611557565b610f64565b610f6460003661176c565b61112d6118ef565b600054600160a81b900460ff161561118c576040805162461bcd60e51b815260206004820152601a60248201527f616c726561647920696e2070726f64756374696f6e206d6f6465000000000000604482015290519081900360640190fd5b60008054600161ff0160a01b031916600160a81b1790556040805160076001609c1b01815290517f83af113638b5422f9e977cebc0aaf0eaf2188eb9a8baae7f9d46c42b33a1560c9181900360200190a1565b600082821115611236576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b508082035b92915050565b6001810154600090600160401b900467ffffffffffffffff1680611269576000915050611058565b6000190160009081526020929092525060409020546001600160c01b031690565b6000828201838110156112e4576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001820154600160401b900467ffffffffffffffff16806113a457604051806040016040528061131a84611d9e565b6001600160c01b03168152602001611331436114b1565b67ffffffffffffffff908116909152600080805260208681526040909120835181549490920151909216600160c01b026001600160c01b039182166001600160c01b0319909416939093171691909117905560018301805467ffffffffffffffff60401b1916600160401b179055610d13565b600019810160009081526020849052604090208054600160c01b900467ffffffffffffffff16438114156113fb576113db84611d9e565b82546001600160c01b0319166001600160c01b03919091161782556114aa565b80431161140457fe5b604051806040016040528061141886611d9e565b6001600160c01b0316815260200161142f436114b1565b67ffffffffffffffff9081169091526000858152602088815260409091208351815494909201518316600160c01b026001600160c01b039283166001600160c01b0319909516949094179091169290921790915560018087018054918601909216600160401b0267ffffffffffffffff60401b199091161790555b5050505050565b6000600160401b82106114f55760405162461bcd60e51b81526004018080602001828103825260268152602001806120026026913960400191505060405180910390fd5b5090565b6000818152602084905260408120548190801561151f576000190191506000905061154f565b600061152b8686611aef565b905061153881600161128a565b600086815260208990526040902055925060019150505b935093915050565b60095460005b818110156116f75760006009828154811061157457fe5b600091825260208220600491820201805460408051632dafdbbf60e01b81529051929550849384936001600160a01b0390931692632dafdbbf92808301926060929182900301818787803b1580156115cb57600080fd5b505af11580156115df573d6000803e3d6000fd5b505050506040513d60608110156115f557600080fd5b5080516020820151604090920151909450909250905080611616848461128a565b101561161e57fe5b60006116378560020154846111df90919063ffffffff16565b600754909150611647908261128a565b600755600385015460009061165d9084906111df565b905061166881611df8565b600854611675908261128a565b600855600186015485106116a9576001860154850361169381611753565b6006546116a0908261128a565b600655506116d5565b600186015460055490869003906116c090826111df565b6005556006546116d090826111df565b600655505b505060018085019390935560028401919091556003909201919091550161155d565b50610f6482611e0f565b3d604051818101604052816000823e821561171a578181f35b8181fd5b600054600160b01b900460ff161561174b5733301461173957fe5b6000805460ff60b01b191690556107af565b6107af6118ef565b610c22611764826106d66002611241565b6002906112eb565b6117746118ef565b600082359050600060076001609c1b016001600160a01b0316636221a54b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156117bc57600080fd5b505afa1580156117d0573d6000803e3d6000fd5b505050506040513d60208110156117e657600080fd5b505160408051808201825242830180825282516020601f89018190048102820181019094528781529394509290918281019190889088908190840183828082843760009201829052509390945250506001600160e01b0319861681526001602081815260409092208451815584830151805191945061186a93928501920190611f68565b509050507fed948300a3694aa01d4a6b258bfd664350193d770c0b51f8387277f6d83ea3b68382878760405180856001600160e01b0319168152602001848152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f191690920182900397509095505050505050a15050505050565b6118f76107d6565b6001600160a01b0316336001600160a01b0316146107af576040805162461bcd60e51b815260206004820152600f60248201526e6f6e6c7920676f7665726e616e636560881b604482015290519081900360640190fd5b600080826040516020018080602001828103825283818151815260200191508051906020019080838360005b8381101561199257818101518382015260200161197a565b50505050905090810190601f1680156119bf5780820380516001836020036101000a031916815260200191505b50925050506040516020818303038152906040528051906020012090506000805b8651811015611a27578681815181106119f557fe5b6020026020010151831415611a1f57858181518110611a1057fe5b60200260200101519150611a27565b6001016119e0565b506001600160a01b038116611a72576040805162461bcd60e51b815260206004820152600c60248201526b61646472657373207a65726f60a01b604482015290519081900360640190fd5b95945050505050565b7f714f205b2abd25bef1d06a1af944e38c113fe6160375c4e1d6d5cf28848e771955565b611acb82826040518060400160405280600981526020016824b7333630ba34b7b760b91b81525061194e565b600a80546001600160a01b0319166001600160a01b03929092169190911790555050565b6001820154600090600160401b900467ffffffffffffffff1680611b1757600091505061123b565b4383101580611b4a57506000198101600090815260208590526040902054600160c01b900467ffffffffffffffff168310155b15611b7257600019016000908152602084905260409020546001600160c01b0316905061123b565b600184015467ffffffffffffffff9081166000818152602087905260409020549091600160c01b90910416841015611bec578015611be15760405162461bcd60e51b81526004018080602001828103825260308152602001806120286030913960400191505060405180910390fd5b60009250505061123b565b6001850154600090611c139087908490600160401b900467ffffffffffffffff1688611e38565b6000908152602087905260409020546001600160c01b0316935050505092915050565b80611c6c6005547f0000000000000000000000000000000000000000dbb8481a7362102da00000006111df90919063ffffffff16565b1015611c7457fe5b611c7d81611df8565b600554611c8a908261128a565b60055550565b60095460005b81811015611d4f5760098181548110611cab57fe5b60009182526020909120600490910201546001600160a01b0384811691161415611d4757604080518082018252601881527f746f6b656e20706f6f6c20616c726561647920616464656400000000000000006020808301918252925162461bcd60e51b81526004810193845282516024820152825192939283926044909201919080838360008315610768578181015183820152602001610750565b600101611c96565b5060098054600101808255600082905283919083908110611d6c57fe5b6000918252602090912060049091020180546001600160a01b0319166001600160a01b03929092169190911790555050565b6000600160c01b82106114f5576040805162461bcd60e51b815260206004820152601d60248201527f76616c756520646f65736e27742066697420696e203139322062697473000000604482015290519081900360640190fd5b610c2261176482611e096002611241565b9061128a565b600b546001600160a01b0382163190611e3290611e2d9083906111df565b611753565b600b5550565b60008381611e478560016111df565b90505b81811115611eb3576000611e6e6002611e686001611e09868861128a565b90611ebd565b600081815260208a90526040902054909150600160c01b900467ffffffffffffffff168510611e9f57809250611ead565b611eaa8160016111df565b91505b50611e4a565b5095945050505050565b6000808211611f13576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381611f1c57fe5b049392505050565b50805460018160011615610100020316600290046000825580601f10611f4a5750610c22565b601f016020900490600052602060002090810190610c229190611fec565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282611f9e5760008555611fe4565b82601f10611fb757805160ff1916838001178555611fe4565b82800160010185558215611fe4579182015b82811115611fe4578251825591602001919060010190611fc9565b506114f59291505b5b808211156114f55760008155600101611fed56fe53616665436173743a2076616c756520646f65736e27742066697420696e2036342062697473436865636b506f696e74486973746f72793a2072656164696e672066726f6d20636c65616e65642d757020626c6f636ba2646970667358221220aaf4c1eb2a9a67dcf6d9cd51620eb7944fc17609f87f60d10d6d6084d54ba66e64736f6c63430007060033