ETH Price: $2,341.81 (-1.27%)

Contract

0x09959798B95d00a3183d20FaC298E4594E599eab
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x60806040108341032020-09-10 12:49:131484 days ago1599742153IN
 Create: KeepRandomBeaconServiceImplV1
0 ETH0.28557585150

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
KeepRandomBeaconServiceImplV1

Compiler Version
v0.5.17+commit.d19bba13

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license
File 1 of 7 : KeepRandomBeaconServiceImplV1.sol
/**
▓▓▌ ▓▓ ▐▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄
▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  ▓▓▓▓▓▓    ▓▓▓▓▓▓▓▀    ▐▓▓▓▓▓▓    ▐▓▓▓▓▓   ▓▓▓▓▓▓     ▓▓▓▓▓   ▐▓▓▓▓▓▌   ▐▓▓▓▓▓▓
  ▓▓▓▓▓▓▄▄▓▓▓▓▓▓▓▀      ▐▓▓▓▓▓▓▄▄▄▄         ▓▓▓▓▓▓▄▄▄▄         ▐▓▓▓▓▓▌   ▐▓▓▓▓▓▓
  ▓▓▓▓▓▓▓▓▓▓▓▓▓▀        ▐▓▓▓▓▓▓▓▓▓▓         ▓▓▓▓▓▓▓▓▓▓▌        ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  ▓▓▓▓▓▓▀▀▓▓▓▓▓▓▄       ▐▓▓▓▓▓▓▀▀▀▀         ▓▓▓▓▓▓▀▀▀▀         ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▀
  ▓▓▓▓▓▓   ▀▓▓▓▓▓▓▄     ▐▓▓▓▓▓▓     ▓▓▓▓▓   ▓▓▓▓▓▓     ▓▓▓▓▓   ▐▓▓▓▓▓▌
▓▓▓▓▓▓▓▓▓▓ █▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  ▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  ▓▓▓▓▓▓▓▓▓▓

                           Trust math, not hardware.
*/

pragma solidity 0.5.17;

import "openzeppelin-solidity/contracts/math/SafeMath.sol";
import "openzeppelin-solidity/contracts/utils/ReentrancyGuard.sol";
import "./utils/AddressArrayUtils.sol";
import "./utils/PercentUtils.sol";
import "./KeepRegistry.sol";
import "./IRandomBeacon.sol";


interface OperatorContract {
    function entryVerificationFee() external view returns(uint256);
    function groupCreationFee() external view returns(uint256);
    function groupProfitFee() external view returns(uint256);
    function gasPriceCeiling() external view returns(uint256);
    function sign(
        uint256 requestId,
        bytes calldata previousEntry
    ) external payable;
    function numberOfGroups() external view returns(uint256);
    function createGroup(uint256 newEntry, address payable submitter) external payable;
    function isGroupSelectionPossible() external view returns (bool);
}

/// @title KeepRandomBeaconServiceImplV1
/// @notice Initial version of service contract that works under Keep Random
/// Beacon proxy and allows upgradability. The purpose of the contract is to have
/// up-to-date logic for threshold random number generation. Updated contracts
/// must inherit from this contract and have to be initialized under updated version
/// name.
/// @dev Warning: you can't set constants directly in the contract and must use
/// initialize() please see openzeppelin upgradeable contracts approach for more
/// info.
contract KeepRandomBeaconServiceImplV1 is ReentrancyGuard, IRandomBeacon {
    using SafeMath for uint256;
    using PercentUtils for uint256;
    using AddressArrayUtils for address[];

    event RelayEntryRequested(uint256 requestId);

    /// @dev Fraction in % of the estimated cost of DKG that is included
    /// in relay request fee.
    uint256 internal _dkgContributionMargin;

    /// @dev Every relay request payment includes DKG contribution that is added to
    /// the DKG fee pool, once the pool value reaches the required minimum, a new
    /// relay entry will trigger the creation of a new group. Expressed in wei.
    uint256 internal _dkgFeePool;

    /// @dev Rewards not paid out to the operators are sent to request subsidy pool to
    /// subsidize new requests: 1% of the subsidy pool is returned to the requester's
    /// surplus address. Expressed in wei.
    uint256 internal _requestSubsidyFeePool;

    /// @dev Each service contract tracks its own requests and these are independent
    /// from operator contracts which track signing requests instead.
    uint256 internal _requestCounter;

    /// @dev Previous entry value produced by the beacon.
    bytes internal _previousEntry;

    /// @dev The cost of executing executeCallback() code of this contract, includes
    /// everything but the logic of the external contract called.
    /// The value is used to estimate the cost of executing a callback and is
    /// used for calculating callback call surplus reimbursement for requestor.
    ///
    /// This value has to be updated in case of EVM opcode price change, but since
    /// upgrading service contract is easy, it is not a worrisome problem.
    uint256 internal _baseCallbackGas;

    struct Callback {
        address callbackContract;
        uint256 callbackFee;
        uint256 callbackGas;
        address payable surplusRecipient;
    }

    mapping(uint256 => Callback) internal _callbacks;

    /// @dev KeepRegistry contract with a list of approved operator contracts and upgraders.
    address internal _registry;

    address[] internal _operatorContracts;

    /// @dev Mapping to store new implementation versions that inherit from this contract.
    mapping (string => bool) internal _initialized;

    /// @dev Seed used as the first random beacon value.
    /// It's a G1 point G * PI =
    /// G * 31415926535897932384626433832795028841971693993751058209749445923078164062862
    /// Where G is the generator of G1 abstract cyclic group.
    bytes constant internal _beaconSeed =
    hex"15c30f4b6cf6dbbcbdcc10fe22f54c8170aea44e198139b776d512d8f027319a1b9e8bfaf1383978231ce98e42bafc8129f473fc993cf60ce327f7d223460663";

    /// @dev Throws if called by any account other than the operator contract
    /// upgrader authorized for this service contract.
    modifier onlyOperatorContractUpgrader() {
        address operatorContractUpgrader = KeepRegistry(_registry).operatorContractUpgraderFor(address(this));
        require(operatorContractUpgrader == msg.sender, "Caller is not operator contract upgrader");
        _;
    }

    constructor() public {
        _initialized["KeepRandomBeaconServiceImplV1"] = true;
    }

    /// @notice Initialize Keep Random Beacon service contract implementation.
    /// @param dkgContributionMargin Fraction in % of the estimated cost of DKG that is included in relay
    /// request fee.
    /// @param registry KeepRegistry contract linked to this contract.
    function initialize(
        uint256 dkgContributionMargin,
        address registry
    )
        public
    {
        require(!initialized(), "Contract is already initialized.");
        require(registry != address(0), "Incorrect registry address");

        _initialized["KeepRandomBeaconServiceImplV1"] = true;
        _dkgContributionMargin = dkgContributionMargin;
        _previousEntry = _beaconSeed;
        _registry = registry;
        _baseCallbackGas = 10226;
    }

    /// @notice Checks if this contract is initialized.
    function initialized() public view returns (bool) {
        return _initialized["KeepRandomBeaconServiceImplV1"];
    }

    /// @notice Adds operator contract
    /// @param operatorContract Address of the operator contract.
    function addOperatorContract(address operatorContract) public onlyOperatorContractUpgrader {
        require(
            KeepRegistry(_registry).isApprovedOperatorContract(operatorContract),
            "Operator contract is not approved"
        );
        _operatorContracts.push(operatorContract);
    }

    /// @notice Removes operator contract
    /// @param operatorContract Address of the operator contract.
    function removeOperatorContract(address operatorContract) public onlyOperatorContractUpgrader {
        _operatorContracts.removeAddress(operatorContract);
    }

    /// @notice Add funds to DKG fee pool.
    function fundDkgFeePool() public payable {
        _dkgFeePool += msg.value;
    }

    /// @notice Add funds to request subsidy fee pool.
    function fundRequestSubsidyFeePool() public payable {
        _requestSubsidyFeePool += msg.value;
    }

    /// @notice Selects an operator contract from the available list using modulo
    /// operation with seed value weighted by the number of active groups on each
    /// operator contract.
    /// @param seed Cryptographically generated random value.
    /// @return Address of operator contract.
    function selectOperatorContract(uint256 seed) public view returns (address) {

        uint256 totalNumberOfGroups;

        uint256 approvedContractsCounter;
        address[] memory approvedContracts = new address[](_operatorContracts.length);

        for (uint i = 0; i < _operatorContracts.length; i++) {
            if (KeepRegistry(_registry).isApprovedOperatorContract(_operatorContracts[i])) {
                totalNumberOfGroups += OperatorContract(_operatorContracts[i]).numberOfGroups();
                approvedContracts[approvedContractsCounter] = _operatorContracts[i];
                approvedContractsCounter++;
            }
        }

        require(totalNumberOfGroups > 0, "Total number of groups must be greater than zero.");

        uint256 selectedIndex = seed % totalNumberOfGroups;

        uint256 selectedContract;
        uint256 indexByGroupCount;

        for (uint256 i = 0; i < approvedContractsCounter; i++) {
            indexByGroupCount += OperatorContract(approvedContracts[i]).numberOfGroups();
            if (selectedIndex < indexByGroupCount) {
                return approvedContracts[selectedContract];
            }
            selectedContract++;
        }

        return approvedContracts[selectedContract];
    }

    /// @notice Creates a request to generate a new relay entry, which will include
    /// a random number (by signing the previous entry's random number).
    /// @return An uint256 representing uniquely generated entry Id.
    function requestRelayEntry() public payable returns (uint256) {
        return requestRelayEntry(address(0), 0);
    }

    /// @notice Creates a request to generate a new relay entry (random number).
    /// @param callbackContract Callback contract address. Callback is called
    /// once a new relay entry has been generated. Callback contract must
    /// declare public `__beaconCallback(uint256)` function that is going to be
    /// executed with the result, once ready.
    /// @param callbackGas Gas required for the callback (2 million gas max).
    /// The customer needs to ensure they provide a sufficient callback gas
    /// to cover the gas fee of executing the callback. Any surplus is returned
    /// to the customer. If the callback gas amount turns to be not enough to
    /// execute the callback, callback execution is skipped.
    /// @return An uint256 representing uniquely generated relay request ID. It
    /// is also returned as part of the event.
    function requestRelayEntry(
        address callbackContract,
        uint256 callbackGas
    ) public nonReentrant payable returns (uint256) {
        require(
            callbackGas <= 2000000,
            "Callback gas exceeds 2000000 gas limit"
        );

        require(
            msg.value >= entryFeeEstimate(callbackGas),
            "Payment is less than required minimum."
        );

        (
            uint256 entryVerificationFee,
            uint256 dkgContributionFee,
            uint256 groupProfitFee,
            uint256 gasPriceCeiling
        ) = entryFeeBreakdown();

        uint256 callbackFee = msg.value.sub(entryVerificationFee)
            .sub(dkgContributionFee).sub(groupProfitFee);

        _dkgFeePool += dkgContributionFee;

        OperatorContract operatorContract = OperatorContract(
            selectOperatorContract(uint256(keccak256(_previousEntry)))
        );

        uint256 selectedOperatorContractFee = operatorContract.groupProfitFee().add(
            operatorContract.entryVerificationFee()
        );

        _requestCounter++;
        uint256 requestId = _requestCounter;

        operatorContract.sign.value(
            selectedOperatorContractFee.add(callbackFee)
        )(requestId, _previousEntry);

        // If selected operator contract is cheaper than expected return the
        // surplus to the subsidy fee pool.
        // We do that instead of returning the surplus to the requestor to have
        // a consistent beacon pricing for customers without fluctuations caused
        // by different operator contracts being selected.
        uint256 surplus = entryVerificationFee.add(groupProfitFee).sub(selectedOperatorContractFee);
        _requestSubsidyFeePool = _requestSubsidyFeePool.add(surplus);

        if (callbackContract != address(0)) {
            _callbacks[requestId] = Callback(callbackContract, callbackFee, callbackGas, msg.sender);
        }

        // Send 1% of the request subsidy pool to the requestor.
        if (_requestSubsidyFeePool >= 100) {
            uint256 amount = _requestSubsidyFeePool.percent(1);
            _requestSubsidyFeePool -= amount;
            (bool success, ) = msg.sender.call.value(amount)("");
            require(success, "Failed send subsidy fee");
        }

        emit RelayEntryRequested(requestId);
        return requestId;
    }

    /// @notice Store valid entry returned by operator contract and call customer
    /// specified callback if required.
    /// @param requestId Request id tracked internally by this contract.
    /// @param entry The generated random number.
    /// @param submitter Relay entry submitter.
    function entryCreated(uint256 requestId, bytes memory entry, address payable submitter) public {
        require(
            _operatorContracts.contains(msg.sender),
            "Only authorized operator contract can call relay entry."
        );

        _previousEntry = entry;
        uint256 entryAsNumber = uint256(keccak256(entry));
        emit RelayEntryGenerated(requestId, entryAsNumber);

        createGroupIfApplicable(entryAsNumber, submitter);
    }

    /// @notice Executes customer specified callback for the relay entry request.
    /// @param requestId Request id tracked internally by this contract.
    /// @param entry The generated random number.
    function executeCallback(uint256 requestId, uint256 entry) public {
        require(
            _operatorContracts.contains(msg.sender),
            "Only authorized operator contract can call execute callback."
        );

        require(
            _callbacks[requestId].callbackContract != address(0),
            "Callback contract not found"
        );

        _callbacks[requestId].callbackContract.call(
            abi.encodeWithSignature("__beaconCallback(uint256)", entry)
        );

        delete _callbacks[requestId];
    }

    /// @notice Triggers the selection process of a new candidate group if the
    /// DKG fee pool equals or exceeds DKG cost estimate.
    /// @param entry The generated random number.
    /// @param submitter Relay entry submitter - operator.
    function createGroupIfApplicable(uint256 entry, address payable submitter) internal {
        address latestOperatorContract = _operatorContracts[_operatorContracts.length.sub(1)];
        uint256 groupCreationFee = OperatorContract(latestOperatorContract).groupCreationFee();

        if (_dkgFeePool >= groupCreationFee && OperatorContract(latestOperatorContract).isGroupSelectionPossible()) {
            OperatorContract(latestOperatorContract).createGroup.value(groupCreationFee)(entry, submitter);
            _dkgFeePool = _dkgFeePool.sub(groupCreationFee);
        }
    }

    /// @notice Get base callback gas required for relay entry callback.
    function baseCallbackGas() public view returns(uint256) {
        return _baseCallbackGas;
    }

    /// @notice Get the minimum payment in wei for relay entry callback.
    /// @param _callbackGas Gas required for the callback.
    function callbackFee(
        uint256 _callbackGas,
        uint256 _gasPriceCeiling
    ) internal view returns(uint256) {
        // gas for the callback itself plus additional operational costs of
        // executing the callback
        uint256 callbackGas = _callbackGas == 0 ? 0 : _callbackGas.add(_baseCallbackGas);
        // We take the gas price from the price feed to not let malicious
        // miner-requestors manipulate the gas price when requesting relay entry
        // and underpricing expensive callbacks.
        return callbackGas.mul(_gasPriceCeiling);
    }

    /// @notice Get the entry fee estimate in wei for relay entry request.
    /// @param callbackGas Gas required for the callback.
    function entryFeeEstimate(uint256 callbackGas) public view returns(uint256) {
        require(
            callbackGas <= 2000000,
            "Callback gas exceeds 2000000 gas limit"
        );

        (
            uint256 entryVerificationFee,
            uint256 dkgContributionFee,
            uint256 groupProfitFee,
            uint256 gasPriceCeiling
        ) = entryFeeBreakdown();

        return entryVerificationFee
            .add(dkgContributionFee)
            .add(groupProfitFee)
            .add(callbackFee(callbackGas, gasPriceCeiling));
    }

    /// @notice Get the entry fee breakdown in wei for relay entry request.
    function entryFeeBreakdown() public view returns(
        uint256 entryVerificationFee,
        uint256 dkgContributionFee,
        uint256 groupProfitFee,
        uint256 gasPriceCeiling
    ) {
        // Select the most expensive entry verification from all the operator contracts
        // and the highest group profit fee from all the operator contracts. We do not
        // know what is going to be the gas price at the moment of submitting an entry,
        // thus we can't calculate at this point which contract is the most expensive
        // based on the entry verification gas and group profit fee. Hence, we need to
        // select maximum of both those values separately.
        for (uint i = 0; i < _operatorContracts.length; i++) {
            OperatorContract operator = OperatorContract(_operatorContracts[i]);

            if (operator.numberOfGroups() > 0) {
                uint256 operatorBid = operator.entryVerificationFee();
                if (operatorBid > entryVerificationFee) {
                    entryVerificationFee = operatorBid;
                }

                operatorBid = operator.groupProfitFee();
                if (operatorBid > groupProfitFee) {
                    groupProfitFee = operatorBid;
                }

                operatorBid = operator.gasPriceCeiling();
                if (operatorBid > gasPriceCeiling) {
                    gasPriceCeiling = operatorBid;
                }
            }
        }

        // Use DKG gas estimate from the latest operator contract since it will be used for the next group creation.
        address latestOperatorContract = _operatorContracts[_operatorContracts.length.sub(1)];
        uint256 groupCreationFee = OperatorContract(latestOperatorContract).groupCreationFee();

        return (
            entryVerificationFee,
            groupCreationFee.percent(_dkgContributionMargin),
            groupProfitFee,
            gasPriceCeiling
        );
    }

    /// @notice Returns DKG contribution margin - a fraction in % of the
    /// estimated cost of DKG that is included in relay request fee.
    function dkgContributionMargin() public view returns(uint256) {
        return _dkgContributionMargin;
    }

    /// @notice Returns the current DKG fee pool value.
    /// Every relay request payment includes DKG contribution that is added to
    /// the DKG fee pool, once the pool value reaches the required minimum, a new
    /// relay entry will trigger the creation of a new group. Expressed in wei.
    function dkgFeePool() public view returns(uint256) {
        return _dkgFeePool;
    }

    /// @notice Returns the current value of request subsidy pool.
    /// Rewards not paid out to the operators are sent to request subsidy pool to
    /// subsidize new requests: 1% of the subsidy pool is returned to the requester's
    /// surplus address. Expressed in wei.
    function requestSubsidyFeePool() public view returns(uint256) {
        return _requestSubsidyFeePool;
    }

    /// @notice Returns callback surplus recipient for the provided request id.
    function callbackSurplusRecipient(uint256 requestId) public view returns(address payable) {
        return _callbacks[requestId].surplusRecipient;
    }

    /// @notice Gets version of the current implementation.
    function version() public pure returns (string memory) {
        return "V1";
    }
}

File 2 of 7 : IRandomBeacon.sol
/**
▓▓▌ ▓▓ ▐▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄
▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  ▓▓▓▓▓▓    ▓▓▓▓▓▓▓▀    ▐▓▓▓▓▓▓    ▐▓▓▓▓▓   ▓▓▓▓▓▓     ▓▓▓▓▓   ▐▓▓▓▓▓▌   ▐▓▓▓▓▓▓
  ▓▓▓▓▓▓▄▄▓▓▓▓▓▓▓▀      ▐▓▓▓▓▓▓▄▄▄▄         ▓▓▓▓▓▓▄▄▄▄         ▐▓▓▓▓▓▌   ▐▓▓▓▓▓▓
  ▓▓▓▓▓▓▓▓▓▓▓▓▓▀        ▐▓▓▓▓▓▓▓▓▓▓         ▓▓▓▓▓▓▓▓▓▓▌        ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  ▓▓▓▓▓▓▀▀▓▓▓▓▓▓▄       ▐▓▓▓▓▓▓▀▀▀▀         ▓▓▓▓▓▓▀▀▀▀         ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▀
  ▓▓▓▓▓▓   ▀▓▓▓▓▓▓▄     ▐▓▓▓▓▓▓     ▓▓▓▓▓   ▓▓▓▓▓▓     ▓▓▓▓▓   ▐▓▓▓▓▓▌
▓▓▓▓▓▓▓▓▓▓ █▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  ▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  ▓▓▓▓▓▓▓▓▓▓

                           Trust math, not hardware.
*/

pragma solidity 0.5.17;


/// @title Keep Random Beacon
///
/// @notice Keep Random Beacon generates verifiable randomness that is resistant
/// to bad actors both in the relay network and on the anchoring blockchain.
interface IRandomBeacon {
    /// @notice Event emitted for each new relay entry generated. It contains
    /// request ID allowing to associate the generated relay entry with relay
    /// request created previously with `requestRelayEntry` function. Event is
    /// emitted no matter if callback was executed or not.
    ///
    /// @param requestId Relay request ID for which entry was generated.
    /// @param entry Generated relay entry.
    event RelayEntryGenerated(uint256 requestId, uint256 entry);

    /// @notice Provides the customer with an estimated entry fee in wei to use
    /// in the request. The fee estimate is only valid for the transaction it is
    /// called in, so the customer must make the request immediately after
    /// obtaining the estimate. Insufficient payment will lead to the request
    /// being rejected and the transaction reverted.
    ///
    /// The customer may decide to provide more ether for an entry fee than
    /// estimated by this function. This is especially helpful when callback gas
    /// cost fluctuates. Any surplus between the passed fee and the actual cost
    /// of producing an entry and executing a callback is returned back to the
    /// customer.
    /// @param callbackGas Gas required for the callback.
    function entryFeeEstimate(uint256 callbackGas)
        external
        view
        returns (uint256);

    /// @notice Submits a request to generate a new relay entry. Executes
    /// callback on the provided callback contract with the generated entry and
    /// emits `RelayEntryGenerated(uint256 requestId, uint256 entry)` event.
    /// Callback contract has to declare public `__beaconCallback(uint256)`
    /// function that is going to be executed with the result, once ready.
    /// It is recommended to implement `IRandomBeaconConsumer` interface to
    /// ensure the correct callback function signature.
    ///
    /// @dev Beacon does not support concurrent relay requests. No new requests
    /// should be made while the beacon is already processing another request.
    /// Requests made while the beacon is busy will be rejected and the
    /// transaction reverted.
    ///
    /// @param callbackContract Callback contract address. Callback is called
    /// once a new relay entry has been generated. Must declare public
    /// `__beaconCallback(uint256)` function. It is recommended to implement
    /// `IRandomBeaconConsumer` interface to ensure the correct callback function
    /// signature.
    /// @param callbackGas Gas required for the callback.
    /// The customer needs to ensure they provide a sufficient callback gas
    /// to cover the gas fee of executing the callback. Any surplus is returned
    /// to the customer. If the callback gas amount turns to be not enough to
    /// execute the callback, callback execution is skipped.
    /// @return An uint256 representing uniquely generated relay request ID
    function requestRelayEntry(address callbackContract, uint256 callbackGas)
        external
        payable
        returns (uint256);

    /// @notice Submits a request to generate a new relay entry. Emits
    /// `RelayEntryGenerated(uint256 requestId, uint256 entry)` event for the
    /// generated entry.
    ///
    /// @dev Beacon does not support concurrent relay requests. No new requests
    /// should be made while the beacon is already processing another request.
    /// Requests made while the beacon is busy will be rejected and the
    /// transaction reverted.
    ///
    /// @return An uint256 representing uniquely generated relay request ID
    function requestRelayEntry() external payable returns (uint256);
}


/// @title Keep Random Beacon Consumer
///
/// @notice Receives Keep Random Beacon relay entries with `__beaconCallback`
/// function. Contract implementing this interface does not have to be the one
/// requesting relay entry but it is the one receiving the requested relay entry
/// once it is produced.
///
/// @dev Use this interface to indicate the contract receives relay entries from
/// the beacon and to ensure the correctness of callback function signature.
interface IRandomBeaconConsumer {
    /// @notice Receives relay entry produced by Keep Random Beacon. This function
    /// should be called only by Keep Random Beacon.
    ///
    /// @param relayEntry Relay entry (random number) produced by Keep Random
    /// Beacon.
    function __beaconCallback(uint256 relayEntry) external;
}

File 3 of 7 : KeepRegistry.sol
pragma solidity 0.5.17;


/// @title KeepRegistry
/// @notice Governance owned registry of approved contracts and roles.
contract KeepRegistry {
    enum ContractStatus {New, Approved, Disabled}

    // Governance role is to enable recovery from key compromise by rekeying
    // other roles. Also, it can disable operator contract panic buttons
    // permanently.
    address public governance;

    // Registry Keeper maintains approved operator contracts. Each operator
    // contract must be approved before it can be authorized by a staker or
    // used by a service contract.
    address public registryKeeper;

    // Each operator contract has a Panic Button which can disable malicious
    // or malfunctioning contract that have been previously approved by the
    // Registry Keeper.
    //
    // New operator contract added to the registry has a default panic button
    // value assigned (defaultPanicButton). Panic button for each operator
    // contract can be later updated by Governance to individual value.
    //
    // It is possible to disable panic button for individual contract by
    // setting the panic button to zero address. In such case, operator contract
    // can not be disabled and is permanently approved in the registry.
    mapping(address => address) public panicButtons;

    // Default panic button for each new operator contract added to the
    // registry. Can be later updated for each contract.
    address public defaultPanicButton;

    // Each service contract has a Operator Contract Upgrader whose purpose
    // is to manage operator contracts for that specific service contract.
    // The Operator Contract Upgrader can add new operator contracts to the
    // service contract’s operator contract list, and deprecate old ones.
    mapping(address => address) public operatorContractUpgraders;

    // Operator contract may have a Service Contract Upgrader whose purpose is
    // to manage service contracts for that specific operator contract.
    // Service Contract Upgrader can add and remove service contracts
    // from the list of service contracts approved to work with the operator
    // contract. List of service contracts is maintained in the operator
    // contract and is optional - not every operator contract needs to have
    // a list of service contracts it wants to cooperate with.
    mapping(address => address) public serviceContractUpgraders;

    // The registry of operator contracts
    mapping(address => ContractStatus) public operatorContracts;

    event OperatorContractApproved(address operatorContract);
    event OperatorContractDisabled(address operatorContract);

    event GovernanceUpdated(address governance);
    event RegistryKeeperUpdated(address registryKeeper);
    event DefaultPanicButtonUpdated(address defaultPanicButton);
    event OperatorContractPanicButtonDisabled(address operatorContract);
    event OperatorContractPanicButtonUpdated(
        address operatorContract,
        address panicButton
    );
    event OperatorContractUpgraderUpdated(
        address serviceContract,
        address upgrader
    );
    event ServiceContractUpgraderUpdated(
        address operatorContract,
        address keeper
    );

    modifier onlyGovernance() {
        require(governance == msg.sender, "Not authorized");
        _;
    }

    modifier onlyRegistryKeeper() {
        require(registryKeeper == msg.sender, "Not authorized");
        _;
    }

    modifier onlyPanicButton(address _operatorContract) {
        address panicButton = panicButtons[_operatorContract];
        require(panicButton != address(0), "Panic button disabled");
        require(panicButton == msg.sender, "Not authorized");
        _;
    }

    modifier onlyForNewContract(address _operatorContract) {
        require(
            isNewOperatorContract(_operatorContract),
            "Not a new operator contract"
        );
        _;
    }

    modifier onlyForApprovedContract(address _operatorContract) {
        require(
            isApprovedOperatorContract(_operatorContract),
            "Not an approved operator contract"
        );
        _;
    }

    constructor() public {
        governance = msg.sender;
        registryKeeper = msg.sender;
        defaultPanicButton = msg.sender;
    }

    function setGovernance(address _governance) public onlyGovernance {
        governance = _governance;
        emit GovernanceUpdated(governance);
    }

    function setRegistryKeeper(address _registryKeeper) public onlyGovernance {
        registryKeeper = _registryKeeper;
        emit RegistryKeeperUpdated(registryKeeper);
    }

    function setDefaultPanicButton(address _panicButton) public onlyGovernance {
        defaultPanicButton = _panicButton;
        emit DefaultPanicButtonUpdated(defaultPanicButton);
    }

    function setOperatorContractPanicButton(
        address _operatorContract,
        address _panicButton
    ) public onlyForApprovedContract(_operatorContract) onlyGovernance {
        require(
            panicButtons[_operatorContract] != address(0),
            "Disabled panic button cannot be updated"
        );
        require(
            _panicButton != address(0),
            "Panic button must be non-zero address"
        );

        panicButtons[_operatorContract] = _panicButton;

        emit OperatorContractPanicButtonUpdated(
            _operatorContract,
            _panicButton
        );
    }

    function disableOperatorContractPanicButton(address _operatorContract)
        public
        onlyForApprovedContract(_operatorContract)
        onlyGovernance
    {
        require(
            panicButtons[_operatorContract] != address(0),
            "Panic button already disabled"
        );

        panicButtons[_operatorContract] = address(0);

        emit OperatorContractPanicButtonDisabled(_operatorContract);
    }

    function setOperatorContractUpgrader(
        address _serviceContract,
        address _operatorContractUpgrader
    ) public onlyGovernance {
        operatorContractUpgraders[_serviceContract] = _operatorContractUpgrader;
        emit OperatorContractUpgraderUpdated(
            _serviceContract,
            _operatorContractUpgrader
        );
    }

    function setServiceContractUpgrader(
        address _operatorContract,
        address _serviceContractUpgrader
    ) public onlyGovernance {
        serviceContractUpgraders[_operatorContract] = _serviceContractUpgrader;
        emit ServiceContractUpgraderUpdated(
            _operatorContract,
            _serviceContractUpgrader
        );
    }

    function approveOperatorContract(address operatorContract)
        public
        onlyForNewContract(operatorContract)
        onlyRegistryKeeper
    {
        operatorContracts[operatorContract] = ContractStatus.Approved;
        panicButtons[operatorContract] = defaultPanicButton;
        emit OperatorContractApproved(operatorContract);
    }

    function disableOperatorContract(address operatorContract)
        public
        onlyForApprovedContract(operatorContract)
        onlyPanicButton(operatorContract)
    {
        operatorContracts[operatorContract] = ContractStatus.Disabled;
        emit OperatorContractDisabled(operatorContract);
    }

    function isNewOperatorContract(address operatorContract)
        public
        view
        returns (bool)
    {
        return operatorContracts[operatorContract] == ContractStatus.New;
    }

    function isApprovedOperatorContract(address operatorContract)
        public
        view
        returns (bool)
    {
        return operatorContracts[operatorContract] == ContractStatus.Approved;
    }

    function operatorContractUpgraderFor(address _serviceContract)
        public
        view
        returns (address)
    {
        return operatorContractUpgraders[_serviceContract];
    }

    function serviceContractUpgraderFor(address _operatorContract)
        public
        view
        returns (address)
    {
        return serviceContractUpgraders[_operatorContract];
    }
}

File 4 of 7 : AddressArrayUtils.sol
pragma solidity 0.5.17;


library AddressArrayUtils {

    function contains(address[] memory self, address _address)
        internal
        pure
        returns (bool)
    {
        for (uint i = 0; i < self.length; i++) {
            if (_address == self[i]) {
                return true;
            }
        }
        return false;
    }

    function removeAddress(address[] storage self, address _addressToRemove)
        internal
        returns (address[] storage)
    {
        for (uint i = 0; i < self.length; i++) {
            // If address is found in array.
            if (_addressToRemove == self[i]) {
                // Delete element at index and shift array.
                for (uint j = i; j < self.length-1; j++) {
                    self[j] = self[j+1];
                }
                self.length--;
                i--;
            }
        }
        return self;
    }
}

File 5 of 7 : PercentUtils.sol
pragma solidity 0.5.17;

import "openzeppelin-solidity/contracts/math/SafeMath.sol";

library PercentUtils {
    using SafeMath for uint256;

    // Return `b`% of `a`
    // 200.percent(40) == 80
    // Commutative, works both ways
    function percent(uint256 a, uint256 b) internal pure returns (uint256) {
        return a.mul(b).div(100);
    }

    // Return `a` as percentage of `b`:
    // 80.asPercentOf(200) == 40
    function asPercentOf(uint256 a, uint256 b) internal pure returns (uint256) {
        return a.mul(100).div(b);
    }
}

File 6 of 7 : SafeMath.sol
pragma solidity ^0.5.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, 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) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     *
     * _Available since v2.4.0._
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @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) {
        // 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 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts 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) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message 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.
     *
     * _Available since v2.4.0._
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts 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) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message 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.
     *
     * _Available since v2.4.0._
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

File 7 of 7 : ReentrancyGuard.sol
pragma solidity ^0.5.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 */
contract ReentrancyGuard {
    // counter to allow mutex lock with only one SSTORE operation
    uint256 private _guardCounter;

    constructor () internal {
        // The counter starts at one to prevent changing it from zero to a non-zero
        // value, which is a more expensive operation.
        _guardCounter = 1;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _guardCounter += 1;
        uint256 localCounter = _guardCounter;
        _;
        require(localCounter == _guardCounter, "ReentrancyGuard: reentrant call");
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"entry","type":"uint256"}],"name":"RelayEntryGenerated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"}],"name":"RelayEntryRequested","type":"event"},{"constant":false,"inputs":[{"internalType":"address","name":"operatorContract","type":"address"}],"name":"addOperatorContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"baseCallbackGas","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"}],"name":"callbackSurplusRecipient","outputs":[{"internalType":"address payable","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"dkgContributionMargin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"dkgFeePool","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"},{"internalType":"bytes","name":"entry","type":"bytes"},{"internalType":"address payable","name":"submitter","type":"address"}],"name":"entryCreated","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"entryFeeBreakdown","outputs":[{"internalType":"uint256","name":"entryVerificationFee","type":"uint256"},{"internalType":"uint256","name":"dkgContributionFee","type":"uint256"},{"internalType":"uint256","name":"groupProfitFee","type":"uint256"},{"internalType":"uint256","name":"gasPriceCeiling","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"callbackGas","type":"uint256"}],"name":"entryFeeEstimate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"},{"internalType":"uint256","name":"entry","type":"uint256"}],"name":"executeCallback","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"fundDkgFeePool","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"fundRequestSubsidyFeePool","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"dkgContributionMargin","type":"uint256"},{"internalType":"address","name":"registry","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"operatorContract","type":"address"}],"name":"removeOperatorContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"requestRelayEntry","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"callbackContract","type":"address"},{"internalType":"uint256","name":"callbackGas","type":"uint256"}],"name":"requestRelayEntry","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"requestSubsidyFeePool","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"seed","type":"uint256"}],"name":"selectOperatorContract","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"}]

608060405234801561001057600080fd5b5060016000819055604080517f4b65657052616e646f6d426561636f6e53657276696365496d706c56310000008152600a601d820152905190819003603d019020805460ff191690911790556120ba8061006b6000396000f3fe6080604052600436106101145760003560e01c8063687d088e116100a0578063e1f9589011610064578063e1f9589014610363578063e58990c51461038f578063ef7284e3146103c2578063efc4971f14610487578063fc3fcec7146104b157610114565b8063687d088e1461029b578063d09dd574146102b0578063d13f1391146102c5578063da35a26f146102ef578063dede8e951461032857610114565b8063280f2043116100e7578063280f2043146101b95780632d53fe8b146101ce5780634611b648146101d657806354fd4d50146101de57806360e07ffd1461026857610114565b80630fda9ce414610119578063100aea0b1461015f57806311e816ee14610186578063158ef93e14610190575b600080fd5b34801561012557600080fd5b506101436004803603602081101561013c57600080fd5b50356104e1565b604080516001600160a01b039092168252519081900360200190f35b34801561016b57600080fd5b50610174610502565b60408051918252519081900360200190f35b61018e610509565b005b34801561019c57600080fd5b506101a5610513565b604080519115158252519081900360200190f35b3480156101c557600080fd5b50610174610553565b610174610559565b61018e61056b565b3480156101ea57600080fd5b506101f3610575565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561022d578181015183820152602001610215565b50505050905090810190601f16801561025a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561027457600080fd5b5061018e6004803603602081101561028b57600080fd5b50356001600160a01b0316610591565b3480156102a757600080fd5b50610174610758565b3480156102bc57600080fd5b5061017461075e565b3480156102d157600080fd5b50610174600480360360208110156102e857600080fd5b5035610764565b3480156102fb57600080fd5b5061018e6004803603604081101561031257600080fd5b50803590602001356001600160a01b03166107f3565b34801561033457600080fd5b5061033d610942565b604080519485526020850193909352838301919091526060830152519081900360800190f35b6101746004803603604081101561037957600080fd5b506001600160a01b038135169060200135610c0a565b34801561039b57600080fd5b5061018e600480360360208110156103b257600080fd5b50356001600160a01b03166111a4565b3480156103ce57600080fd5b5061018e600480360360608110156103e557600080fd5b8135919081019060408101602082013564010000000081111561040757600080fd5b82018360208201111561041957600080fd5b8035906020019184600183028401116401000000008311171561043b57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550505090356001600160a01b0316915061127a9050565b34801561049357600080fd5b50610143600480360360208110156104aa57600080fd5b503561138d565b3480156104bd57600080fd5b5061018e600480360360408110156104d457600080fd5b508035906020013561168c565b6000818152600760205260409020600301546001600160a01b03165b919050565b6002545b90565b6003805434019055565b604080517f4b65657052616e646f6d426561636f6e53657276696365496d706c56310000008152600a601d820152905190819003603d0190205460ff1690565b60015490565b6000610566600080610c0a565b905090565b6002805434019055565b604080518082019091526002815261563160f01b602082015290565b600854604080516363dc5fcf60e01b815230600482015290516000926001600160a01b0316916363dc5fcf916024808301926020929190829003018186803b1580156105dc57600080fd5b505afa1580156105f0573d6000803e3d6000fd5b505050506040513d602081101561060657600080fd5b505190506001600160a01b03811633146106515760405162461bcd60e51b8152600401808060200182810382526028815260200180611f0d6028913960400191505060405180910390fd5b600854604080516384d5768960e01b81526001600160a01b038581166004830152915191909216916384d57689916024808301926020929190829003018186803b15801561069e57600080fd5b505afa1580156106b2573d6000803e3d6000fd5b505050506040513d60208110156106c857600080fd5b50516107055760405162461bcd60e51b8152600401808060200182810382526021815260200180611eec6021913960400191505060405180910390fd5b50600980546001810182556000919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0180546001600160a01b0319166001600160a01b0392909216919091179055565b60035490565b60065490565b6000621e84808211156107a85760405162461bcd60e51b81526004018080602001828103825260268152602001806120606026913960400191505060405180910390fd5b6000806000806107b6610942565b93509350935093506107e96107cb87836118be565b6107dd8481888863ffffffff6118ff16565b9063ffffffff6118ff16565b9695505050505050565b6107fb610513565b1561084d576040805162461bcd60e51b815260206004820181905260248201527f436f6e747261637420697320616c726561647920696e697469616c697a65642e604482015290519081900360640190fd5b6001600160a01b0381166108a8576040805162461bcd60e51b815260206004820152601a60248201527f496e636f72726563742072656769737472792061646472657373000000000000604482015290519081900360640190fd5b604080517f4b65657052616e646f6d426561636f6e53657276696365496d706c56310000008152600a601d820152815190819003603d018120805460ff1916600190811790915584905560608101825281815290611fef6020830139805161091891600591602090910190611e33565b50600880546001600160a01b0319166001600160a01b0392909216919091179055506127f2600655565b6000808080805b600954811015610b475760006009828154811061096257fe5b600091825260208083209091015460408051635fca924b60e11b815290516001600160a01b039092169450849263bf95249692600480840193829003018186803b1580156109af57600080fd5b505afa1580156109c3573d6000803e3d6000fd5b505050506040513d60208110156109d957600080fd5b50511115610b3e576000816001600160a01b031663517471a96040518163ffffffff1660e01b815260040160206040518083038186803b158015610a1c57600080fd5b505afa158015610a30573d6000803e3d6000fd5b505050506040513d6020811015610a4657600080fd5b5051905086811115610a56578096505b816001600160a01b031663c44389466040518163ffffffff1660e01b815260040160206040518083038186803b158015610a8f57600080fd5b505afa158015610aa3573d6000803e3d6000fd5b505050506040513d6020811015610ab957600080fd5b5051905084811115610ac9578094505b816001600160a01b031663e1f4d6326040518163ffffffff1660e01b815260040160206040518083038186803b158015610b0257600080fd5b505afa158015610b16573d6000803e3d6000fd5b505050506040513d6020811015610b2c57600080fd5b5051905083811115610b3c578093505b505b50600101610949565b506009805460009190610b6190600163ffffffff61196016565b81548110610b6b57fe5b6000918252602080832090910154604080516318601a0b60e31b815290516001600160a01b039092169450849263c300d05892600480840193829003018186803b158015610bb857600080fd5b505afa158015610bcc573d6000803e3d6000fd5b505050506040513d6020811015610be257600080fd5b50516001549091508690610bfd90839063ffffffff6119a216565b9096509450505090919293565b60008054600101808255621e8480831115610c565760405162461bcd60e51b81526004018080602001828103825260268152602001806120606026913960400191505060405180910390fd5b610c5f83610764565b341015610c9d5760405162461bcd60e51b8152600401808060200182810382526026815260200180611fc96026913960400191505060405180910390fd5b600080600080610cab610942565b929650909450925090506000610cd983610ccd8681348a63ffffffff61196016565b9063ffffffff61196016565b9050836002600082825401925050819055506000610d6260056040518082805460018160011615610100020316600290048015610d4d5780601f10610d2b576101008083540402835291820191610d4d565b820191906000526020600020905b815481529060010190602001808311610d39575b5050915050604051809103902060001c61138d565b90506000610e46826001600160a01b031663517471a96040518163ffffffff1660e01b815260040160206040518083038186803b158015610da257600080fd5b505afa158015610db6573d6000803e3d6000fd5b505050506040513d6020811015610dcc57600080fd5b505160408051636221c4a360e11b815290516001600160a01b0386169163c4438946916004808301926020929190829003018186803b158015610e0e57600080fd5b505afa158015610e22573d6000803e3d6000fd5b505050506040513d6020811015610e3857600080fd5b50519063ffffffff6118ff16565b60048054600101908190559091506001600160a01b038316639b3d270a610e73848763ffffffff6118ff16565b604080516001600160e01b031960e085901b1681526004810186815260248201928352600580546002600019610100600184161502019091160460448401819052889491936064019084908015610f0b5780601f10610ee057610100808354040283529160200191610f0b565b820191906000526020600020905b815481529060010190602001808311610eee57829003601f168201915b505093505050506000604051808303818588803b158015610f2b57600080fd5b505af1158015610f3f573d6000803e3d6000fd5b50505050506000610f5d83610ccd898c6118ff90919063ffffffff16565b600354909150610f73908263ffffffff6118ff16565b6003556001600160a01b038d161561103d5760405180608001604052808e6001600160a01b031681526020018681526020018d8152602001336001600160a01b03168152506007600084815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550602082015181600101556040820151816002015560608201518160030160006101000a8154816001600160a01b0302191690836001600160a01b031602179055509050505b60646003541061110a5760035460009061105e90600163ffffffff6119a216565b600380548290039055604051909150600090339083908381818185875af1925050503d80600081146110ac576040519150601f19603f3d011682016040523d82523d6000602084013e6110b1565b606091505b5050905080611107576040805162461bcd60e51b815260206004820152601760248201527f4661696c65642073656e64207375627369647920666565000000000000000000604482015290519081900360640190fd5b50505b6040805183815290517fc65bedbc1f2ce56540b8b4e1b7b41261bef9dc7aee32cb3b6806a70c5f4828fa9181900360200190a150985050505050505050600054811461119d576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b5092915050565b600854604080516363dc5fcf60e01b815230600482015290516000926001600160a01b0316916363dc5fcf916024808301926020929190829003018186803b1580156111ef57600080fd5b505afa158015611203573d6000803e3d6000fd5b505050506040513d602081101561121957600080fd5b505190506001600160a01b03811633146112645760405162461bcd60e51b8152600401808060200182810382526028815260200180611f0d6028913960400191505060405180910390fd5b61127560098363ffffffff6119c516565b505050565b6112e73360098054806020026020016040519081016040528092919081815260200182805480156112d457602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116112b6575b5050505050611a9d90919063ffffffff16565b6113225760405162461bcd60e51b8152600401808060200182810382526037815260200180611f716037913960400191505060405180910390fd5b8151611335906005906020850190611e33565b50815160208084019190912060408051868152928301829052805191927fddb7473cb5eaf3aaa2cf09ea9d573d4876aac471614f99773f32a4b5994ea7e1929081900390910190a16113878183611af3565b50505050565b600080600060606009805490506040519080825280602002602001820160405280156113c3578160200160208202803883390190505b50905060005b60095481101561155c57600854600980546001600160a01b03909216916384d576899190849081106113f757fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b15801561144557600080fd5b505afa158015611459573d6000803e3d6000fd5b505050506040513d602081101561146f57600080fd5b505115611554576009818154811061148357fe5b6000918252602091829020015460408051635fca924b60e11b815290516001600160a01b039092169263bf95249692600480840193829003018186803b1580156114cc57600080fd5b505afa1580156114e0573d6000803e3d6000fd5b505050506040513d60208110156114f657600080fd5b50516009805495909101948290811061150b57fe5b9060005260206000200160009054906101000a90046001600160a01b031682848151811061153557fe5b6001600160a01b03909216602092830291909101909101526001909201915b6001016113c9565b506000831161159c5760405162461bcd60e51b815260040180806020018281038252603181526020018061202f6031913960400191505060405180910390fd5b60008386816115a757fe5b069050600080805b8581101561166a578481815181106115c357fe5b60200260200101516001600160a01b031663bf9524966040518163ffffffff1660e01b815260040160206040518083038186803b15801561160357600080fd5b505afa158015611617573d6000803e3d6000fd5b505050506040513d602081101561162d57600080fd5b505191909101908184101561165e5784838151811061164857fe5b60200260200101519750505050505050506104fd565b600192830192016115af565b5083828151811061167757fe5b60200260200101519650505050505050919050565b6116f73360098054806020026020016040519081016040528092919081815260200182805480156112d4576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116112b6575050505050611a9d90919063ffffffff16565b6117325760405162461bcd60e51b815260040180806020018281038252603c815260200180611f35603c913960400191505060405180910390fd5b6000828152600760205260409020546001600160a01b031661179b576040805162461bcd60e51b815260206004820152601b60248201527f43616c6c6261636b20636f6e7472616374206e6f7420666f756e640000000000604482015290519081900360640190fd5b6000828152600760209081526040918290205482516024808201869052845180830390910181526044909101845291820180516001600160e01b03166306adc0e560e31b178152925182516001600160a01b039092169390918291908083835b6020831061181a5780518252601f1990920191602091820191016117fb565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461187c576040519150601f19603f3d011682016040523d82523d6000602084013e611881565b606091505b50505060009182525060076020526040812080546001600160a01b0319908116825560018201839055600282019290925560030180549091169055565b60008083156118e0576006546118db90859063ffffffff6118ff16565b6118e3565b60005b90506118f5818463ffffffff611ca116565b9150505b92915050565b600082820183811015611959576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600061195983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611cfa565b600061195960646119b9858563ffffffff611ca116565b9063ffffffff611d9116565b6000805b8354811015611a95578381815481106119de57fe5b6000918252602090912001546001600160a01b0384811691161415611a8d57805b845460001901811015611a7657848160010181548110611a1b57fe5b9060005260206000200160009054906101000a90046001600160a01b0316858281548110611a4557fe5b600091825260209091200180546001600160a01b0319166001600160a01b03929092169190911790556001016119ff565b508354611a87856000198301611eb1565b50600019015b6001016119c9565b509192915050565b6000805b8351811015611ae957838181518110611ab657fe5b60200260200101516001600160a01b0316836001600160a01b03161415611ae15760019150506118f9565b600101611aa1565b5060009392505050565b6009805460009190611b0c90600163ffffffff61196016565b81548110611b1657fe5b6000918252602080832090910154604080516318601a0b60e31b815290516001600160a01b039092169450849263c300d05892600480840193829003018186803b158015611b6357600080fd5b505afa158015611b77573d6000803e3d6000fd5b505050506040513d6020811015611b8d57600080fd5b50516002549091508111801590611c055750816001600160a01b03166321a8f86c6040518163ffffffff1660e01b815260040160206040518083038186803b158015611bd857600080fd5b505afa158015611bec573d6000803e3d6000fd5b505050506040513d6020811015611c0257600080fd5b50515b1561138757816001600160a01b031663c96e71fb8286866040518463ffffffff1660e01b815260040180838152602001826001600160a01b03166001600160a01b03168152602001925050506000604051808303818588803b158015611c6a57600080fd5b505af1158015611c7e573d6000803e3d6000fd5b5050505050611c988160025461196090919063ffffffff16565b60025550505050565b600082611cb0575060006118f9565b82820282848281611cbd57fe5b04146119595760405162461bcd60e51b8152600401808060200182810382526021815260200180611fa86021913960400191505060405180910390fd5b60008184841115611d895760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611d4e578181015183820152602001611d36565b50505050905090810190601f168015611d7b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600061195983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525060008183611e1d5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315611d4e578181015183820152602001611d36565b506000838581611e2957fe5b0495945050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611e7457805160ff1916838001178555611ea1565b82800160010185558215611ea1579182015b82811115611ea1578251825591602001919060010190611e86565b50611ead929150611ed1565b5090565b815481835581811115611275576000838152602090206112759181019083015b61050691905b80821115611ead5760008155600101611ed756fe4f70657261746f7220636f6e7472616374206973206e6f7420617070726f76656443616c6c6572206973206e6f74206f70657261746f7220636f6e74726163742075706772616465724f6e6c7920617574686f72697a6564206f70657261746f7220636f6e74726163742063616e2063616c6c20657865637574652063616c6c6261636b2e4f6e6c7920617574686f72697a6564206f70657261746f7220636f6e74726163742063616e2063616c6c2072656c617920656e7472792e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775061796d656e74206973206c657373207468616e207265717569726564206d696e696d756d2e15c30f4b6cf6dbbcbdcc10fe22f54c8170aea44e198139b776d512d8f027319a1b9e8bfaf1383978231ce98e42bafc8129f473fc993cf60ce327f7d223460663546f74616c206e756d626572206f662067726f757073206d7573742062652067726561746572207468616e207a65726f2e43616c6c6261636b206761732065786365656473203230303030303020676173206c696d6974a265627a7a72315820ee695e70629593412efef81cae0f44a7b65b97f7d3e8d28c5dfde087ff75edaa64736f6c63430005110032

Deployed Bytecode

0x6080604052600436106101145760003560e01c8063687d088e116100a0578063e1f9589011610064578063e1f9589014610363578063e58990c51461038f578063ef7284e3146103c2578063efc4971f14610487578063fc3fcec7146104b157610114565b8063687d088e1461029b578063d09dd574146102b0578063d13f1391146102c5578063da35a26f146102ef578063dede8e951461032857610114565b8063280f2043116100e7578063280f2043146101b95780632d53fe8b146101ce5780634611b648146101d657806354fd4d50146101de57806360e07ffd1461026857610114565b80630fda9ce414610119578063100aea0b1461015f57806311e816ee14610186578063158ef93e14610190575b600080fd5b34801561012557600080fd5b506101436004803603602081101561013c57600080fd5b50356104e1565b604080516001600160a01b039092168252519081900360200190f35b34801561016b57600080fd5b50610174610502565b60408051918252519081900360200190f35b61018e610509565b005b34801561019c57600080fd5b506101a5610513565b604080519115158252519081900360200190f35b3480156101c557600080fd5b50610174610553565b610174610559565b61018e61056b565b3480156101ea57600080fd5b506101f3610575565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561022d578181015183820152602001610215565b50505050905090810190601f16801561025a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561027457600080fd5b5061018e6004803603602081101561028b57600080fd5b50356001600160a01b0316610591565b3480156102a757600080fd5b50610174610758565b3480156102bc57600080fd5b5061017461075e565b3480156102d157600080fd5b50610174600480360360208110156102e857600080fd5b5035610764565b3480156102fb57600080fd5b5061018e6004803603604081101561031257600080fd5b50803590602001356001600160a01b03166107f3565b34801561033457600080fd5b5061033d610942565b604080519485526020850193909352838301919091526060830152519081900360800190f35b6101746004803603604081101561037957600080fd5b506001600160a01b038135169060200135610c0a565b34801561039b57600080fd5b5061018e600480360360208110156103b257600080fd5b50356001600160a01b03166111a4565b3480156103ce57600080fd5b5061018e600480360360608110156103e557600080fd5b8135919081019060408101602082013564010000000081111561040757600080fd5b82018360208201111561041957600080fd5b8035906020019184600183028401116401000000008311171561043b57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550505090356001600160a01b0316915061127a9050565b34801561049357600080fd5b50610143600480360360208110156104aa57600080fd5b503561138d565b3480156104bd57600080fd5b5061018e600480360360408110156104d457600080fd5b508035906020013561168c565b6000818152600760205260409020600301546001600160a01b03165b919050565b6002545b90565b6003805434019055565b604080517f4b65657052616e646f6d426561636f6e53657276696365496d706c56310000008152600a601d820152905190819003603d0190205460ff1690565b60015490565b6000610566600080610c0a565b905090565b6002805434019055565b604080518082019091526002815261563160f01b602082015290565b600854604080516363dc5fcf60e01b815230600482015290516000926001600160a01b0316916363dc5fcf916024808301926020929190829003018186803b1580156105dc57600080fd5b505afa1580156105f0573d6000803e3d6000fd5b505050506040513d602081101561060657600080fd5b505190506001600160a01b03811633146106515760405162461bcd60e51b8152600401808060200182810382526028815260200180611f0d6028913960400191505060405180910390fd5b600854604080516384d5768960e01b81526001600160a01b038581166004830152915191909216916384d57689916024808301926020929190829003018186803b15801561069e57600080fd5b505afa1580156106b2573d6000803e3d6000fd5b505050506040513d60208110156106c857600080fd5b50516107055760405162461bcd60e51b8152600401808060200182810382526021815260200180611eec6021913960400191505060405180910390fd5b50600980546001810182556000919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0180546001600160a01b0319166001600160a01b0392909216919091179055565b60035490565b60065490565b6000621e84808211156107a85760405162461bcd60e51b81526004018080602001828103825260268152602001806120606026913960400191505060405180910390fd5b6000806000806107b6610942565b93509350935093506107e96107cb87836118be565b6107dd8481888863ffffffff6118ff16565b9063ffffffff6118ff16565b9695505050505050565b6107fb610513565b1561084d576040805162461bcd60e51b815260206004820181905260248201527f436f6e747261637420697320616c726561647920696e697469616c697a65642e604482015290519081900360640190fd5b6001600160a01b0381166108a8576040805162461bcd60e51b815260206004820152601a60248201527f496e636f72726563742072656769737472792061646472657373000000000000604482015290519081900360640190fd5b604080517f4b65657052616e646f6d426561636f6e53657276696365496d706c56310000008152600a601d820152815190819003603d018120805460ff1916600190811790915584905560608101825281815290611fef6020830139805161091891600591602090910190611e33565b50600880546001600160a01b0319166001600160a01b0392909216919091179055506127f2600655565b6000808080805b600954811015610b475760006009828154811061096257fe5b600091825260208083209091015460408051635fca924b60e11b815290516001600160a01b039092169450849263bf95249692600480840193829003018186803b1580156109af57600080fd5b505afa1580156109c3573d6000803e3d6000fd5b505050506040513d60208110156109d957600080fd5b50511115610b3e576000816001600160a01b031663517471a96040518163ffffffff1660e01b815260040160206040518083038186803b158015610a1c57600080fd5b505afa158015610a30573d6000803e3d6000fd5b505050506040513d6020811015610a4657600080fd5b5051905086811115610a56578096505b816001600160a01b031663c44389466040518163ffffffff1660e01b815260040160206040518083038186803b158015610a8f57600080fd5b505afa158015610aa3573d6000803e3d6000fd5b505050506040513d6020811015610ab957600080fd5b5051905084811115610ac9578094505b816001600160a01b031663e1f4d6326040518163ffffffff1660e01b815260040160206040518083038186803b158015610b0257600080fd5b505afa158015610b16573d6000803e3d6000fd5b505050506040513d6020811015610b2c57600080fd5b5051905083811115610b3c578093505b505b50600101610949565b506009805460009190610b6190600163ffffffff61196016565b81548110610b6b57fe5b6000918252602080832090910154604080516318601a0b60e31b815290516001600160a01b039092169450849263c300d05892600480840193829003018186803b158015610bb857600080fd5b505afa158015610bcc573d6000803e3d6000fd5b505050506040513d6020811015610be257600080fd5b50516001549091508690610bfd90839063ffffffff6119a216565b9096509450505090919293565b60008054600101808255621e8480831115610c565760405162461bcd60e51b81526004018080602001828103825260268152602001806120606026913960400191505060405180910390fd5b610c5f83610764565b341015610c9d5760405162461bcd60e51b8152600401808060200182810382526026815260200180611fc96026913960400191505060405180910390fd5b600080600080610cab610942565b929650909450925090506000610cd983610ccd8681348a63ffffffff61196016565b9063ffffffff61196016565b9050836002600082825401925050819055506000610d6260056040518082805460018160011615610100020316600290048015610d4d5780601f10610d2b576101008083540402835291820191610d4d565b820191906000526020600020905b815481529060010190602001808311610d39575b5050915050604051809103902060001c61138d565b90506000610e46826001600160a01b031663517471a96040518163ffffffff1660e01b815260040160206040518083038186803b158015610da257600080fd5b505afa158015610db6573d6000803e3d6000fd5b505050506040513d6020811015610dcc57600080fd5b505160408051636221c4a360e11b815290516001600160a01b0386169163c4438946916004808301926020929190829003018186803b158015610e0e57600080fd5b505afa158015610e22573d6000803e3d6000fd5b505050506040513d6020811015610e3857600080fd5b50519063ffffffff6118ff16565b60048054600101908190559091506001600160a01b038316639b3d270a610e73848763ffffffff6118ff16565b604080516001600160e01b031960e085901b1681526004810186815260248201928352600580546002600019610100600184161502019091160460448401819052889491936064019084908015610f0b5780601f10610ee057610100808354040283529160200191610f0b565b820191906000526020600020905b815481529060010190602001808311610eee57829003601f168201915b505093505050506000604051808303818588803b158015610f2b57600080fd5b505af1158015610f3f573d6000803e3d6000fd5b50505050506000610f5d83610ccd898c6118ff90919063ffffffff16565b600354909150610f73908263ffffffff6118ff16565b6003556001600160a01b038d161561103d5760405180608001604052808e6001600160a01b031681526020018681526020018d8152602001336001600160a01b03168152506007600084815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550602082015181600101556040820151816002015560608201518160030160006101000a8154816001600160a01b0302191690836001600160a01b031602179055509050505b60646003541061110a5760035460009061105e90600163ffffffff6119a216565b600380548290039055604051909150600090339083908381818185875af1925050503d80600081146110ac576040519150601f19603f3d011682016040523d82523d6000602084013e6110b1565b606091505b5050905080611107576040805162461bcd60e51b815260206004820152601760248201527f4661696c65642073656e64207375627369647920666565000000000000000000604482015290519081900360640190fd5b50505b6040805183815290517fc65bedbc1f2ce56540b8b4e1b7b41261bef9dc7aee32cb3b6806a70c5f4828fa9181900360200190a150985050505050505050600054811461119d576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b5092915050565b600854604080516363dc5fcf60e01b815230600482015290516000926001600160a01b0316916363dc5fcf916024808301926020929190829003018186803b1580156111ef57600080fd5b505afa158015611203573d6000803e3d6000fd5b505050506040513d602081101561121957600080fd5b505190506001600160a01b03811633146112645760405162461bcd60e51b8152600401808060200182810382526028815260200180611f0d6028913960400191505060405180910390fd5b61127560098363ffffffff6119c516565b505050565b6112e73360098054806020026020016040519081016040528092919081815260200182805480156112d457602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116112b6575b5050505050611a9d90919063ffffffff16565b6113225760405162461bcd60e51b8152600401808060200182810382526037815260200180611f716037913960400191505060405180910390fd5b8151611335906005906020850190611e33565b50815160208084019190912060408051868152928301829052805191927fddb7473cb5eaf3aaa2cf09ea9d573d4876aac471614f99773f32a4b5994ea7e1929081900390910190a16113878183611af3565b50505050565b600080600060606009805490506040519080825280602002602001820160405280156113c3578160200160208202803883390190505b50905060005b60095481101561155c57600854600980546001600160a01b03909216916384d576899190849081106113f757fe5b60009182526020918290200154604080516001600160e01b031960e086901b1681526001600160a01b0390921660048301525160248083019392829003018186803b15801561144557600080fd5b505afa158015611459573d6000803e3d6000fd5b505050506040513d602081101561146f57600080fd5b505115611554576009818154811061148357fe5b6000918252602091829020015460408051635fca924b60e11b815290516001600160a01b039092169263bf95249692600480840193829003018186803b1580156114cc57600080fd5b505afa1580156114e0573d6000803e3d6000fd5b505050506040513d60208110156114f657600080fd5b50516009805495909101948290811061150b57fe5b9060005260206000200160009054906101000a90046001600160a01b031682848151811061153557fe5b6001600160a01b03909216602092830291909101909101526001909201915b6001016113c9565b506000831161159c5760405162461bcd60e51b815260040180806020018281038252603181526020018061202f6031913960400191505060405180910390fd5b60008386816115a757fe5b069050600080805b8581101561166a578481815181106115c357fe5b60200260200101516001600160a01b031663bf9524966040518163ffffffff1660e01b815260040160206040518083038186803b15801561160357600080fd5b505afa158015611617573d6000803e3d6000fd5b505050506040513d602081101561162d57600080fd5b505191909101908184101561165e5784838151811061164857fe5b60200260200101519750505050505050506104fd565b600192830192016115af565b5083828151811061167757fe5b60200260200101519650505050505050919050565b6116f73360098054806020026020016040519081016040528092919081815260200182805480156112d4576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116112b6575050505050611a9d90919063ffffffff16565b6117325760405162461bcd60e51b815260040180806020018281038252603c815260200180611f35603c913960400191505060405180910390fd5b6000828152600760205260409020546001600160a01b031661179b576040805162461bcd60e51b815260206004820152601b60248201527f43616c6c6261636b20636f6e7472616374206e6f7420666f756e640000000000604482015290519081900360640190fd5b6000828152600760209081526040918290205482516024808201869052845180830390910181526044909101845291820180516001600160e01b03166306adc0e560e31b178152925182516001600160a01b039092169390918291908083835b6020831061181a5780518252601f1990920191602091820191016117fb565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461187c576040519150601f19603f3d011682016040523d82523d6000602084013e611881565b606091505b50505060009182525060076020526040812080546001600160a01b0319908116825560018201839055600282019290925560030180549091169055565b60008083156118e0576006546118db90859063ffffffff6118ff16565b6118e3565b60005b90506118f5818463ffffffff611ca116565b9150505b92915050565b600082820183811015611959576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600061195983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611cfa565b600061195960646119b9858563ffffffff611ca116565b9063ffffffff611d9116565b6000805b8354811015611a95578381815481106119de57fe5b6000918252602090912001546001600160a01b0384811691161415611a8d57805b845460001901811015611a7657848160010181548110611a1b57fe5b9060005260206000200160009054906101000a90046001600160a01b0316858281548110611a4557fe5b600091825260209091200180546001600160a01b0319166001600160a01b03929092169190911790556001016119ff565b508354611a87856000198301611eb1565b50600019015b6001016119c9565b509192915050565b6000805b8351811015611ae957838181518110611ab657fe5b60200260200101516001600160a01b0316836001600160a01b03161415611ae15760019150506118f9565b600101611aa1565b5060009392505050565b6009805460009190611b0c90600163ffffffff61196016565b81548110611b1657fe5b6000918252602080832090910154604080516318601a0b60e31b815290516001600160a01b039092169450849263c300d05892600480840193829003018186803b158015611b6357600080fd5b505afa158015611b77573d6000803e3d6000fd5b505050506040513d6020811015611b8d57600080fd5b50516002549091508111801590611c055750816001600160a01b03166321a8f86c6040518163ffffffff1660e01b815260040160206040518083038186803b158015611bd857600080fd5b505afa158015611bec573d6000803e3d6000fd5b505050506040513d6020811015611c0257600080fd5b50515b1561138757816001600160a01b031663c96e71fb8286866040518463ffffffff1660e01b815260040180838152602001826001600160a01b03166001600160a01b03168152602001925050506000604051808303818588803b158015611c6a57600080fd5b505af1158015611c7e573d6000803e3d6000fd5b5050505050611c988160025461196090919063ffffffff16565b60025550505050565b600082611cb0575060006118f9565b82820282848281611cbd57fe5b04146119595760405162461bcd60e51b8152600401808060200182810382526021815260200180611fa86021913960400191505060405180910390fd5b60008184841115611d895760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611d4e578181015183820152602001611d36565b50505050905090810190601f168015611d7b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600061195983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525060008183611e1d5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315611d4e578181015183820152602001611d36565b506000838581611e2957fe5b0495945050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611e7457805160ff1916838001178555611ea1565b82800160010185558215611ea1579182015b82811115611ea1578251825591602001919060010190611e86565b50611ead929150611ed1565b5090565b815481835581811115611275576000838152602090206112759181019083015b61050691905b80821115611ead5760008155600101611ed756fe4f70657261746f7220636f6e7472616374206973206e6f7420617070726f76656443616c6c6572206973206e6f74206f70657261746f7220636f6e74726163742075706772616465724f6e6c7920617574686f72697a6564206f70657261746f7220636f6e74726163742063616e2063616c6c20657865637574652063616c6c6261636b2e4f6e6c7920617574686f72697a6564206f70657261746f7220636f6e74726163742063616e2063616c6c2072656c617920656e7472792e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775061796d656e74206973206c657373207468616e207265717569726564206d696e696d756d2e15c30f4b6cf6dbbcbdcc10fe22f54c8170aea44e198139b776d512d8f027319a1b9e8bfaf1383978231ce98e42bafc8129f473fc993cf60ce327f7d223460663546f74616c206e756d626572206f662067726f757073206d7573742062652067726561746572207468616e207a65726f2e43616c6c6261636b206761732065786365656473203230303030303020676173206c696d6974a265627a7a72315820ee695e70629593412efef81cae0f44a7b65b97f7d3e8d28c5dfde087ff75edaa64736f6c63430005110032

Deployed Bytecode Sourcemap

3287:17699:3:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20683:152;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20683:152:3;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;20683:152:3;;:::i;:::-;;;;-1:-1:-1;;;;;20683:152:3;;;;;;;;;;;;;;20119:86;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20119:86:3;;;:::i;:::-;;;;;;;;;;;;;;;;8306:104;;;:::i;:::-;;7302:119;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7302:119:3;;;:::i;:::-;;;;;;;;;;;;;;;;;;19708:108;;8:9:-1;5:2;;;30:1;27;20:12;5:2;19708:108:3;;;:::i;10210:118::-;;;:::i;8163:82::-;;;:::i;20901:83::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20901:83:3;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;20901:83:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7532:307;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7532:307:3;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;7532:307:3;-1:-1:-1;;;;;7532:307:3;;:::i;20489:108::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20489:108:3;;;:::i;15990:96::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;15990:96:3;;;:::i;16946:566::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;16946:566:3;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;16946:566:3;;:::i;6762:478::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6762:478:3;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;6762:478:3;;;;;;-1:-1:-1;;;;;6762:478:3;;:::i;17594:1966::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;17594:1966:3;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11193:2369;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;11193:2369:3;;;;;;;;:::i;7953:161::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7953:161:3;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;7953:161:3;-1:-1:-1;;;;;7953:161:3;;:::i;13861:465::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;13861:465:3;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;13861:465:3;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;13861:465:3;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;13861:465:3;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;13861:465:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;13861:465:3;;-1:-1:-1;;;13861:465:3;;-1:-1:-1;;;;;13861:465:3;;-1:-1:-1;13861:465:3;;-1:-1:-1;13861:465:3:i;8715:1263::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8715:1263:3;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;8715:1263:3;;:::i;14537:542::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;14537:542:3;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;14537:542:3;;;;;;;:::i;20683:152::-;20756:15;20790:21;;;:10;:21;;;;;:38;;;-1:-1:-1;;;;;20790:38:3;20683:152;;;;:::o;20119:86::-;20187:11;;20119:86;;:::o;8306:104::-;8368:22;:35;;8394:9;8368:35;;;8306:104::o;7302:119::-;7369:45;;;;;;:12;:45;;;;;;;;;;;;;;;;;7302:119;:::o;19708:108::-;19787:22;;19708:108;:::o;10210:118::-;10263:7;10289:32;10315:1;10319;10289:17;:32::i;:::-;10282:39;;10210:118;:::o;8163:82::-;8214:11;:24;;8229:9;8214:24;;;8163:82::o;20901:83::-;20966:11;;;;;;;;;;;;-1:-1:-1;;;20966:11:3;;;;20901:83;:::o;7532:307::-;6211:9;;6198:66;;;-1:-1:-1;;;6198:66:3;;6258:4;6198:66;;;;;;6163:32;;-1:-1:-1;;;;;6211:9:3;;6198:51;;:66;;;;;;;;;;;;;;6211:9;6198:66;;;5:2:-1;;;;30:1;27;20:12;5:2;6198:66:3;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;6198:66:3;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;6198:66:3;;-1:-1:-1;;;;;;6282:38:3;;6310:10;6282:38;6274:91;;;;-1:-1:-1;;;6274:91:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7667:9;;7654:68;;;-1:-1:-1;;;7654:68:3;;-1:-1:-1;;;;;7654:68:3;;;;;;;;;7667:9;;;;;7654:50;;:68;;;;;;;;;;;;;;7667:9;7654:68;;;5:2:-1;;;;30:1;27;20:12;5:2;7654:68:3;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;7654:68:3;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;7654:68:3;7633:148;;;;-1:-1:-1;;;7633:148:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7791:18:3;27:10:-1;;39:1;23:18;;45:23;;-1:-1;7791:41:3;;;;;;;;-1:-1:-1;;;;;;7791:41:3;-1:-1:-1;;;;;7791:41:3;;;;;;;;;;7532:307::o;20489:108::-;20568:22;;20489:108;:::o;15990:96::-;16063:16;;15990:96;:::o;16946:566::-;17013:7;17068;17053:11;:22;;17032:107;;;;-1:-1:-1;;;17032:107:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17164:28;17206:26;17246:22;17282:23;17318:19;:17;:19::i;:::-;17150:187;;;;;;;;17355:150;17463:41;17475:11;17488:15;17463:11;:41::i;:::-;17355:90;17430:14;17355:90;:20;17393:18;17355:57;:37;:57;:::i;:::-;:74;:90;:74;:90;:::i;:150::-;17348:157;16946:566;-1:-1:-1;;;;;;16946:566:3:o;6762:478::-;6891:13;:11;:13::i;:::-;6890:14;6882:59;;;;;-1:-1:-1;;;6882:59:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;6959:22:3;;6951:61;;;;;-1:-1:-1;;;6951:61:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;7023:45;;;;;;:12;:45;;;;;;;;;;;;;;:52;;-1:-1:-1;;7023:52:3;7071:4;7023:52;;;;;;7085:46;;;7158:11;;;;;;;;7023:45;7158:11;7023:45;7158:11;;;7141:28;;;;:14;;:28;;;;;;:::i;:::-;-1:-1:-1;7179:9:3;:20;;-1:-1:-1;;;;;;7179:20:3;-1:-1:-1;;;;;7179:20:3;;;;;;;;;;-1:-1:-1;7228:5:3;7209:16;:24;6762:478::o;17594:1966::-;17652:28;;;;;18293:771;18314:18;:25;18310:29;;18293:771;;;18360:25;18405:18;18424:1;18405:21;;;;;;;;;;;;;;;;;;;;18446:25;;;-1:-1:-1;;;18446:25:3;;;;-1:-1:-1;;;;;18405:21:3;;;;-1:-1:-1;18405:21:3;;18446:23;;:25;;;;;;;;;;18405:21;18446:25;;;5:2:-1;;;;30:1;27;20:12;5:2;18446:25:3;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;18446:25:3;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;18446:25:3;:29;18442:612;;;18495:19;18517:8;-1:-1:-1;;;;;18517:29:3;;:31;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;18517:31:3;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;18517:31:3;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;18517:31:3;;-1:-1:-1;18570:34:3;;;18566:115;;;18651:11;18628:34;;18566:115;18713:8;-1:-1:-1;;;;;18713:23:3;;:25;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;18713:25:3;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;18713:25:3;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;18713:25:3;;-1:-1:-1;18760:28:3;;;18756:103;;;18829:11;18812:28;;18756:103;18891:8;-1:-1:-1;;;;;18891:24:3;;:26;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;18891:26:3;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;18891:26:3;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;18891:26:3;;-1:-1:-1;18939:29:3;;;18935:105;;;19010:11;18992:29;;18935:105;18442:612;;-1:-1:-1;18341:3:3;;18293:771;;;-1:-1:-1;19224:18:3;19243:25;;19191:30;;19224:18;19243:32;;19273:1;19243:32;:29;:32;:::i;:::-;19224:52;;;;;;;;;;;;;;;;;;;;19313:59;;;-1:-1:-1;;;19313:59:3;;;;-1:-1:-1;;;;;19224:52:3;;;;-1:-1:-1;19224:52:3;;19313:57;;:59;;;;;;;;;;19224:52;19313:59;;;5:2:-1;;;;30:1;27;20:12;5:2;19313:59:3;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;19313:59:3;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;19313:59:3;19463:22;;19313:59;;-1:-1:-1;19404:20:3;;19438:48;;19313:59;;19438:48;:24;:48;:::i;:::-;19383:170;;-1:-1:-1;19383:170:3;-1:-1:-1;;;17594:1966:3;;;;:::o;11193:2369::-;11326:7;1296:18:1;;1313:1;1296:18;;;;11381:7:3;11366:22;;;11345:107;;;;-1:-1:-1;;;11345:107:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11497:29;11514:11;11497:16;:29::i;:::-;11484:9;:42;;11463:127;;;;-1:-1:-1;;;11463:127:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11615:28;11657:26;11697:22;11733:23;11769:19;:17;:19::i;:::-;11601:187;;-1:-1:-1;11601:187:3;;-1:-1:-1;11601:187:3;-1:-1:-1;11601:187:3;-1:-1:-1;11799:19:3;11821:92;11601:187;11821:72;11601:187;11821:72;:9;11601:187;11821:35;:13;:35;:::i;:::-;:52;:72;:52;:72;:::i;:92::-;11799:114;;11939:18;11924:11;;:33;;;;;;;;;;;11968;12034:58;12075:14;12065:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12057:34;;12034:22;:58::i;:::-;11968:134;;12113:35;12151:100;12202:16;-1:-1:-1;;;;;12202:37:3;;:39;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12202:39:3;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;12202:39:3;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;12202:39:3;12151:33;;;-1:-1:-1;;;12151:33:3;;;;-1:-1:-1;;;;;12151:31:3;;;;;:33;;;;;12202:39;;12151:33;;;;;;;:31;:33;;;5:2:-1;;;;30:1;27;20:12;5:2;12151:33:3;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;12151:33:3;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;12151:33:3;;:100;:37;:100;:::i;:::-;12262:15;:17;;;;;;;;12113:138;;-1:-1:-1;;;;;;12335:21:3;;;12376:44;12113:138;12408:11;12376:44;:31;:44;:::i;:::-;12335:122;;;-1:-1:-1;;;;;;12335:122:3;;;;;;;;;;;;;;;;;;;12442:14;12335:122;;;-1:-1:-1;;12335:122:3;;;;;;;;;;;;;;;;;12431:9;;12442:14;;12335:122;;;12442:14;;12335:122;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12335:122:3;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;12335:122:3;;;;;12809:15;12827:73;12872:27;12827:40;12852:14;12827:20;:24;;:40;;;;:::i;:73::-;12935:22;;12809:91;;-1:-1:-1;12935:35:3;;12809:91;12935:35;:26;:35;:::i;:::-;12910:22;:60;-1:-1:-1;;;;;12985:30:3;;;12981:149;;13055:64;;;;;;;;13064:16;-1:-1:-1;;;;;13055:64:3;;;;;13082:11;13055:64;;;;13095:11;13055:64;;;;13108:10;-1:-1:-1;;;;;13055:64:3;;;;13031:10;:21;13042:9;13031:21;;;;;;;;;;;:88;;;;;;;;;;;;;-1:-1:-1;;;;;13031:88:3;;;;;-1:-1:-1;;;;;13031:88:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;13031:88:3;;;;;-1:-1:-1;;;;;13031:88:3;;;;;;;;;12981:149;13235:3;13209:22;;:29;13205:279;;13271:22;;13254:14;;13271:33;;13302:1;13271:33;:30;:33;:::i;:::-;13318:22;:32;;;;;;;13383:33;;13254:50;;-1:-1:-1;13318:22:3;;13383:10;;13254:50;;13318:22;13383:33;13318:22;13383:33;13254:50;13383:10;:33;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;13364:52:3;;;13438:7;13430:43;;;;;-1:-1:-1;;;13430:43:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;13205:279;;;13499:30;;;;;;;;;;;;;;;;;-1:-1:-1;13546:9:3;-1:-1:-1;;;;;;;;1405:13:1;;1389:12;:29;1381:73;;;;;-1:-1:-1;;;1381:73:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;11193:2369:3;;;;;:::o;7953:161::-;6211:9;;6198:66;;;-1:-1:-1;;;6198:66:3;;6258:4;6198:66;;;;;;6163:32;;-1:-1:-1;;;;;6211:9:3;;6198:51;;:66;;;;;;;;;;;;;;6211:9;6198:66;;;5:2:-1;;;;30:1;27;20:12;5:2;6198:66:3;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;6198:66:3;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;6198:66:3;;-1:-1:-1;;;;;;6282:38:3;;6310:10;6282:38;6274:91;;;;-1:-1:-1;;;6274:91:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8057:50;:18;8090:16;8057:50;:32;:50;:::i;:::-;;7953:161;;:::o;13861:465::-;13987:39;14015:10;13987:18;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;13987:27:3;;;;;;;;;;;;;;;;;;;;;;;:39;;;;:::i;:::-;13966:141;;;;-1:-1:-1;;;13966:141:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14118:22;;;;:14;;:22;;;;;:::i;:::-;-1:-1:-1;14182:16:3;;;;;;;;;;14214:45;;;;;;;;;;;;;;14182:16;;14214:45;;;;;;;;;;;14270:49;14294:13;14309:9;14270:23;:49::i;:::-;13861:465;;;;:::o;8715:1263::-;8782:7;8802:27;8840:32;8882:34;8933:18;:25;;;;8919:40;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;8919:40:3;-1:-1:-1;8882:77:3;-1:-1:-1;8975:6:3;8970:397;8991:18;:25;8987:29;;8970:397;;;9054:9;;9092:18;:21;;-1:-1:-1;;;;;9054:9:3;;;;9041:50;;9092:18;9111:1;;9092:21;;;;;;;;;;;;;;;;;9041:73;;;-1:-1:-1;;;;;;9041:73:3;;;;;;;-1:-1:-1;;;;;9092:21:3;;;9041:73;;;;;;;;;;9092:21;9041:73;;;;;;;;;5:2:-1;;;;30:1;27;20:12;5:2;9041:73:3;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;9041:73:3;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;9041:73:3;9037:320;;;9174:18;9193:1;9174:21;;;;;;;;;;;;;;;;;;;9157:56;;;-1:-1:-1;;;9157:56:3;;;;-1:-1:-1;;;;;9174:21:3;;;;9157:54;;:56;;;;;;;;;;9174:21;9157:56;;;5:2:-1;;;;30:1;27;20:12;5:2;9157:56:3;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;9157:56:3;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;9157:56:3;9277:18;:21;;9134:79;;;;;9296:1;;9277:21;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;9277:21:3;9231:17;9249:24;9231:43;;;;;;;;-1:-1:-1;;;;;9231:67:3;;;:43;;;;;;;;;;;:67;9316:26;;;;;9037:320;9018:3;;8970:397;;;;9407:1;9385:19;:23;9377:85;;;;-1:-1:-1;;;9377:85:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9473:21;9504:19;9497:4;:26;;;;;;;-1:-1:-1;9534:24:3;;;9604:315;9628:24;9624:1;:28;9604:315;;;9711:17;9729:1;9711:20;;;;;;;;;;;;;;-1:-1:-1;;;;;9694:53:3;;:55;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9694:55:3;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;9694:55:3;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;9694:55:3;9673:76;;;;;9767:33;;;9763:114;;;9827:17;9845:16;9827:35;;;;;;;;;;;;;;9820:42;;;;;;;;;;;9763:114;9890:18;;;;;9654:3;9604:315;;;;9936:17;9954:16;9936:35;;;;;;;;;;;;;;9929:42;;;;;;;;8715:1263;;;:::o;14537:542::-;14634:39;14662:10;14634:18;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;14634:27:3;;;;;;;;;;;;;;;;;;;;;;:39;;;;:::i;:::-;14613:146;;;;-1:-1:-1;;;14613:146:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14841:1;14791:21;;;:10;:21;;;;;:38;-1:-1:-1;;;;;14791:38:3;14770:126;;;;;-1:-1:-1;;;14770:126:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;14907:21;;;;:10;:21;;;;;;;;;:38;14964:59;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;14964:59:3;;;;;;25:18:-1;;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;14907:126:3;;;;-1:-1:-1;;;;;14907:38:3;;;;:126;;;;25:18:-1;14907:126:3;;25:18:-1;36:153;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;14907:126:3;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;-1:-1;;;15051:21:3;;;;-1:-1:-1;15051:10:3;:21;;;;;15044:28;;-1:-1:-1;;;;;;15044:28:3;;;;;;;;;;;;;;;;;;;;;;;;;;;14537:542::o;16224:583::-;16337:7;;16488:17;;:58;;16529:16;;16512:34;;:12;;:34;:16;:34;:::i;:::-;16488:58;;;16508:1;16488:58;16466:80;-1:-1:-1;16767:33:3;16466:80;16783:16;16767:33;:15;:33;:::i;:::-;16760:40;;;16224:583;;;;;:::o;834:176:0:-;892:7;923:5;;;946:6;;;;938:46;;;;;-1:-1:-1;;;938:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;1002:1;834:176;-1:-1:-1;;;834:176:0:o;1274:134::-;1332:7;1358:43;1362:1;1365;1358:43;;;;;;;;;;;;;;;;;:3;:43::i;237:112:6:-;299:7;325:17;338:3;325:8;:1;331;325:8;:5;:8;:::i;:::-;:12;:17;:12;:17;:::i;351:553:5:-;458:17;;491:386;512:11;;508:15;;491:386;;;613:4;618:1;613:7;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;593:27:5;;;613:7;;593:27;589:278;;;714:1;700:101;721:11;;-1:-1:-1;;721:13:5;717:17;;700:101;;;773:4;778:1;780;778:3;773:9;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;773:9:5;763:4;768:1;763:7;;;;;;;;;;;;;;;;;:19;;-1:-1:-1;;;;;;763:19:5;-1:-1:-1;;;;;763:19:5;;;;;;;;;;-1:-1:-1;736:3:5;700:101;;;-1:-1:-1;818:13:5;;;:4;-1:-1:-1;;818:13:5;;;:::i;:::-;-1:-1:-1;;;849:3:5;589:278;525:3;;491:386;;;-1:-1:-1;893:4:5;;351:553;-1:-1:-1;;351:553:5:o;59:286::-;165:4;;185:132;206:4;:11;202:1;:15;185:132;;;254:4;259:1;254:7;;;;;;;;;;;;;;-1:-1:-1;;;;;242:19:5;:8;-1:-1:-1;;;;;242:19:5;;238:69;;;288:4;281:11;;;;;238:69;219:3;;185:132;;;-1:-1:-1;333:5:5;;59:286;-1:-1:-1;;;59:286:5:o;15331:580:3:-;15458:18;15477:25;;15425:30;;15458:18;15477:32;;15507:1;15477:32;:29;:32;:::i;:::-;15458:52;;;;;;;;;;;;;;;;;;;;15547:59;;;-1:-1:-1;;;15547:59:3;;;;-1:-1:-1;;;;;15458:52:3;;;;-1:-1:-1;15458:52:3;;15547:57;;:59;;;;;;;;;;15458:52;15547:59;;;5:2:-1;;;;30:1;27;20:12;5:2;15547:59:3;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;15547:59:3;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;15547:59:3;15621:11;;15547:59;;-1:-1:-1;15621:31:3;-1:-1:-1;15621:31:3;;;:102;;;15673:22;-1:-1:-1;;;;;15656:65:3;;:67;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;15656:67:3;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;15656:67:3;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;15656:67:3;15621:102;15617:288;;;15756:22;-1:-1:-1;;;;;15739:52:3;;15798:16;15816:5;15823:9;15739:94;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;15739:94:3;-1:-1:-1;;;;;15739:94:3;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;15739:94:3;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;15739:94:3;;;;;15861:33;15877:16;15861:11;;:15;;:33;;;;:::i;:::-;15847:11;:47;15331:580;;;;:::o;2159:459:0:-;2217:7;2458:6;2454:45;;-1:-1:-1;2487:1:0;2480:8;;2454:45;2521:5;;;2525:1;2521;:5;:1;2544:5;;;;;:10;2536:56;;;;-1:-1:-1;;;2536:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1732:187;1818:7;1853:12;1845:6;;;;1837:29;;;;-1:-1:-1;;;1837:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;1837:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;1888:5:0;;;1732:187::o;3073:130::-;3131:7;3157:39;3161:1;3164;3157:39;;;;;;;;;;;;;;;;;3804:7;3904:12;3897:5;3889:28;;;;-1:-1:-1;;;3889:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27:10:-1;;8:100;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;3889:28:0;;3927:9;3943:1;3939;:5;;;;;;;3718:338;-1:-1:-1;;;;;3718:338:0:o;3287:17699:3:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3287:17699:3;;;-1:-1:-1;3287:17699:3;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Swarm Source

bzzr://ee695e70629593412efef81cae0f44a7b65b97f7d3e8d28c5dfde087ff75edaa

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.