false
false
0

Contract Address Details

0x1000000000000000000000000000000000000004

Contract Name
DistributionTreasury
Creator
Balance
0 FLR ( )
Tokens
Fetching tokens...
Transactions
8 Transactions
Transfers
0 Transfers
Gas Used
272,942
Last Balance Update
21701733
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
DistributionTreasury




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




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

./contracts/genesis/implementation/DistributionTreasury.sol

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

import "../../governance/implementation/GovernedAtGenesis.sol";


/**
 * @title Distribution treasury
 * @notice A genesis contract used to hold funds until the distribution plan is chosen.
 */
contract DistributionTreasury is GovernedAtGenesis {

    // How often can the distribution contract pull funds - 29 days constant
    uint256 internal constant MAX_PULL_FREQUENCY_SEC = 29 days;
    uint256 public constant MAX_PULL_AMOUNT_WEI = 725000000 ether;

    // Errors
    string internal constant ERR_DISTRIBUTION_ONLY = "distribution only";
    string internal constant ERR_TOO_OFTEN = "too often";
    string internal constant ERR_TOO_MUCH = "too much";
    string internal constant ERR_SEND_FUNDS_FAILED = "send funds failed";
    string internal constant ERR_ALREADY_SET = "already set";
    string internal constant ERR_WRONG_ADDRESS = "wrong address";
    string internal constant ERR_ADDRESS_ZERO = "address zero";

    // Storage
    address public selectedDistribution;
    address public initialDistribution;
    address public distributionToDelegators;
    uint256 public lastPullTs;


    modifier onlyDistributionToDelegators {
        require (msg.sender == selectedDistribution && msg.sender == distributionToDelegators, ERR_DISTRIBUTION_ONLY);
        _;
    }

    /**
     * @dev This constructor should contain no code as this contract is pre-loaded into the genesis block.
     *   The super constructor is called for testing convenience.
     */
    constructor() GovernedAtGenesis(address(0)) {
        /* empty block */
    }

    /**
     * @notice Sets both distribution contract addresses.
     * @param _initialDistribution          Initial distribution contract address.
     * @param _distributionToDelegators     Distribution to delegators contracts address.
     */
    function setContracts(address _initialDistribution, address _distributionToDelegators) external onlyGovernance {
        require(initialDistribution == address(0) && distributionToDelegators == address(0), ERR_ALREADY_SET);
        require(_initialDistribution != address(0) && _distributionToDelegators != address(0), ERR_ADDRESS_ZERO);
        initialDistribution = _initialDistribution;
        distributionToDelegators = _distributionToDelegators;
    }

    /**
     * @notice Selects one of the two distribution contracts
     * @param _selectedDistribution         Selected distribution contract address.
     */
    function selectDistributionContract(address _selectedDistribution) external onlyGovernance {
        require(selectedDistribution == address(0), ERR_ALREADY_SET);
        require(_selectedDistribution == initialDistribution || _selectedDistribution == distributionToDelegators, 
            ERR_WRONG_ADDRESS);
        selectedDistribution = _selectedDistribution;
        if (_selectedDistribution == initialDistribution) {
            // send funds
            _sendFunds(_selectedDistribution, address(this).balance);
        }
    }

    /**
     * @notice Moves funds to the distribution contract (once per month)
     * @param _amountWei   The amount of wei to pull to distribution contract
     */
    function pullFunds(uint256 _amountWei) external onlyDistributionToDelegators {
        // this also serves as reentrancy guard, since any re-entry will happen in the same block
        require(lastPullTs + MAX_PULL_FREQUENCY_SEC <= block.timestamp, ERR_TOO_OFTEN);
        require(_amountWei <= MAX_PULL_AMOUNT_WEI, ERR_TOO_MUCH);
        lastPullTs = block.timestamp;
        _sendFunds(msg.sender, _amountWei);
    }

    function _sendFunds(address _recipient, uint256 _amountWei) internal {
        /* solhint-disable avoid-low-level-calls */
        //slither-disable-next-line arbitrary-send
        (bool success, ) = _recipient.call{value: _amountWei}("");
        /* solhint-enable avoid-low-level-calls */
        require(success, ERR_SEND_FUNDS_FAILED);
    }
}
        

./contracts/governance/implementation/GovernedAtGenesis.sol

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

import "./GovernedBase.sol";


/**
 * @title Governed At Genesis
 * @dev This contract enforces a fixed governance address when the constructor
 *  is not executed on a contract (for instance when directly loaded to the genesis block).
 *  This is required to fix governance on a contract when the network starts, at such point
 *  where theoretically no accounts yet exist, and leaving it ungoverned could result in a race
 *  to claim governance by an unauthorized address.
 **/
contract GovernedAtGenesis is GovernedBase {
    constructor(address _governance) GovernedBase(_governance) { }

    /**
     * @notice Set governance to a fixed address when constructor is not called.
     **/
    function initialiseFixedAddress() public virtual returns (address) {
        address governanceAddress = address(0xfffEc6C83c8BF5c3F4AE0cCF8c45CE20E4560BD7);
        
        super.initialise(governanceAddress);
        return governanceAddress;
    }

    /**
     * @notice Disallow initialise to be called
     * @param _governance The governance address for initial claiming
     **/
    // solhint-disable-next-line no-unused-vars
    function initialise(address _governance) public override pure {
        assert(false);
    }
}
          

./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/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);
}
          

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"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":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_PULL_AMOUNT_WEI","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cancelGovernanceCall","inputs":[{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"distributionToDelegators","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"executeGovernanceCall","inputs":[{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"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":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"initialDistribution","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[],"name":"initialise","inputs":[{"type":"address","name":"_governance","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"initialiseFixedAddress","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastPullTs","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"productionMode","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"pullFunds","inputs":[{"type":"uint256","name":"_amountWei","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"selectDistributionContract","inputs":[{"type":"address","name":"_selectedDistribution","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"selectedDistribution","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setContracts","inputs":[{"type":"address","name":"_initialDistribution","internalType":"address"},{"type":"address","name":"_distributionToDelegators","internalType":"address"}]},{"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"}]}]
              

Deployed ByteCode

0x608060405234801561001057600080fd5b506004361061010b5760003560e01c806375a0fef9116100a2578063d8952a4911610071578063d8952a491461029a578063e17f212e146102c8578063e1a1a5dc146102e4578063ec8d87771461030a578063f5a98383146103275761010b565b806375a0fef91461025c57806395645e34146102645780639d6a890f1461026c578063c9f960eb146102925761010b565b8063616d7c9f116100de578063616d7c9f1461017f57806362354e031461018757806367fc40291461018f57806374e6310e146101b65761010b565b8063100223bb1461011057806329d71f6d1461012a5780635aa6e675146101325780635ff2707914610156575b600080fd5b61011861032f565b60408051918252519081900360200190f35b610118610335565b61013a610345565b604080516001600160a01b039092168252519081900360200190f35b61017d6004803603602081101561016c57600080fd5b50356001600160e01b0319166103da565b005b61013a61072f565b61013a61073e565b61017d600480360360208110156101a557600080fd5b50356001600160e01b031916610749565b6101dd600480360360208110156101cc57600080fd5b50356001600160e01b031916610831565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610220578181015183820152602001610208565b50505050905090810190601f16801561024d5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b61013a6108d7565b61013a6108e6565b61017d6004803603602081101561028257600080fd5b50356001600160a01b03166108f5565b61013a6108fa565b61017d600480360360408110156102b057600080fd5b506001600160a01b038135811691602001351661091a565b6102d0610aef565b604080519115158252519081900360200190f35b61017d600480360360208110156102fa57600080fd5b50356001600160a01b0316610aff565b61017d6004803603602081101561032057600080fd5b5035610c8b565b61017d610e29565b60055481565b6b0257b4b8c0aa5cf8f500000081565b60008054600160a81b900460ff16610368576000546001600160a01b03166103d5565b60076001609c1b016001600160a01b031663732524946040518163ffffffff1660e01b815260040160206040518083038186803b1580156103a857600080fd5b505afa1580156103bc573d6000803e3d6000fd5b505050506040513d60208110156103d257600080fd5b50515b905090565b60408051630debfda360e41b8152336004820152905160076001609c1b019163debfda30916024808301926020929190829003018186803b15801561041e57600080fd5b505afa158015610432573d6000803e3d6000fd5b505050506040513d602081101561044857600080fd5b505161048b576040805162461bcd60e51b815260206004820152600d60248201526c37b7363c9032bc32b1baba37b960991b604482015290519081900360640190fd5b6001600160e01b03198116600090815260016020526040902080546104f7576040805162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f72000000000000604482015290519081900360640190fd5b805442101561054d576040805162461bcd60e51b815260206004820152601960248201527f74696d656c6f636b3a206e6f7420616c6c6f7765642079657400000000000000604482015290519081900360640190fd5b6000816001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105e75780601f106105bc576101008083540402835291602001916105e7565b820191906000526020600020905b8154815290600101906020018083116105ca57829003601f168201915b5050506001600160e01b031986166000908152600160208190526040822082815594955090925061061b915083018261129d565b50506000805460ff60b01b1916600160b01b178155604051825130918491819060208401908083835b602083106106635780518252601f199092019160209182019101610644565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146106c5576040519150601f19603f3d011682016040523d82523d6000602084013e6106ca565b606091505b50506000805460ff60b01b19169055604080516001600160e01b03198716815242602082015281519293507fa7326b57fc9cfe267aaea5e7f0b01757154d265620a0585819416ee9ddd2c438929081900390910190a161072981610ee3565b50505050565b6004546001600160a01b031681565b60076001609c1b0181565b610751610f00565b6001600160e01b031981166000908152600160205260409020546107bc576040805162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f72000000000000604482015290519081900360640190fd5b604080516001600160e01b03198316815242602082015281517f7735b2391c38a81419c513e30ca578db7158eadd7101511b23e221c654d19cf8929181900390910190a16001600160e01b0319811660009081526001602081905260408220828155919061082c9083018261129d565b505050565b600160208181526000928352604092839020805481840180548651600296821615610100026000190190911695909504601f810185900485028601850190965285855290949193929091908301828280156108cd5780601f106108a2576101008083540402835291602001916108cd565b820191906000526020600020905b8154815290600101906020018083116108b057829003601f168201915b5050505050905082565b6002546001600160a01b031681565b6003546001600160a01b031681565bfe5b50565b600073fffec6c83c8bf5c3f4ae0ccf8c45ce20e4560bd76103d581610f61565b600054600160b01b900460ff168061093c5750600054600160a81b900460ff16155b15610ae05761094961101a565b6003546001600160a01b031615801561096b57506004546001600160a01b0316155b6040518060400160405280600b81526020016a185b1c9958591e481cd95d60aa1b81525090610a185760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156109dd5781810151838201526020016109c5565b50505050905090810190601f168015610a0a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506001600160a01b03821615801590610a3957506001600160a01b03811615155b6040518060400160405280600c81526020016b61646472657373207a65726f60a01b81525090610aaa5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156109dd5781810151838201526020016109c5565b50600380546001600160a01b038085166001600160a01b0319928316179092556004805492841692909116919091179055610aeb565b610aeb60003661104f565b5050565b600054600160a81b900460ff1681565b600054600160b01b900460ff1680610b215750600054600160a81b900460ff16155b15610c8057610b2e61101a565b60025460408051808201909152600b81526a185b1c9958591e481cd95d60aa1b6020820152906001600160a01b031615610ba95760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156109dd5781810151838201526020016109c5565b506003546001600160a01b0382811691161480610bd357506004546001600160a01b038281169116145b6040518060400160405280600d81526020016c77726f6e67206164647265737360981b81525090610c455760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156109dd5781810151838201526020016109c5565b50600280546001600160a01b0319166001600160a01b038381169182179092556003549091161415610c7b57610c7b81476111d2565b6108f7565b6108f760003661104f565b6002546001600160a01b031633148015610caf57506004546001600160a01b031633145b60405180604001604052806011815260200170646973747269627574696f6e206f6e6c7960781b81525090610d255760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156109dd5781810151838201526020016109c5565b504262263b80600554011115604051806040016040528060098152602001683a37b79037b33a32b760b91b81525090610d9f5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156109dd5781810151838201526020016109c5565b506040805180820190915260088152670e8dede40daeac6d60c31b60208201526b0257b4b8c0aa5cf8f5000000821115610e1a5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156109dd5781810151838201526020016109c5565b50426005556108f733826111d2565b610e31610f00565b600054600160a81b900460ff1615610e90576040805162461bcd60e51b815260206004820152601a60248201527f616c726561647920696e2070726f64756374696f6e206d6f6465000000000000604482015290519081900360640190fd5b60008054600161ff0160a01b031916600160a81b1790556040805160076001609c1b01815290517f83af113638b5422f9e977cebc0aaf0eaf2188eb9a8baae7f9d46c42b33a1560c9181900360200190a1565b3d604051818101604052816000823e8215610efc578181f35b8181fd5b610f08610345565b6001600160a01b0316336001600160a01b031614610f5f576040805162461bcd60e51b815260206004820152600f60248201526e6f6e6c7920676f7665726e616e636560881b604482015290519081900360640190fd5b565b600054600160a01b900460ff1615610fb7576040805162461bcd60e51b8152602060048201526014602482015273696e697469616c6973656420213d2066616c736560601b604482015290519081900360640190fd5b60008054600160a01b60ff60a01b19909116176001600160a01b0319166001600160a01b03831690811790915560408051918252517f9789733827840833afc031fb2ef9ab6894271f77bad2085687cf4ae5c7bee4db916020908290030190a150565b600054600160b01b900460ff16156110475733301461103557fe5b6000805460ff60b01b19169055610f5f565b610f5f610f00565b611057610f00565b600082359050600060076001609c1b016001600160a01b0316636221a54b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561109f57600080fd5b505afa1580156110b3573d6000803e3d6000fd5b505050506040513d60208110156110c957600080fd5b505160408051808201825242830180825282516020601f89018190048102820181019094528781529394509290918281019190889088908190840183828082843760009201829052509390945250506001600160e01b0319861681526001602081815260409092208451815584830151805191945061114d939285019201906112e1565b509050507fed948300a3694aa01d4a6b258bfd664350193d770c0b51f8387277f6d83ea3b68382878760405180856001600160e01b0319168152602001848152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f191690920182900397509095505050505050a15050505050565b6040516000906001600160a01b0384169083908381818185875af1925050503d806000811461121d576040519150601f19603f3d011682016040523d82523d6000602084013e611222565b606091505b5050905080604051806040016040528060118152602001701cd95b9908199d5b991cc819985a5b1959607a1b815250906107295760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156109dd5781810151838201526020016109c5565b50805460018160011615610100020316600290046000825580601f106112c357506108f7565b601f0160209004906000526020600020908101906108f7919061136d565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282611317576000855561135d565b82601f1061133057805160ff191683800117855561135d565b8280016001018555821561135d579182015b8281111561135d578251825591602001919060010190611342565b5061136992915061136d565b5090565b5b80821115611369576000815560010161136e56fea264697066735822122023f7cb20d6e161023a579061b9301b398dd68992257d7ca8390e83d839609dd764736f6c63430007060033