ETH Price: $2,993.25 (-2.04%)
Gas: 3 Gwei

Contract

0xC7B5aF82B05Eb3b64F12241B04B2cF14469E39F7
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
0x60806040134926302021-10-26 11:08:51985 days ago1635246531IN
 Create: Lido
0 ETH0.50541839108.29409395

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Lido

Compiler Version
v0.4.24+commit.e67f0147

Optimization Enabled:
Yes with 200 runs

Other Settings:
constantinople EvmVersion
File 1 of 33 : Lido.sol
// SPDX-FileCopyrightText: 2020 Lido <[email protected]>

// SPDX-License-Identifier: GPL-3.0

/* See contracts/COMPILERS.md */
pragma solidity 0.4.24;

import "@aragon/os/contracts/apps/AragonApp.sol";
import "@aragon/os/contracts/lib/math/SafeMath.sol";
import "@aragon/os/contracts/lib/math/SafeMath64.sol";
import "@aragon/os/contracts/common/IsContract.sol";
import "solidity-bytes-utils/contracts/BytesLib.sol";

import "./interfaces/ILido.sol";
import "./interfaces/INodeOperatorsRegistry.sol";
import "./interfaces/IDepositContract.sol";

import "./StETH.sol";


/**
* @title Liquid staking pool implementation
*
* Lido is an Ethereum 2.0 liquid staking protocol solving the problem of frozen staked Ethers
* until transfers become available in Ethereum 2.0.
* Whitepaper: https://lido.fi/static/Lido:Ethereum-Liquid-Staking.pdf
*
* NOTE: the code below assumes moderate amount of node operators, e.g. up to 50.
*
* Since balances of all token holders change when the amount of total pooled Ether
* changes, this token cannot fully implement ERC20 standard: it only emits `Transfer`
* events upon explicit transfer between holders. In contrast, when Lido oracle reports
* rewards, no Transfer events are generated: doing so would require emitting an event
* for each token holder and thus running an unbounded loop.
*/
contract Lido is ILido, IsContract, StETH, AragonApp {
    using SafeMath for uint256;
    using SafeMath64 for uint64;
    using UnstructuredStorage for bytes32;

    /// ACL
    bytes32 constant public PAUSE_ROLE = keccak256("PAUSE_ROLE");
    bytes32 constant public MANAGE_FEE = keccak256("MANAGE_FEE");
    bytes32 constant public MANAGE_WITHDRAWAL_KEY = keccak256("MANAGE_WITHDRAWAL_KEY");
    bytes32 constant public SET_ORACLE = keccak256("SET_ORACLE");
    bytes32 constant public BURN_ROLE = keccak256("BURN_ROLE");
    bytes32 constant public SET_TREASURY = keccak256("SET_TREASURY");
    bytes32 constant public SET_INSURANCE_FUND = keccak256("SET_INSURANCE_FUND");
    bytes32 constant public DEPOSIT_ROLE = keccak256("DEPOSIT_ROLE");

    uint256 constant public PUBKEY_LENGTH = 48;
    uint256 constant public WITHDRAWAL_CREDENTIALS_LENGTH = 32;
    uint256 constant public SIGNATURE_LENGTH = 96;

    uint256 constant public DEPOSIT_SIZE = 32 ether;

    uint256 internal constant DEPOSIT_AMOUNT_UNIT = 1000000000 wei;

    /// @dev default value for maximum number of Ethereum 2.0 validators registered in a single depositBufferedEther call
    uint256 internal constant DEFAULT_MAX_DEPOSITS_PER_CALL = 150;

    bytes32 internal constant FEE_POSITION = keccak256("lido.Lido.fee");
    bytes32 internal constant TREASURY_FEE_POSITION = keccak256("lido.Lido.treasuryFee");
    bytes32 internal constant INSURANCE_FEE_POSITION = keccak256("lido.Lido.insuranceFee");
    bytes32 internal constant NODE_OPERATORS_FEE_POSITION = keccak256("lido.Lido.nodeOperatorsFee");

    bytes32 internal constant DEPOSIT_CONTRACT_POSITION = keccak256("lido.Lido.depositContract");
    bytes32 internal constant ORACLE_POSITION = keccak256("lido.Lido.oracle");
    bytes32 internal constant NODE_OPERATORS_REGISTRY_POSITION = keccak256("lido.Lido.nodeOperatorsRegistry");
    bytes32 internal constant TREASURY_POSITION = keccak256("lido.Lido.treasury");
    bytes32 internal constant INSURANCE_FUND_POSITION = keccak256("lido.Lido.insuranceFund");

    /// @dev amount of Ether (on the current Ethereum side) buffered on this smart contract balance
    bytes32 internal constant BUFFERED_ETHER_POSITION = keccak256("lido.Lido.bufferedEther");
    /// @dev number of deposited validators (incrementing counter of deposit operations).
    bytes32 internal constant DEPOSITED_VALIDATORS_POSITION = keccak256("lido.Lido.depositedValidators");
    /// @dev total amount of Beacon-side Ether (sum of all the balances of Lido validators)
    bytes32 internal constant BEACON_BALANCE_POSITION = keccak256("lido.Lido.beaconBalance");
    /// @dev number of Lido's validators available in the Beacon state
    bytes32 internal constant BEACON_VALIDATORS_POSITION = keccak256("lido.Lido.beaconValidators");

    /// @dev Credentials which allows the DAO to withdraw Ether on the 2.0 side
    bytes32 internal constant WITHDRAWAL_CREDENTIALS_POSITION = keccak256("lido.Lido.withdrawalCredentials");

    /**
    * @dev As AragonApp, Lido contract must be initialized with following variables:
    * @param depositContract official ETH2 Deposit contract
    * @param _oracle oracle contract
    * @param _operators instance of Node Operators Registry
    */
    function initialize(
        IDepositContract depositContract,
        address _oracle,
        INodeOperatorsRegistry _operators,
        address _treasury,
        address _insuranceFund
    )
        public onlyInit
    {
        _setDepositContract(depositContract);
        _setOracle(_oracle);
        _setOperators(_operators);
        _setTreasury(_treasury);
        _setInsuranceFund(_insuranceFund);

        initialized();
    }

    /**
    * @notice Send funds to the pool
    * @dev Users are able to submit their funds by transacting to the fallback function.
    * Unlike vanilla Eth2.0 Deposit contract, accepting only 32-Ether transactions, Lido
    * accepts payments of any size. Submitted Ethers are stored in Buffer until someone calls
    * depositBufferedEther() and pushes them to the ETH2 Deposit contract.
    */
    function() external payable {
        // protection against accidental submissions by calling non-existent function
        require(msg.data.length == 0, "NON_EMPTY_DATA");
        _submit(0);
    }

    /**
    * @notice Send funds to the pool with optional _referral parameter
    * @dev This function is alternative way to submit funds. Supports optional referral address.
    * @return Amount of StETH shares generated
    */
    function submit(address _referral) external payable returns (uint256) {
        return _submit(_referral);
    }

    /**
    * @notice Deposits buffered ethers to the official DepositContract.
    * @dev This function is separated from submit() to reduce the cost of sending funds.
    */
    function depositBufferedEther() external auth(DEPOSIT_ROLE) {
        return _depositBufferedEther(DEFAULT_MAX_DEPOSITS_PER_CALL);
    }

    /**
      * @notice Deposits buffered ethers to the official DepositContract, making no more than `_maxDeposits` deposit calls.
      * @dev This function is separated from submit() to reduce the cost of sending funds.
      */
    function depositBufferedEther(uint256 _maxDeposits) external auth(DEPOSIT_ROLE) {
        return _depositBufferedEther(_maxDeposits);
    }

    function burnShares(address _account, uint256 _sharesAmount)
        external
        authP(BURN_ROLE, arr(_account, _sharesAmount))
        returns (uint256 newTotalShares)
    {
        return _burnShares(_account, _sharesAmount);
    }

    /**
      * @notice Stop pool routine operations
      */
    function stop() external auth(PAUSE_ROLE) {
        _stop();
    }

    /**
      * @notice Resume pool routine operations
      */
    function resume() external auth(PAUSE_ROLE) {
        _resume();
    }

    /**
      * @notice Set fee rate to `_feeBasisPoints` basis points. The fees are accrued when oracles report staking results
      * @param _feeBasisPoints Fee rate, in basis points
      */
    function setFee(uint16 _feeBasisPoints) external auth(MANAGE_FEE) {
        _setBPValue(FEE_POSITION, _feeBasisPoints);
        emit FeeSet(_feeBasisPoints);
    }

    /**
      * @notice Set fee distribution: `_treasuryFeeBasisPoints` basis points go to the treasury, `_insuranceFeeBasisPoints` basis points go to the insurance fund, `_operatorsFeeBasisPoints` basis points go to node operators. The sum has to be 10 000.
      */
    function setFeeDistribution(
        uint16 _treasuryFeeBasisPoints,
        uint16 _insuranceFeeBasisPoints,
        uint16 _operatorsFeeBasisPoints
    )
        external auth(MANAGE_FEE)
    {
        require(
            10000 == uint256(_treasuryFeeBasisPoints)
            .add(uint256(_insuranceFeeBasisPoints))
            .add(uint256(_operatorsFeeBasisPoints)),
            "FEES_DONT_ADD_UP"
        );

        _setBPValue(TREASURY_FEE_POSITION, _treasuryFeeBasisPoints);
        _setBPValue(INSURANCE_FEE_POSITION, _insuranceFeeBasisPoints);
        _setBPValue(NODE_OPERATORS_FEE_POSITION, _operatorsFeeBasisPoints);

        emit FeeDistributionSet(_treasuryFeeBasisPoints, _insuranceFeeBasisPoints, _operatorsFeeBasisPoints);
    }

    /**
      * @notice Set authorized oracle contract address to `_oracle`
      * @dev Contract specified here is allowed to make periodical updates of beacon states
      * by calling pushBeacon.
      * @param _oracle oracle contract
      */
    function setOracle(address _oracle) external auth(SET_ORACLE) {
        _setOracle(_oracle);
    }

    /**
      * @notice Set treasury contract address to `_treasury`
      * @dev Contract specified here is used to accumulate the protocol treasury fee.
      * @param _treasury contract which accumulates treasury fee.
      */
    function setTreasury(address _treasury) external auth(SET_TREASURY) {
        _setTreasury(_treasury);
    }

    /**
      * @notice Set insuranceFund contract address to `_insuranceFund`
      * @dev Contract specified here is used to accumulate the protocol insurance fee.
      * @param _insuranceFund contract which accumulates insurance fee.
      */
    function setInsuranceFund(address _insuranceFund) external auth(SET_INSURANCE_FUND) {
        _setInsuranceFund(_insuranceFund);
    }

    /**
      * @notice Set credentials to withdraw ETH on ETH 2.0 side after the phase 2 is launched to `_withdrawalCredentials`
      * @dev Note that setWithdrawalCredentials discards all unused signing keys as the signatures are invalidated.
      * @param _withdrawalCredentials hash of withdrawal multisignature key as accepted by
      *        the deposit_contract.deposit function
      */
    function setWithdrawalCredentials(bytes32 _withdrawalCredentials) external auth(MANAGE_WITHDRAWAL_KEY) {
        WITHDRAWAL_CREDENTIALS_POSITION.setStorageBytes32(_withdrawalCredentials);
        getOperators().trimUnusedKeys();

        emit WithdrawalCredentialsSet(_withdrawalCredentials);
    }

    /**
      * @notice Issues withdrawal request. Not implemented.
      * @param _amount Amount of StETH to withdraw
      * @param _pubkeyHash Receiving address
      */
    function withdraw(uint256 _amount, bytes32 _pubkeyHash) external whenNotStopped { /* solhint-disable-line no-unused-vars */
        //will be upgraded to an actual implementation when withdrawals are enabled (Phase 1.5 or 2 of Eth2 launch, likely late 2021 or 2022).
        //at the moment withdrawals are not possible in the beacon chain and there's no workaround
        revert("NOT_IMPLEMENTED_YET");
    }

    /**
    * @notice Updates the number of Lido-controlled keys in the beacon validators set and their total balance.
    * @dev periodically called by the Oracle contract
    * @param _beaconValidators number of Lido's keys in the beacon state
    * @param _beaconBalance simmarized balance of Lido-controlled keys in wei
    */
    function pushBeacon(uint256 _beaconValidators, uint256 _beaconBalance) external whenNotStopped {
        require(msg.sender == getOracle(), "APP_AUTH_FAILED");

        uint256 depositedValidators = DEPOSITED_VALIDATORS_POSITION.getStorageUint256();
        require(_beaconValidators <= depositedValidators, "REPORTED_MORE_DEPOSITED");

        uint256 beaconValidators = BEACON_VALIDATORS_POSITION.getStorageUint256();
        // Since the calculation of funds in the ingress queue is based on the number of validators
        // that are in a transient state (deposited but not seen on beacon yet), we can't decrease the previously
        // reported number (we'll be unable to figure out who is in the queue and count them).
        // See LIP-1 for details https://github.com/lidofinance/lido-improvement-proposals/blob/develop/LIPS/lip-1.md
        require(_beaconValidators >= beaconValidators, "REPORTED_LESS_VALIDATORS");
        uint256 appearedValidators = _beaconValidators.sub(beaconValidators);

        // RewardBase is the amount of money that is not included in the reward calculation
        // Just appeared validators * 32 added to the previously reported beacon balance
        uint256 rewardBase = (appearedValidators.mul(DEPOSIT_SIZE)).add(BEACON_BALANCE_POSITION.getStorageUint256());

        // Save the current beacon balance and validators to
        // calcuate rewards on the next push
        BEACON_BALANCE_POSITION.setStorageUint256(_beaconBalance);
        BEACON_VALIDATORS_POSITION.setStorageUint256(_beaconValidators);

        if (_beaconBalance > rewardBase) {
            uint256 rewards = _beaconBalance.sub(rewardBase);
            distributeRewards(rewards);
        }
    }

    /**
      * @notice Send funds to recovery Vault. Overrides default AragonApp behaviour.
      * @param _token Token to be sent to recovery vault.
      */
    function transferToVault(address _token) external {
        require(allowRecoverability(_token), "RECOVER_DISALLOWED");
        address vault = getRecoveryVault();
        require(isContract(vault), "RECOVER_VAULT_NOT_CONTRACT");

        uint256 balance;
        if (_token == ETH) {
            balance = _getUnaccountedEther();
            // Transfer replaced by call to prevent transfer gas amount issue    
            require(vault.call.value(balance)(), "RECOVER_TRANSFER_FAILED");
        } else {
            ERC20 token = ERC20(_token);
            balance = token.staticBalanceOf(this);
            // safeTransfer comes from overriden default implementation
            require(token.safeTransfer(vault, balance), "RECOVER_TOKEN_TRANSFER_FAILED");
        }

        emit RecoverToVault(vault, _token, balance);
    }

    /**
      * @notice Returns staking rewards fee rate
      */
    function getFee() external view returns (uint16 feeBasisPoints) {
        return _getFee();
    }

    /**
      * @notice Returns fee distribution proportion
      */
    function getFeeDistribution()
        external
        view
        returns (
            uint16 treasuryFeeBasisPoints,
            uint16 insuranceFeeBasisPoints,
            uint16 operatorsFeeBasisPoints
        )
    {
        return _getFeeDistribution();
    }

    /**
      * @notice Returns current credentials to withdraw ETH on ETH 2.0 side after the phase 2 is launched
      */
    function getWithdrawalCredentials() public view returns (bytes32) {
        return WITHDRAWAL_CREDENTIALS_POSITION.getStorageBytes32();
    }

    /**
    * @notice Get the amount of Ether temporary buffered on this contract balance
    * @dev Buffered balance is kept on the contract from the moment the funds are received from user
    * until the moment they are actually sent to the official Deposit contract.
    * @return uint256 of buffered funds in wei
    */
    function getBufferedEther() external view returns (uint256) {
        return _getBufferedEther();
    }

    /**
      * @notice Gets deposit contract handle
      */
    function getDepositContract() public view returns (IDepositContract) {
        return IDepositContract(DEPOSIT_CONTRACT_POSITION.getStorageAddress());
    }

    /**
    * @notice Gets authorized oracle address
    * @return address of oracle contract
    */
    function getOracle() public view returns (address) {
        return ORACLE_POSITION.getStorageAddress();
    }

    /**
      * @notice Gets node operators registry interface handle
      */
    function getOperators() public view returns (INodeOperatorsRegistry) {
        return INodeOperatorsRegistry(NODE_OPERATORS_REGISTRY_POSITION.getStorageAddress());
    }

    /**
      * @notice Returns the treasury address
      */
    function getTreasury() public view returns (address) {
        return TREASURY_POSITION.getStorageAddress();
    }

    /**
      * @notice Returns the insurance fund address
      */
    function getInsuranceFund() public view returns (address) {
        return INSURANCE_FUND_POSITION.getStorageAddress();
    }

    /**
    * @notice Returns the key values related to Beacon-side
    * @return depositedValidators - number of deposited validators
    * @return beaconValidators - number of Lido's validators visible in the Beacon state, reported by oracles
    * @return beaconBalance - total amount of Beacon-side Ether (sum of all the balances of Lido validators)
    */
    function getBeaconStat() public view returns (uint256 depositedValidators, uint256 beaconValidators, uint256 beaconBalance) {
        depositedValidators = DEPOSITED_VALIDATORS_POSITION.getStorageUint256();
        beaconValidators = BEACON_VALIDATORS_POSITION.getStorageUint256();
        beaconBalance = BEACON_BALANCE_POSITION.getStorageUint256();
    }

    /**
    * @dev Sets the address of Deposit contract
    * @param _contract the address of Deposit contract
    */
    function _setDepositContract(IDepositContract _contract) internal {
        require(isContract(address(_contract)), "NOT_A_CONTRACT");
        DEPOSIT_CONTRACT_POSITION.setStorageAddress(address(_contract));
    }

    /**
    * @dev Internal function to set authorized oracle address
    * @param _oracle oracle contract
    */
    function _setOracle(address _oracle) internal {
        require(isContract(_oracle), "NOT_A_CONTRACT");
        ORACLE_POSITION.setStorageAddress(_oracle);
    }

    /**
    * @dev Internal function to set node operator registry address
    * @param _r registry of node operators
    */
    function _setOperators(INodeOperatorsRegistry _r) internal {
        require(isContract(_r), "NOT_A_CONTRACT");
        NODE_OPERATORS_REGISTRY_POSITION.setStorageAddress(_r);
    }

    function _setTreasury(address _treasury) internal {
        require(_treasury != address(0), "SET_TREASURY_ZERO_ADDRESS");
        TREASURY_POSITION.setStorageAddress(_treasury);
    }

    function _setInsuranceFund(address _insuranceFund) internal {
        require(_insuranceFund != address(0), "SET_INSURANCE_FUND_ZERO_ADDRESS");
        INSURANCE_FUND_POSITION.setStorageAddress(_insuranceFund);
    }

    /**
    * @dev Process user deposit, mints liquid tokens and increase the pool buffer
    * @param _referral address of referral.
    * @return amount of StETH shares generated
    */
    function _submit(address _referral) internal whenNotStopped returns (uint256) {
        address sender = msg.sender;
        uint256 deposit = msg.value;
        require(deposit != 0, "ZERO_DEPOSIT");

        uint256 sharesAmount = getSharesByPooledEth(deposit);
        if (sharesAmount == 0) {
            // totalControlledEther is 0: either the first-ever deposit or complete slashing
            // assume that shares correspond to Ether 1-to-1
            sharesAmount = deposit;
        }

        _mintShares(sender, sharesAmount);
        _submitted(sender, deposit, _referral);
        _emitTransferAfterMintingShares(sender, sharesAmount);
        return sharesAmount;
    }

    /**
     * @dev Emits an {Transfer} event where from is 0 address. Indicates mint events.
     */
    function _emitTransferAfterMintingShares(address _to, uint256 _sharesAmount) internal {
        emit Transfer(address(0), _to, getPooledEthByShares(_sharesAmount));
    }

    /**
    * @dev Deposits buffered eth to the DepositContract and assigns chunked deposits to node operators
    */
    function _depositBufferedEther(uint256 _maxDeposits) internal whenNotStopped {
        uint256 buffered = _getBufferedEther();
        if (buffered >= DEPOSIT_SIZE) {
            uint256 unaccounted = _getUnaccountedEther();
            uint256 numDeposits = buffered.div(DEPOSIT_SIZE);
            _markAsUnbuffered(_ETH2Deposit(numDeposits < _maxDeposits ? numDeposits : _maxDeposits));
            assert(_getUnaccountedEther() == unaccounted);
        }
    }

    /**
    * @dev Performs deposits to the ETH 2.0 side
    * @param _numDeposits Number of deposits to perform
    * @return actually deposited Ether amount
    */
    function _ETH2Deposit(uint256 _numDeposits) internal returns (uint256) {
        (bytes memory pubkeys, bytes memory signatures) = getOperators().assignNextSigningKeys(_numDeposits);

        if (pubkeys.length == 0) {
            return 0;
        }

        require(pubkeys.length.mod(PUBKEY_LENGTH) == 0, "REGISTRY_INCONSISTENT_PUBKEYS_LEN");
        require(signatures.length.mod(SIGNATURE_LENGTH) == 0, "REGISTRY_INCONSISTENT_SIG_LEN");

        uint256 numKeys = pubkeys.length.div(PUBKEY_LENGTH);
        require(numKeys == signatures.length.div(SIGNATURE_LENGTH), "REGISTRY_INCONSISTENT_SIG_COUNT");

        for (uint256 i = 0; i < numKeys; ++i) {
            bytes memory pubkey = BytesLib.slice(pubkeys, i * PUBKEY_LENGTH, PUBKEY_LENGTH);
            bytes memory signature = BytesLib.slice(signatures, i * SIGNATURE_LENGTH, SIGNATURE_LENGTH);
            _stake(pubkey, signature);
        }

        DEPOSITED_VALIDATORS_POSITION.setStorageUint256(
            DEPOSITED_VALIDATORS_POSITION.getStorageUint256().add(numKeys)
        );

        return numKeys.mul(DEPOSIT_SIZE);
    }

    /**
    * @dev Invokes a deposit call to the official Deposit contract
    * @param _pubkey Validator to stake for
    * @param _signature Signature of the deposit call
    */
    function _stake(bytes memory _pubkey, bytes memory _signature) internal {
        bytes32 withdrawalCredentials = getWithdrawalCredentials();
        require(withdrawalCredentials != 0, "EMPTY_WITHDRAWAL_CREDENTIALS");

        uint256 value = DEPOSIT_SIZE;

        // The following computations and Merkle tree-ization will make official Deposit contract happy
        uint256 depositAmount = value.div(DEPOSIT_AMOUNT_UNIT);
        assert(depositAmount.mul(DEPOSIT_AMOUNT_UNIT) == value);    // properly rounded

        // Compute deposit data root (`DepositData` hash tree root) according to deposit_contract.sol
        bytes32 pubkeyRoot = sha256(_pad64(_pubkey));
        bytes32 signatureRoot = sha256(
            abi.encodePacked(
                sha256(BytesLib.slice(_signature, 0, 64)),
                sha256(_pad64(BytesLib.slice(_signature, 64, SIGNATURE_LENGTH.sub(64))))
            )
        );

        bytes32 depositDataRoot = sha256(
            abi.encodePacked(
                sha256(abi.encodePacked(pubkeyRoot, withdrawalCredentials)),
                sha256(abi.encodePacked(_toLittleEndian64(depositAmount), signatureRoot))
            )
        );

        uint256 targetBalance = address(this).balance.sub(value);

        getDepositContract().deposit.value(value)(
            _pubkey, abi.encodePacked(withdrawalCredentials), _signature, depositDataRoot);
        require(address(this).balance == targetBalance, "EXPECTING_DEPOSIT_TO_HAPPEN");
    }

    /**
    * @dev Distributes rewards by minting and distributing corresponding amount of liquid tokens.
    * @param _totalRewards Total rewards accrued on the Ethereum 2.0 side in wei
    */
    function distributeRewards(uint256 _totalRewards) internal {
        // We need to take a defined percentage of the reported reward as a fee, and we do
        // this by minting new token shares and assigning them to the fee recipients (see
        // StETH docs for the explanation of the shares mechanics). The staking rewards fee
        // is defined in basis points (1 basis point is equal to 0.01%, 10000 is 100%).
        //
        // Since we've increased totalPooledEther by _totalRewards (which is already
        // performed by the time this function is called), the combined cost of all holders'
        // shares has became _totalRewards StETH tokens more, effectively splitting the reward
        // between each token holder proportionally to their token share.
        //
        // Now we want to mint new shares to the fee recipient, so that the total cost of the
        // newly-minted shares exactly corresponds to the fee taken:
        //
        // shares2mint * newShareCost = (_totalRewards * feeBasis) / 10000
        // newShareCost = newTotalPooledEther / (prevTotalShares + shares2mint)
        //
        // which follows to:
        //
        //                        _totalRewards * feeBasis * prevTotalShares
        // shares2mint = --------------------------------------------------------------
        //                 (newTotalPooledEther * 10000) - (feeBasis * _totalRewards)
        //
        // The effect is that the given percentage of the reward goes to the fee recipient, and
        // the rest of the reward is distributed between token holders proportionally to their
        // token shares.
        uint256 feeBasis = _getFee();
        uint256 shares2mint = (
            _totalRewards.mul(feeBasis).mul(_getTotalShares())
            .div(
                _getTotalPooledEther().mul(10000)
                .sub(feeBasis.mul(_totalRewards))
            )
        );

        // Mint the calculated amount of shares to this contract address. This will reduce the
        // balances of the holders, as if the fee was taken in parts from each of them.
        _mintShares(address(this), shares2mint);

        (,uint16 insuranceFeeBasisPoints, uint16 operatorsFeeBasisPoints) = _getFeeDistribution();

        uint256 toInsuranceFund = shares2mint.mul(insuranceFeeBasisPoints).div(10000);
        address insuranceFund = getInsuranceFund();
        _transferShares(address(this), insuranceFund, toInsuranceFund);
        _emitTransferAfterMintingShares(insuranceFund, toInsuranceFund);

        uint256 distributedToOperatorsShares = _distributeNodeOperatorsReward(
            shares2mint.mul(operatorsFeeBasisPoints).div(10000)
        );

        // Transfer the rest of the fee to treasury
        uint256 toTreasury = shares2mint.sub(toInsuranceFund).sub(distributedToOperatorsShares);

        address treasury = getTreasury();
        _transferShares(address(this), treasury, toTreasury);
        _emitTransferAfterMintingShares(treasury, toTreasury);
    }

    function _distributeNodeOperatorsReward(uint256 _sharesToDistribute) internal returns (uint256 distributed) {
        (address[] memory recipients, uint256[] memory shares) = getOperators().getRewardsDistribution(_sharesToDistribute);

        assert(recipients.length == shares.length);

        distributed = 0;
        for (uint256 idx = 0; idx < recipients.length; ++idx) {
            _transferShares(
                address(this),
                recipients[idx],
                shares[idx]
            );
            _emitTransferAfterMintingShares(recipients[idx], shares[idx]);
            distributed = distributed.add(shares[idx]);
        }
    }

    /**
    * @dev Records a deposit made by a user with optional referral
    * @param _sender sender's address
    * @param _value Deposit value in wei
    * @param _referral address of the referral
    */
    function _submitted(address _sender, uint256 _value, address _referral) internal {
        BUFFERED_ETHER_POSITION.setStorageUint256(_getBufferedEther().add(_value));

        emit Submitted(_sender, _value, _referral);
    }

    /**
      * @dev Records a deposit to the deposit_contract.deposit function.
      * @param _amount Total amount deposited to the ETH 2.0 side
      */
    function _markAsUnbuffered(uint256 _amount) internal {
        BUFFERED_ETHER_POSITION.setStorageUint256(
            BUFFERED_ETHER_POSITION.getStorageUint256().sub(_amount));

        emit Unbuffered(_amount);
    }

    /**
      * @dev Write a value nominated in basis points
      */
    function _setBPValue(bytes32 _slot, uint16 _value) internal {
        require(_value <= 10000, "VALUE_OVER_100_PERCENT");
        _slot.setStorageUint256(uint256(_value));
    }

    /**
      * @dev Returns staking rewards fee rate
      */
    function _getFee() internal view returns (uint16) {
        return _readBPValue(FEE_POSITION);
    }

    /**
      * @dev Returns fee distribution proportion
      */
    function _getFeeDistribution() internal view
        returns (uint16 treasuryFeeBasisPoints, uint16 insuranceFeeBasisPoints, uint16 operatorsFeeBasisPoints)
    {
        treasuryFeeBasisPoints = _readBPValue(TREASURY_FEE_POSITION);
        insuranceFeeBasisPoints = _readBPValue(INSURANCE_FEE_POSITION);
        operatorsFeeBasisPoints = _readBPValue(NODE_OPERATORS_FEE_POSITION);
    }

    /**
      * @dev Read a value nominated in basis points
      */
    function _readBPValue(bytes32 _slot) internal view returns (uint16) {
        uint256 v = _slot.getStorageUint256();
        assert(v <= 10000);
        return uint16(v);
    }

    /**
      * @dev Gets the amount of Ether temporary buffered on this contract balance
      */
    function _getBufferedEther() internal view returns (uint256) {
        uint256 buffered = BUFFERED_ETHER_POSITION.getStorageUint256();
        assert(address(this).balance >= buffered);

        return buffered;
    }

    /**
      * @dev Gets unaccounted (excess) Ether on this contract balance
      */
    function _getUnaccountedEther() internal view returns (uint256) {
        return address(this).balance.sub(_getBufferedEther());
    }

    /**
    * @dev Calculates and returns the total base balance (multiple of 32) of validators in transient state,
    *      i.e. submitted to the official Deposit contract but not yet visible in the beacon state.
    * @return transient balance in wei (1e-18 Ether)
    */
    function _getTransientBalance() internal view returns (uint256) {
        uint256 depositedValidators = DEPOSITED_VALIDATORS_POSITION.getStorageUint256();
        uint256 beaconValidators = BEACON_VALIDATORS_POSITION.getStorageUint256();
        // beaconValidators can never be less than deposited ones.
        assert(depositedValidators >= beaconValidators);
        uint256 transientValidators = depositedValidators.sub(beaconValidators);
        return transientValidators.mul(DEPOSIT_SIZE);
    }

    /**
    * @dev Gets the total amount of Ether controlled by the system
    * @return total balance in wei
    */
    function _getTotalPooledEther() internal view returns (uint256) {
        uint256 bufferedBalance = _getBufferedEther();
        uint256 beaconBalance = BEACON_BALANCE_POSITION.getStorageUint256();
        uint256 transientBalance = _getTransientBalance();
        return bufferedBalance.add(beaconBalance).add(transientBalance);
    }

    /**
      * @dev Padding memory array with zeroes up to 64 bytes on the right
      * @param _b Memory array of size 32 .. 64
      */
    function _pad64(bytes memory _b) internal pure returns (bytes memory) {
        assert(_b.length >= 32 && _b.length <= 64);
        if (64 == _b.length)
            return _b;

        bytes memory zero32 = new bytes(32);
        assembly { mstore(add(zero32, 0x20), 0) }

        if (32 == _b.length)
            return BytesLib.concat(_b, zero32);
        else
            return BytesLib.concat(_b, BytesLib.slice(zero32, 0, uint256(64).sub(_b.length)));
    }

    /**
      * @dev Converting value to little endian bytes and padding up to 32 bytes on the right
      * @param _value Number less than `2**64` for compatibility reasons
      */
    function _toLittleEndian64(uint256 _value) internal pure returns (uint256 result) {
        result = 0;
        uint256 temp_value = _value;
        for (uint256 i = 0; i < 8; ++i) {
            result = (result << 8) | (temp_value & 0xFF);
            temp_value >>= 8;
        }

        assert(0 == temp_value);    // fully converted
        result <<= (24 * 8);
    }

    function to64(uint256 v) internal pure returns (uint64) {
        assert(v <= uint256(uint64(-1)));
        return uint64(v);
    }
}

File 2 of 33 : IDepositContract.sol
// SPDX-FileCopyrightText: 2020 Lido <[email protected]>

// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.4.24;


/**
  * @title Deposit contract interface
  */
interface IDepositContract {
    /**
      * @notice Top-ups deposit of a validator on the ETH 2.0 side
      * @param pubkey Validator signing key
      * @param withdrawal_credentials Credentials that allows to withdraw funds
      * @param signature Signature of the request
      * @param deposit_data_root The deposits Merkle tree node, used as a checksum
      */
    function deposit(
        bytes /* 48 */ pubkey,
        bytes /* 32 */ withdrawal_credentials,
        bytes /* 96 */ signature,
        bytes32 deposit_data_root
    )
        external payable;
}

File 3 of 33 : AragonApp.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.4.24;

import "./AppStorage.sol";
import "../acl/ACLSyntaxSugar.sol";
import "../common/Autopetrified.sol";
import "../common/ConversionHelpers.sol";
import "../common/ReentrancyGuard.sol";
import "../common/VaultRecoverable.sol";
import "../evmscript/EVMScriptRunner.sol";


// Contracts inheriting from AragonApp are, by default, immediately petrified upon deployment so
// that they can never be initialized.
// Unless overriden, this behaviour enforces those contracts to be usable only behind an AppProxy.
// ReentrancyGuard, EVMScriptRunner, and ACLSyntaxSugar are not directly used by this contract, but
// are included so that they are automatically usable by subclassing contracts
contract AragonApp is AppStorage, Autopetrified, VaultRecoverable, ReentrancyGuard, EVMScriptRunner, ACLSyntaxSugar {
    string private constant ERROR_AUTH_FAILED = "APP_AUTH_FAILED";

    modifier auth(bytes32 _role) {
        require(canPerform(msg.sender, _role, new uint256[](0)), ERROR_AUTH_FAILED);
        _;
    }

    modifier authP(bytes32 _role, uint256[] _params) {
        require(canPerform(msg.sender, _role, _params), ERROR_AUTH_FAILED);
        _;
    }

    /**
    * @dev Check whether an action can be performed by a sender for a particular role on this app
    * @param _sender Sender of the call
    * @param _role Role on this app
    * @param _params Permission params for the role
    * @return Boolean indicating whether the sender has the permissions to perform the action.
    *         Always returns false if the app hasn't been initialized yet.
    */
    function canPerform(address _sender, bytes32 _role, uint256[] _params) public view returns (bool) {
        if (!hasInitialized()) {
            return false;
        }

        IKernel linkedKernel = kernel();
        if (address(linkedKernel) == address(0)) {
            return false;
        }

        return linkedKernel.hasPermission(
            _sender,
            address(this),
            _role,
            ConversionHelpers.dangerouslyCastUintArrayToBytes(_params)
        );
    }

    /**
    * @dev Get the recovery vault for the app
    * @return Recovery vault address for the app
    */
    function getRecoveryVault() public view returns (address) {
        // Funds recovery via a vault is only available when used with a kernel
        return kernel().getRecoveryVault(); // if kernel is not set, it will revert
    }
}

File 4 of 33 : SafeMath.sol
// See https://github.com/OpenZeppelin/openzeppelin-solidity/blob/d51e38758e1d985661534534d5c61e27bece5042/contracts/math/SafeMath.sol
// Adapted to use pragma ^0.4.24 and satisfy our linter rules

pragma solidity ^0.4.24;


/**
 * @title SafeMath
 * @dev Math operations with safety checks that revert on error
 */
library SafeMath {
    string private constant ERROR_ADD_OVERFLOW = "MATH_ADD_OVERFLOW";
    string private constant ERROR_SUB_UNDERFLOW = "MATH_SUB_UNDERFLOW";
    string private constant ERROR_MUL_OVERFLOW = "MATH_MUL_OVERFLOW";
    string private constant ERROR_DIV_ZERO = "MATH_DIV_ZERO";

    /**
    * @dev Multiplies two numbers, reverts on 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-solidity/pull/522
        if (_a == 0) {
            return 0;
        }

        uint256 c = _a * _b;
        require(c / _a == _b, ERROR_MUL_OVERFLOW);

        return c;
    }

    /**
    * @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
    */
    function div(uint256 _a, uint256 _b) internal pure returns (uint256) {
        require(_b > 0, ERROR_DIV_ZERO); // Solidity only automatically asserts when dividing by 0
        uint256 c = _a / _b;
        // assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold

        return c;
    }

    /**
    * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
    */
    function sub(uint256 _a, uint256 _b) internal pure returns (uint256) {
        require(_b <= _a, ERROR_SUB_UNDERFLOW);
        uint256 c = _a - _b;

        return c;
    }

    /**
    * @dev Adds two numbers, reverts on overflow.
    */
    function add(uint256 _a, uint256 _b) internal pure returns (uint256) {
        uint256 c = _a + _b;
        require(c >= _a, ERROR_ADD_OVERFLOW);

        return c;
    }

    /**
    * @dev Divides two numbers and returns the remainder (unsigned integer modulo),
    * reverts when dividing by zero.
    */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0, ERROR_DIV_ZERO);
        return a % b;
    }
}

File 5 of 33 : SafeMath64.sol
// See https://github.com/OpenZeppelin/openzeppelin-solidity/blob/d51e38758e1d985661534534d5c61e27bece5042/contracts/math/SafeMath.sol
// Adapted for uint64, pragma ^0.4.24, and satisfying our linter rules
// Also optimized the mul() implementation, see https://github.com/aragon/aragonOS/pull/417

pragma solidity ^0.4.24;


/**
 * @title SafeMath64
 * @dev Math operations for uint64 with safety checks that revert on error
 */
library SafeMath64 {
    string private constant ERROR_ADD_OVERFLOW = "MATH64_ADD_OVERFLOW";
    string private constant ERROR_SUB_UNDERFLOW = "MATH64_SUB_UNDERFLOW";
    string private constant ERROR_MUL_OVERFLOW = "MATH64_MUL_OVERFLOW";
    string private constant ERROR_DIV_ZERO = "MATH64_DIV_ZERO";

    /**
    * @dev Multiplies two numbers, reverts on overflow.
    */
    function mul(uint64 _a, uint64 _b) internal pure returns (uint64) {
        uint256 c = uint256(_a) * uint256(_b);
        require(c < 0x010000000000000000, ERROR_MUL_OVERFLOW); // 2**64 (less gas this way)

        return uint64(c);
    }

    /**
    * @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
    */
    function div(uint64 _a, uint64 _b) internal pure returns (uint64) {
        require(_b > 0, ERROR_DIV_ZERO); // Solidity only automatically asserts when dividing by 0
        uint64 c = _a / _b;
        // assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold

        return c;
    }

    /**
    * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
    */
    function sub(uint64 _a, uint64 _b) internal pure returns (uint64) {
        require(_b <= _a, ERROR_SUB_UNDERFLOW);
        uint64 c = _a - _b;

        return c;
    }

    /**
    * @dev Adds two numbers, reverts on overflow.
    */
    function add(uint64 _a, uint64 _b) internal pure returns (uint64) {
        uint64 c = _a + _b;
        require(c >= _a, ERROR_ADD_OVERFLOW);

        return c;
    }

    /**
    * @dev Divides two numbers and returns the remainder (unsigned integer modulo),
    * reverts when dividing by zero.
    */
    function mod(uint64 a, uint64 b) internal pure returns (uint64) {
        require(b != 0, ERROR_DIV_ZERO);
        return a % b;
    }
}

File 6 of 33 : IsContract.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.4.24;


contract IsContract {
    /*
    * NOTE: this should NEVER be used for authentication
    * (see pitfalls: https://github.com/fergarrui/ethereum-security/tree/master/contracts/extcodesize).
    *
    * This is only intended to be used as a sanity check that an address is actually a contract,
    * RATHER THAN an address not being a contract.
    */
    function isContract(address _target) internal view returns (bool) {
        if (_target == address(0)) {
            return false;
        }

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

File 7 of 33 : BytesLib.sol
/*
 * @title Solidity Bytes Arrays Utils
 * @author Gonçalo Sá <[email protected]>
 *
 * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.
 *      The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.
 */

pragma solidity ^0.4.19;


library BytesLib {
    function concat(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bytes) {
        bytes memory tempBytes;

        assembly {
            // Get a location of some free memory and store it in tempBytes as
            // Solidity does for memory variables.
            tempBytes := mload(0x40)

            // Store the length of the first bytes array at the beginning of
            // the memory for tempBytes.
            let length := mload(_preBytes)
            mstore(tempBytes, length)

            // Maintain a memory counter for the current write location in the
            // temp bytes array by adding the 32 bytes for the array length to
            // the starting location.
            let mc := add(tempBytes, 0x20)
            // Stop copying when the memory counter reaches the length of the
            // first bytes array.
            let end := add(mc, length)

            for {
                // Initialize a copy counter to the start of the _preBytes data,
                // 32 bytes into its memory.
                let cc := add(_preBytes, 0x20)
            } lt(mc, end) {
                // Increase both counters by 32 bytes each iteration.
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                // Write the _preBytes data into the tempBytes memory 32 bytes
                // at a time.
                mstore(mc, mload(cc))
            }

            // Add the length of _postBytes to the current length of tempBytes
            // and store it as the new length in the first 32 bytes of the
            // tempBytes memory.
            length := mload(_postBytes)
            mstore(tempBytes, add(length, mload(tempBytes)))

            // Move the memory counter back from a multiple of 0x20 to the
            // actual end of the _preBytes data.
            mc := end
            // Stop copying when the memory counter reaches the new combined
            // length of the arrays.
            end := add(mc, length)

            for {
                let cc := add(_postBytes, 0x20)
            } lt(mc, end) {
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                mstore(mc, mload(cc))
            }

            // Update the free-memory pointer by padding our last write location
            // to 32 bytes: add 31 bytes to the end of tempBytes to move to the
            // next 32 byte block, then round down to the nearest multiple of
            // 32. If the sum of the length of the two arrays is zero then add 
            // one before rounding down to leave a blank 32 bytes (the length block with 0).
            mstore(0x40, and(
              add(add(end, iszero(add(length, mload(_preBytes)))), 31),
              not(31) // Round down to the nearest 32 bytes.
            ))
        }

        return tempBytes;
    }

    function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {
        assembly {
            // Read the first 32 bytes of _preBytes storage, which is the length
            // of the array. (We don't need to use the offset into the slot
            // because arrays use the entire slot.)
            let fslot := sload(_preBytes_slot)
            // Arrays of 31 bytes or less have an even value in their slot,
            // while longer arrays have an odd value. The actual length is
            // the slot divided by two for odd values, and the lowest order
            // byte divided by two for even values.
            // If the slot is even, bitwise and the slot with 255 and divide by
            // two to get the length. If the slot is odd, bitwise and the slot
            // with -1 and divide by two.
            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
            let mlength := mload(_postBytes)
            let newlength := add(slength, mlength)
            // slength can contain both the length and contents of the array
            // if length < 32 bytes so let's prepare for that
            // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
            switch add(lt(slength, 32), lt(newlength, 32))
            case 2 {
                // Since the new array still fits in the slot, we just need to
                // update the contents of the slot.
                // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length
                sstore(
                    _preBytes_slot,
                    // all the modifications to the slot are inside this
                    // next block
                    add(
                        // we can just add to the slot contents because the
                        // bytes we want to change are the LSBs
                        fslot,
                        add(
                            mul(
                                div(
                                    // load the bytes from memory
                                    mload(add(_postBytes, 0x20)),
                                    // zero all bytes to the right
                                    exp(0x100, sub(32, mlength))
                                ),
                                // and now shift left the number of bytes to
                                // leave space for the length in the slot
                                exp(0x100, sub(32, newlength))
                            ),
                            // increase length by the double of the memory
                            // bytes length
                            mul(mlength, 2)
                        )
                    )
                )
            }
            case 1 {
                // The stored value fits in the slot, but the combined value
                // will exceed it.
                // get the keccak hash to get the contents of the array
                mstore(0x0, _preBytes_slot)
                let sc := add(keccak256(0x0, 0x20), div(slength, 32))

                // save new length
                sstore(_preBytes_slot, add(mul(newlength, 2), 1))

                // The contents of the _postBytes array start 32 bytes into
                // the structure. Our first read should obtain the `submod`
                // bytes that can fit into the unused space in the last word
                // of the stored array. To get this, we read 32 bytes starting
                // from `submod`, so the data we read overlaps with the array
                // contents by `submod` bytes. Masking the lowest-order
                // `submod` bytes allows us to add that value directly to the
                // stored value.

                let submod := sub(32, slength)
                let mc := add(_postBytes, submod)
                let end := add(_postBytes, mlength)
                let mask := sub(exp(0x100, submod), 1)

                sstore(
                    sc,
                    add(
                        and(
                            fslot,
                            0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
                        ),
                        and(mload(mc), mask)
                    )
                )

                for {
                    mc := add(mc, 0x20)
                    sc := add(sc, 1)
                } lt(mc, end) {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } {
                    sstore(sc, mload(mc))
                }

                mask := exp(0x100, sub(mc, end))

                sstore(sc, mul(div(mload(mc), mask), mask))
            }
            default {
                // get the keccak hash to get the contents of the array
                mstore(0x0, _preBytes_slot)
                // Start copying to the last used word of the stored array.
                let sc := add(keccak256(0x0, 0x20), div(slength, 32))

                // save new length
                sstore(_preBytes_slot, add(mul(newlength, 2), 1))

                // Copy over the first `submod` bytes of the new data as in
                // case 1 above.
                let slengthmod := mod(slength, 32)
                let mlengthmod := mod(mlength, 32)
                let submod := sub(32, slengthmod)
                let mc := add(_postBytes, submod)
                let end := add(_postBytes, mlength)
                let mask := sub(exp(0x100, submod), 1)

                sstore(sc, add(sload(sc), and(mload(mc), mask)))
                
                for { 
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } lt(mc, end) {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } {
                    sstore(sc, mload(mc))
                }

                mask := exp(0x100, sub(mc, end))

                sstore(sc, mul(div(mload(mc), mask), mask))
            }
        }
    }

    function slice(bytes _bytes, uint _start, uint _length) internal  pure returns (bytes) {
        require(_bytes.length >= (_start + _length));

        bytes memory tempBytes;

        assembly {
            switch iszero(_length)
            case 0 {
                // Get a location of some free memory and store it in tempBytes as
                // Solidity does for memory variables.
                tempBytes := mload(0x40)

                // The first word of the slice result is potentially a partial
                // word read from the original array. To read it, we calculate
                // the length of that partial word and start copying that many
                // bytes into the array. The first word we copy will start with
                // data we don't care about, but the last `lengthmod` bytes will
                // land at the beginning of the contents of the new array. When
                // we're done copying, we overwrite the full first word with
                // the actual length of the slice.
                let lengthmod := and(_length, 31)

                // The multiplication in the next line is necessary
                // because when slicing multiples of 32 bytes (lengthmod == 0)
                // the following copy loop was copying the origin's length
                // and then ending prematurely not copying everything it should.
                let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
                let end := add(mc, _length)

                for {
                    // The multiplication in the next line has the same exact purpose
                    // as the one above.
                    let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
                } lt(mc, end) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                    mstore(mc, mload(cc))
                }

                mstore(tempBytes, _length)

                //update free-memory pointer
                //allocating the array padded to 32 bytes like the compiler does now
                mstore(0x40, and(add(mc, 31), not(31)))
            }
            //if we want a zero-length slice let's just return a zero-length array
            default {
                tempBytes := mload(0x40)

                mstore(0x40, add(tempBytes, 0x20))
            }
        }

        return tempBytes;
    }

    function toAddress(bytes _bytes, uint _start) internal  pure returns (address) {
        require(_bytes.length >= (_start + 20));
        address tempAddress;

        assembly {
            tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
        }

        return tempAddress;
    }

    function toUint8(bytes _bytes, uint _start) internal  pure returns (uint8) {
        require(_bytes.length >= (_start + 1));
        uint8 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x1), _start))
        }

        return tempUint;
    }

    function toUint16(bytes _bytes, uint _start) internal  pure returns (uint16) {
        require(_bytes.length >= (_start + 2));
        uint16 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x2), _start))
        }

        return tempUint;
    }

    function toUint32(bytes _bytes, uint _start) internal  pure returns (uint32) {
        require(_bytes.length >= (_start + 4));
        uint32 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x4), _start))
        }

        return tempUint;
    }

    function toUint(bytes _bytes, uint _start) internal  pure returns (uint256) {
        require(_bytes.length >= (_start + 32));
        uint256 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x20), _start))
        }

        return tempUint;
    }

    function toBytes32(bytes _bytes, uint _start) internal  pure returns (bytes32) {
        require(_bytes.length >= (_start + 32));
        bytes32 tempBytes32;

        assembly {
            tempBytes32 := mload(add(add(_bytes, 0x20), _start))
        }

        return tempBytes32;
    }

    function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {
        bool success = true;

        assembly {
            let length := mload(_preBytes)

            // if lengths don't match the arrays are not equal
            switch eq(length, mload(_postBytes))
            case 1 {
                // cb is a circuit breaker in the for loop since there's
                //  no said feature for inline assembly loops
                // cb = 1 - don't breaker
                // cb = 0 - break
                let cb := 1

                let mc := add(_preBytes, 0x20)
                let end := add(mc, length)

                for {
                    let cc := add(_postBytes, 0x20)
                // the next line is the loop condition:
                // while(uint(mc < end) + cb == 2)
                } eq(add(lt(mc, end), cb), 2) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                    // if any of these checks fails then arrays are not equal
                    if iszero(eq(mload(mc), mload(cc))) {
                        // unsuccess:
                        success := 0
                        cb := 0
                    }
                }
            }
            default {
                // unsuccess:
                success := 0
            }
        }

        return success;
    }

    function equalStorage(bytes storage _preBytes, bytes memory _postBytes) internal view returns (bool) {
        bool success = true;

        assembly {
            // we know _preBytes_offset is 0
            let fslot := sload(_preBytes_slot)
            // Decode the length of the stored array like in concatStorage().
            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
            let mlength := mload(_postBytes)

            // if lengths don't match the arrays are not equal
            switch eq(slength, mlength)
            case 1 {
                // slength can contain both the length and contents of the array
                // if length < 32 bytes so let's prepare for that
                // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
                if iszero(iszero(slength)) {
                    switch lt(slength, 32)
                    case 1 {
                        // blank the last byte which is the length
                        fslot := mul(div(fslot, 0x100), 0x100)

                        if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {
                            // unsuccess:
                            success := 0
                        }
                    }
                    default {
                        // cb is a circuit breaker in the for loop since there's
                        //  no said feature for inline assembly loops
                        // cb = 1 - don't breaker
                        // cb = 0 - break
                        let cb := 1

                        // get the keccak hash to get the contents of the array
                        mstore(0x0, _preBytes_slot)
                        let sc := keccak256(0x0, 0x20)

                        let mc := add(_postBytes, 0x20)
                        let end := add(mc, mlength)

                        // the next line is the loop condition:
                        // while(uint(mc < end) + cb == 2)
                        for {} eq(add(lt(mc, end), cb), 2) {
                            sc := add(sc, 1)
                            mc := add(mc, 0x20)
                        } {
                            if iszero(eq(sload(sc), mload(mc))) {
                                // unsuccess:
                                success := 0
                                cb := 0
                            }
                        }
                    }
                }
            }
            default {
                // unsuccess:
                success := 0
            }
        }

        return success;
    }
}

File 8 of 33 : ILido.sol
// SPDX-FileCopyrightText: 2020 Lido <[email protected]>

// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.4.24;


/**
  * @title Liquid staking pool
  *
  * For the high-level description of the pool operation please refer to the paper.
  * Pool manages withdrawal keys and fees. It receives ether submitted by users on the ETH 1 side
  * and stakes it via the deposit_contract.sol contract. It doesn't hold ether on it's balance,
  * only a small portion (buffer) of it.
  * It also mints new tokens for rewards generated at the ETH 2.0 side.
  */
interface ILido {
    /**
      * @notice Stop pool routine operations
      */
    function stop() external;

    /**
      * @notice Resume pool routine operations
      */
    function resume() external;

    event Stopped();
    event Resumed();


    /**
      * @notice Set fee rate to `_feeBasisPoints` basis points. The fees are accrued when oracles report staking results
      * @param _feeBasisPoints Fee rate, in basis points
      */
    function setFee(uint16 _feeBasisPoints) external;

    /**
      * @notice Set fee distribution: `_treasuryFeeBasisPoints` basis points go to the treasury, `_insuranceFeeBasisPoints` basis points go to the insurance fund, `_operatorsFeeBasisPoints` basis points go to node operators. The sum has to be 10 000.
      */
    function setFeeDistribution(
        uint16 _treasuryFeeBasisPoints,
        uint16 _insuranceFeeBasisPoints,
        uint16 _operatorsFeeBasisPoints)
        external;

    /**
      * @notice Returns staking rewards fee rate
      */
    function getFee() external view returns (uint16 feeBasisPoints);

    /**
      * @notice Returns fee distribution proportion
      */
    function getFeeDistribution() external view returns (uint16 treasuryFeeBasisPoints, uint16 insuranceFeeBasisPoints,
                                                         uint16 operatorsFeeBasisPoints);

    event FeeSet(uint16 feeBasisPoints);

    event FeeDistributionSet(uint16 treasuryFeeBasisPoints, uint16 insuranceFeeBasisPoints, uint16 operatorsFeeBasisPoints);


    /**
      * @notice Set credentials to withdraw ETH on ETH 2.0 side after the phase 2 is launched to `_withdrawalCredentials`
      * @dev Note that setWithdrawalCredentials discards all unused signing keys as the signatures are invalidated.
      * @param _withdrawalCredentials hash of withdrawal multisignature key as accepted by
      *        the deposit_contract.deposit function
      */
    function setWithdrawalCredentials(bytes32 _withdrawalCredentials) external;

    /**
      * @notice Returns current credentials to withdraw ETH on ETH 2.0 side after the phase 2 is launched
      */
    function getWithdrawalCredentials() external view returns (bytes);


    event WithdrawalCredentialsSet(bytes32 withdrawalCredentials);


    /**
      * @notice Ether on the ETH 2.0 side reported by the oracle
      * @param _epoch Epoch id
      * @param _eth2balance Balance in wei on the ETH 2.0 side
      */
    function pushBeacon(uint256 _epoch, uint256 _eth2balance) external;


    // User functions

    /**
      * @notice Adds eth to the pool
      * @return StETH Amount of StETH generated
      */
    function submit(address _referral) external payable returns (uint256 StETH);

    // Records a deposit made by a user
    event Submitted(address indexed sender, uint256 amount, address referral);

    // The `_amount` of ether was sent to the deposit_contract.deposit function.
    event Unbuffered(uint256 amount);

    /**
      * @notice Issues withdrawal request. Large withdrawals will be processed only after the phase 2 launch.
      * @param _amount Amount of StETH to burn
      * @param _pubkeyHash Receiving address
      */
    function withdraw(uint256 _amount, bytes32 _pubkeyHash) external;

    // Requested withdrawal of `etherAmount` to `pubkeyHash` on the ETH 2.0 side, `tokenAmount` burned by `sender`,
    // `sentFromBuffer` was sent on the current Ethereum side.
    event Withdrawal(address indexed sender, uint256 tokenAmount, uint256 sentFromBuffer,
                     bytes32 indexed pubkeyHash, uint256 etherAmount);


    // Info functions

    /**
      * @notice Gets the amount of Ether controlled by the system
      */
    function getTotalPooledEther() external view returns (uint256);

    /**
      * @notice Gets the amount of Ether temporary buffered on this contract balance
      */
    function getBufferedEther() external view returns (uint256);

    /**
      * @notice Returns the key values related to Beacon-side
      * @return depositedValidators - number of deposited validators
      * @return beaconValidators - number of Lido's validators visible in the Beacon state, reported by oracles
      * @return beaconBalance - total amount of Beacon-side Ether (sum of all the balances of Lido validators)
      */
    function getBeaconStat() external view returns (uint256 depositedValidators, uint256 beaconValidators, uint256 beaconBalance);
}

File 9 of 33 : INodeOperatorsRegistry.sol
// SPDX-FileCopyrightText: 2020 Lido <[email protected]>

// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.4.24;


/**
  * @title Node Operator registry
  *
  * Node Operator registry manages signing keys and other node operator data.
  * It's also responsible for distributing rewards to node operators.
  */
interface INodeOperatorsRegistry {
    /**
      * @notice Add node operator named `name` with reward address `rewardAddress` and staking limit `stakingLimit` validators
      * @param _name Human-readable name
      * @param _rewardAddress Ethereum 1 address which receives stETH rewards for this operator
      * @param _stakingLimit the maximum number of validators to stake for this operator
      * @return a unique key of the added operator
      */
    function addNodeOperator(string _name, address _rewardAddress, uint64 _stakingLimit) external returns (uint256 id);

    /**
      * @notice `_active ? 'Enable' : 'Disable'` the node operator #`_id`
      */
    function setNodeOperatorActive(uint256 _id, bool _active) external;

    /**
      * @notice Change human-readable name of the node operator #`_id` to `_name`
      */
    function setNodeOperatorName(uint256 _id, string _name) external;

    /**
      * @notice Change reward address of the node operator #`_id` to `_rewardAddress`
      */
    function setNodeOperatorRewardAddress(uint256 _id, address _rewardAddress) external;

    /**
      * @notice Set the maximum number of validators to stake for the node operator #`_id` to `_stakingLimit`
      */
    function setNodeOperatorStakingLimit(uint256 _id, uint64 _stakingLimit) external;

    /**
      * @notice Report `_stoppedIncrement` more stopped validators of the node operator #`_id`
      */
    function reportStoppedValidators(uint256 _id, uint64 _stoppedIncrement) external;

    /**
      * @notice Remove unused signing keys
      * @dev Function is used by the pool
      */
    function trimUnusedKeys() external;

    /**
      * @notice Returns total number of node operators
      */
    function getNodeOperatorsCount() external view returns (uint256);

    /**
      * @notice Returns number of active node operators
      */
    function getActiveNodeOperatorsCount() external view returns (uint256);

    /**
      * @notice Returns the n-th node operator
      * @param _id Node Operator id
      * @param _fullInfo If true, name will be returned as well
      */
    function getNodeOperator(uint256 _id, bool _fullInfo) external view returns (
        bool active,
        string name,
        address rewardAddress,
        uint64 stakingLimit,
        uint64 stoppedValidators,
        uint64 totalSigningKeys,
        uint64 usedSigningKeys);

    /**
      * @notice Returns the rewards distribution proportional to the effective stake for each node operator.
      * @param _totalRewardShares Total amount of reward shares to distribute.
      */
    function getRewardsDistribution(uint256 _totalRewardShares) external view returns (
        address[] memory recipients,
        uint256[] memory shares
    );

    event NodeOperatorAdded(uint256 id, string name, address rewardAddress, uint64 stakingLimit);
    event NodeOperatorActiveSet(uint256 indexed id, bool active);
    event NodeOperatorNameSet(uint256 indexed id, string name);
    event NodeOperatorRewardAddressSet(uint256 indexed id, address rewardAddress);
    event NodeOperatorStakingLimitSet(uint256 indexed id, uint64 stakingLimit);
    event NodeOperatorTotalStoppedValidatorsReported(uint256 indexed id, uint64 totalStopped);

    /**
     * @notice Selects and returns at most `_numKeys` signing keys (as well as the corresponding
     *         signatures) from the set of active keys and marks the selected keys as used.
     *         May only be called by the pool contract.
     *
     * @param _numKeys The number of keys to select. The actual number of selected keys may be less
     *        due to the lack of active keys.
     */
    function assignNextSigningKeys(uint256 _numKeys) external returns (bytes memory pubkeys, bytes memory signatures);

    /**
      * @notice Add `_quantity` validator signing keys to the keys of the node operator #`_operator_id`. Concatenated keys are: `_pubkeys`
      * @dev Along with each key the DAO has to provide a signatures for the
      *      (pubkey, withdrawal_credentials, 32000000000) message.
      *      Given that information, the contract'll be able to call
      *      deposit_contract.deposit on-chain.
      * @param _operator_id Node Operator id
      * @param _quantity Number of signing keys provided
      * @param _pubkeys Several concatenated validator signing keys
      * @param _signatures Several concatenated signatures for (pubkey, withdrawal_credentials, 32000000000) messages
      */
    function addSigningKeys(uint256 _operator_id, uint256 _quantity, bytes _pubkeys, bytes _signatures) external;

    /**
      * @notice Removes a validator signing key #`_index` from the keys of the node operator #`_operator_id`
      * @param _operator_id Node Operator id
      * @param _index Index of the key, starting with 0
      */
    function removeSigningKey(uint256 _operator_id, uint256 _index) external;

    /**
      * @notice Returns total number of signing keys of the node operator #`_operator_id`
      */
    function getTotalSigningKeyCount(uint256 _operator_id) external view returns (uint256);

    /**
      * @notice Returns number of usable signing keys of the node operator #`_operator_id`
      */
    function getUnusedSigningKeyCount(uint256 _operator_id) external view returns (uint256);

    /**
      * @notice Returns n-th signing key of the node operator #`_operator_id`
      * @param _operator_id Node Operator id
      * @param _index Index of the key, starting with 0
      * @return key Key
      * @return depositSignature Signature needed for a deposit_contract.deposit call
      * @return used Flag indication if the key was used in the staking
      */
    function getSigningKey(uint256 _operator_id, uint256 _index) external view returns
            (bytes key, bytes depositSignature, bool used);

    event SigningKeyAdded(uint256 indexed operatorId, bytes pubkey);
    event SigningKeyRemoved(uint256 indexed operatorId, bytes pubkey);
}

File 10 of 33 : StETH.sol
// SPDX-FileCopyrightText: 2020 Lido <[email protected]>

// SPDX-License-Identifier: GPL-3.0

/* See contracts/COMPILERS.md */
pragma solidity 0.4.24;

import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import "@aragon/os/contracts/common/UnstructuredStorage.sol";
import "@aragon/os/contracts/lib/math/SafeMath.sol";
import "./lib/Pausable.sol";

/**
 * @title Interest-bearing ERC20-like token for Lido Liquid Stacking protocol.
 *
 * This contract is abstract. To make the contract deployable override the
 * `_getTotalPooledEther` function. `Lido.sol` contract inherits StETH and defines
 * the `_getTotalPooledEther` function.
 *
 * StETH balances are dynamic and represent the holder's share in the total amount
 * of Ether controlled by the protocol. Account shares aren't normalized, so the
 * contract also stores the sum of all shares to calculate each account's token balance
 * which equals to:
 *
 *   shares[account] * _getTotalPooledEther() / _getTotalShares()
 *
 * For example, assume that we have:
 *
 *   _getTotalPooledEther() -> 10 ETH
 *   sharesOf(user1) -> 100
 *   sharesOf(user2) -> 400
 *
 * Therefore:
 *
 *   balanceOf(user1) -> 2 tokens which corresponds 2 ETH
 *   balanceOf(user2) -> 8 tokens which corresponds 8 ETH
 *
 * Since balances of all token holders change when the amount of total pooled Ether
 * changes, this token cannot fully implement ERC20 standard: it only emits `Transfer`
 * events upon explicit transfer between holders. In contrast, when total amount of
 * pooled Ether increases, no `Transfer` events are generated: doing so would require
 * emitting an event for each token holder and thus running an unbounded loop.
 *
 * The token inherits from `Pausable` and uses `whenNotStopped` modifier for methods
 * which change `shares` or `allowances`. `_stop` and `_resume` functions are overriden
 * in `Lido.sol` and might be called by an account with the `PAUSE_ROLE` assigned by the
 * DAO. This is useful for emergency scenarios, e.g. a protocol bug, where one might want
 * to freeze all token transfers and approvals until the emergency is resolved.
 */
contract StETH is IERC20, Pausable {
    using SafeMath for uint256;
    using UnstructuredStorage for bytes32;

    /**
     * @dev StETH balances are dynamic and are calculated based on the accounts' shares
     * and the total amount of Ether controlled by the protocol. Account shares aren't
     * normalized, so the contract also stores the sum of all shares to calculate
     * each account's token balance which equals to:
     *
     *   shares[account] * _getTotalPooledEther() / _getTotalShares()
    */
    mapping (address => uint256) private shares;

    /**
     * @dev Allowances are nominated in tokens, not token shares.
     */
    mapping (address => mapping (address => uint256)) private allowances;

    /**
     * @dev Storage position used for holding the total amount of shares in existence.
     *
     * The Lido protocol is built on top of Aragon and uses the Unstructured Storage pattern
     * for value types:
     *
     * https://blog.openzeppelin.com/upgradeability-using-unstructured-storage
     * https://blog.8bitzen.com/posts/20-02-2020-understanding-how-solidity-upgradeable-unstructured-proxies-work
     *
     * For reference types, conventional storage variables are used since it's non-trivial
     * and error-prone to implement reference-type unstructured storage using Solidity v0.4;
     * see https://github.com/lidofinance/lido-dao/issues/181#issuecomment-736098834
     */
    bytes32 internal constant TOTAL_SHARES_POSITION = keccak256("lido.StETH.totalShares");

    /**
     * @return the name of the token.
     */
    function name() public pure returns (string) {
        return "Liquid staked Ether 2.0";
    }

    /**
     * @return the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public pure returns (string) {
        return "stETH";
    }

    /**
     * @return the number of decimals for getting user representation of a token amount.
     */
    function decimals() public pure returns (uint8) {
        return 18;
    }

    /**
     * @return the amount of tokens in existence.
     *
     * @dev Always equals to `_getTotalPooledEther()` since token amount
     * is pegged to the total amount of Ether controlled by the protocol.
     */
    function totalSupply() public view returns (uint256) {
        return _getTotalPooledEther();
    }

    /**
     * @return the entire amount of Ether controlled by the protocol.
     *
     * @dev The sum of all ETH balances in the protocol, equals to the total supply of stETH.
     */
    function getTotalPooledEther() public view returns (uint256) {
        return _getTotalPooledEther();
    }

    /**
     * @return the amount of tokens owned by the `_account`.
     *
     * @dev Balances are dynamic and equal the `_account`'s share in the amount of the
     * total Ether controlled by the protocol. See `sharesOf`.
     */
    function balanceOf(address _account) public view returns (uint256) {
        return getPooledEthByShares(_sharesOf(_account));
    }

    /**
     * @notice Moves `_amount` tokens from the caller's account to the `_recipient` account.
     *
     * @return a boolean value indicating whether the operation succeeded.
     * Emits a `Transfer` event.
     *
     * Requirements:
     *
     * - `_recipient` cannot be the zero address.
     * - the caller must have a balance of at least `_amount`.
     * - the contract must not be paused.
     *
     * @dev The `_amount` argument is the amount of tokens, not shares.
     */
    function transfer(address _recipient, uint256 _amount) public returns (bool) {
        _transfer(msg.sender, _recipient, _amount);
        return true;
    }

    /**
     * @return the remaining number of tokens that `_spender` is allowed to spend
     * on behalf of `_owner` through `transferFrom`. This is zero by default.
     *
     * @dev This value changes when `approve` or `transferFrom` is called.
     */
    function allowance(address _owner, address _spender) public view returns (uint256) {
        return allowances[_owner][_spender];
    }

    /**
     * @notice Sets `_amount` as the allowance of `_spender` over the caller's tokens.
     *
     * @return a boolean value indicating whether the operation succeeded.
     * Emits an `Approval` event.
     *
     * Requirements:
     *
     * - `_spender` cannot be the zero address.
     * - the contract must not be paused.
     *
     * @dev The `_amount` argument is the amount of tokens, not shares.
     */
    function approve(address _spender, uint256 _amount) public returns (bool) {
        _approve(msg.sender, _spender, _amount);
        return true;
    }

    /**
     * @notice Moves `_amount` tokens from `_sender` to `_recipient` using the
     * allowance mechanism. `_amount` is then deducted from the caller's
     * allowance.
     *
     * @return a boolean value indicating whether the operation succeeded.
     *
     * Emits a `Transfer` event.
     * Emits an `Approval` event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `_sender` and `_recipient` cannot be the zero addresses.
     * - `_sender` must have a balance of at least `_amount`.
     * - the caller must have allowance for `_sender`'s tokens of at least `_amount`.
     * - the contract must not be paused.
     *
     * @dev The `_amount` argument is the amount of tokens, not shares.
     */
    function transferFrom(address _sender, address _recipient, uint256 _amount) public returns (bool) {
        uint256 currentAllowance = allowances[_sender][msg.sender];
        require(currentAllowance >= _amount, "TRANSFER_AMOUNT_EXCEEDS_ALLOWANCE");

        _transfer(_sender, _recipient, _amount);
        _approve(_sender, msg.sender, currentAllowance.sub(_amount));
        return true;
    }

    /**
     * @notice Atomically increases the allowance granted to `_spender` by the caller by `_addedValue`.
     *
     * This is an alternative to `approve` that can be used as a mitigation for
     * problems described in:
     * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol#L42
     * Emits an `Approval` event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `_spender` cannot be the the zero address.
     * - the contract must not be paused.
     */
    function increaseAllowance(address _spender, uint256 _addedValue) public returns (bool) {
        _approve(msg.sender, _spender, allowances[msg.sender][_spender].add(_addedValue));
        return true;
    }

    /**
     * @notice Atomically decreases the allowance granted to `_spender` by the caller by `_subtractedValue`.
     *
     * This is an alternative to `approve` that can be used as a mitigation for
     * problems described in:
     * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol#L42
     * Emits an `Approval` event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `_spender` cannot be the zero address.
     * - `_spender` must have allowance for the caller of at least `_subtractedValue`.
     * - the contract must not be paused.
     */
    function decreaseAllowance(address _spender, uint256 _subtractedValue) public returns (bool) {
        uint256 currentAllowance = allowances[msg.sender][_spender];
        require(currentAllowance >= _subtractedValue, "DECREASED_ALLOWANCE_BELOW_ZERO");
        _approve(msg.sender, _spender, currentAllowance.sub(_subtractedValue));
        return true;
    }

    /**
     * @return the total amount of shares in existence.
     *
     * @dev The sum of all accounts' shares can be an arbitrary number, therefore
     * it is necessary to store it in order to calculate each account's relative share.
     */
    function getTotalShares() public view returns (uint256) {
        return _getTotalShares();
    }

    /**
     * @return the amount of shares owned by `_account`.
     */
    function sharesOf(address _account) public view returns (uint256) {
        return _sharesOf(_account);
    }

    /**
     * @return the amount of shares that corresponds to `_ethAmount` protocol-controlled Ether.
     */
    function getSharesByPooledEth(uint256 _ethAmount) public view returns (uint256) {
        uint256 totalPooledEther = _getTotalPooledEther();
        if (totalPooledEther == 0) {
            return 0;
        } else {
            return _ethAmount
                .mul(_getTotalShares())
                .div(totalPooledEther);
        }
    }

    /**
     * @return the amount of Ether that corresponds to `_sharesAmount` token shares.
     */
    function getPooledEthByShares(uint256 _sharesAmount) public view returns (uint256) {
        uint256 totalShares = _getTotalShares();
        if (totalShares == 0) {
            return 0;
        } else {
            return _sharesAmount
                .mul(_getTotalPooledEther())
                .div(totalShares);
        }
    }

    /**
     * @return the total amount (in wei) of Ether controlled by the protocol.
     * @dev This is used for calaulating tokens from shares and vice versa.
     * @dev This function is required to be implemented in a derived contract.
     */
    function _getTotalPooledEther() internal view returns (uint256);

    /**
     * @notice Moves `_amount` tokens from `_sender` to `_recipient`.
     * Emits a `Transfer` event.
     */
    function _transfer(address _sender, address _recipient, uint256 _amount) internal {
        uint256 _sharesToTransfer = getSharesByPooledEth(_amount);
        _transferShares(_sender, _recipient, _sharesToTransfer);
        emit Transfer(_sender, _recipient, _amount);
    }

    /**
     * @notice Sets `_amount` as the allowance of `_spender` over the `_owner` s tokens.
     *
     * Emits an `Approval` event.
     *
     * Requirements:
     *
     * - `_owner` cannot be the zero address.
     * - `_spender` cannot be the zero address.
     * - the contract must not be paused.
     */
    function _approve(address _owner, address _spender, uint256 _amount) internal whenNotStopped {
        require(_owner != address(0), "APPROVE_FROM_ZERO_ADDRESS");
        require(_spender != address(0), "APPROVE_TO_ZERO_ADDRESS");

        allowances[_owner][_spender] = _amount;
        emit Approval(_owner, _spender, _amount);
    }

    /**
     * @return the total amount of shares in existence.
     */
    function _getTotalShares() internal view returns (uint256) {
        return TOTAL_SHARES_POSITION.getStorageUint256();
    }

    /**
     * @return the amount of shares owned by `_account`.
     */
    function _sharesOf(address _account) internal view returns (uint256) {
        return shares[_account];
    }

    /**
     * @notice Moves `_sharesAmount` shares from `_sender` to `_recipient`.
     *
     * Requirements:
     *
     * - `_sender` cannot be the zero address.
     * - `_recipient` cannot be the zero address.
     * - `_sender` must hold at least `_sharesAmount` shares.
     * - the contract must not be paused.
     */
    function _transferShares(address _sender, address _recipient, uint256 _sharesAmount) internal whenNotStopped {
        require(_sender != address(0), "TRANSFER_FROM_THE_ZERO_ADDRESS");
        require(_recipient != address(0), "TRANSFER_TO_THE_ZERO_ADDRESS");

        uint256 currentSenderShares = shares[_sender];
        require(_sharesAmount <= currentSenderShares, "TRANSFER_AMOUNT_EXCEEDS_BALANCE");

        shares[_sender] = currentSenderShares.sub(_sharesAmount);
        shares[_recipient] = shares[_recipient].add(_sharesAmount);
    }

    /**
     * @notice Creates `_sharesAmount` shares and assigns them to `_recipient`, increasing the total amount of shares.
     * @dev This doesn't increase the token total supply.
     *
     * Requirements:
     *
     * - `_recipient` cannot be the zero address.
     * - the contract must not be paused.
     */
    function _mintShares(address _recipient, uint256 _sharesAmount) internal whenNotStopped returns (uint256 newTotalShares) {
        require(_recipient != address(0), "MINT_TO_THE_ZERO_ADDRESS");

        newTotalShares = _getTotalShares().add(_sharesAmount);
        TOTAL_SHARES_POSITION.setStorageUint256(newTotalShares);

        shares[_recipient] = shares[_recipient].add(_sharesAmount);

        // Notice: we're not emitting a Transfer event from the zero address here since shares mint
        // works by taking the amount of tokens corresponding to the minted shares from all other
        // token holders, proportionally to their share. The total supply of the token doesn't change
        // as the result. This is equivalent to performing a send from each other token holder's
        // address to `address`, but we cannot reflect this as it would require sending an unbounded
        // number of events.
    }

    /**
     * @notice Destroys `_sharesAmount` shares from `_account`'s holdings, decreasing the total amount of shares.
     * @dev This doesn't decrease the token total supply.
     *
     * Requirements:
     *
     * - `_account` cannot be the zero address.
     * - `_account` must hold at least `_sharesAmount` shares.
     * - the contract must not be paused.
     */
    function _burnShares(address _account, uint256 _sharesAmount) internal whenNotStopped returns (uint256 newTotalShares) {
        require(_account != address(0), "BURN_FROM_THE_ZERO_ADDRESS");

        uint256 accountShares = shares[_account];
        require(_sharesAmount <= accountShares, "BURN_AMOUNT_EXCEEDS_BALANCE");

        newTotalShares = _getTotalShares().sub(_sharesAmount);
        TOTAL_SHARES_POSITION.setStorageUint256(newTotalShares);

        shares[_account] = accountShares.sub(_sharesAmount);

        // Notice: we're not emitting a Transfer event to the zero address here since shares burn
        // works by redistributing the amount of tokens corresponding to the burned shares between
        // all other token holders. The total supply of the token doesn't change as the result.
        // This is equivalent to performing a send from `address` to each other token holder address,
        // but we cannot reflect this as it would require sending an unbounded number of events.
    }
}

File 11 of 33 : AppStorage.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.4.24;

import "../common/UnstructuredStorage.sol";
import "../kernel/IKernel.sol";


contract AppStorage {
    using UnstructuredStorage for bytes32;

    /* Hardcoded constants to save gas
    bytes32 internal constant KERNEL_POSITION = keccak256("aragonOS.appStorage.kernel");
    bytes32 internal constant APP_ID_POSITION = keccak256("aragonOS.appStorage.appId");
    */
    bytes32 internal constant KERNEL_POSITION = 0x4172f0f7d2289153072b0a6ca36959e0cbe2efc3afe50fc81636caa96338137b;
    bytes32 internal constant APP_ID_POSITION = 0xd625496217aa6a3453eecb9c3489dc5a53e6c67b444329ea2b2cbc9ff547639b;

    function kernel() public view returns (IKernel) {
        return IKernel(KERNEL_POSITION.getStorageAddress());
    }

    function appId() public view returns (bytes32) {
        return APP_ID_POSITION.getStorageBytes32();
    }

    function setKernel(IKernel _kernel) internal {
        KERNEL_POSITION.setStorageAddress(address(_kernel));
    }

    function setAppId(bytes32 _appId) internal {
        APP_ID_POSITION.setStorageBytes32(_appId);
    }
}

File 12 of 33 : ACLSyntaxSugar.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.4.24;


contract ACLSyntaxSugar {
    function arr() internal pure returns (uint256[]) {
        return new uint256[](0);
    }

    function arr(bytes32 _a) internal pure returns (uint256[] r) {
        return arr(uint256(_a));
    }

    function arr(bytes32 _a, bytes32 _b) internal pure returns (uint256[] r) {
        return arr(uint256(_a), uint256(_b));
    }

    function arr(address _a) internal pure returns (uint256[] r) {
        return arr(uint256(_a));
    }

    function arr(address _a, address _b) internal pure returns (uint256[] r) {
        return arr(uint256(_a), uint256(_b));
    }

    function arr(address _a, uint256 _b, uint256 _c) internal pure returns (uint256[] r) {
        return arr(uint256(_a), _b, _c);
    }

    function arr(address _a, uint256 _b, uint256 _c, uint256 _d) internal pure returns (uint256[] r) {
        return arr(uint256(_a), _b, _c, _d);
    }

    function arr(address _a, uint256 _b) internal pure returns (uint256[] r) {
        return arr(uint256(_a), uint256(_b));
    }

    function arr(address _a, address _b, uint256 _c, uint256 _d, uint256 _e) internal pure returns (uint256[] r) {
        return arr(uint256(_a), uint256(_b), _c, _d, _e);
    }

    function arr(address _a, address _b, address _c) internal pure returns (uint256[] r) {
        return arr(uint256(_a), uint256(_b), uint256(_c));
    }

    function arr(address _a, address _b, uint256 _c) internal pure returns (uint256[] r) {
        return arr(uint256(_a), uint256(_b), uint256(_c));
    }

    function arr(uint256 _a) internal pure returns (uint256[] r) {
        r = new uint256[](1);
        r[0] = _a;
    }

    function arr(uint256 _a, uint256 _b) internal pure returns (uint256[] r) {
        r = new uint256[](2);
        r[0] = _a;
        r[1] = _b;
    }

    function arr(uint256 _a, uint256 _b, uint256 _c) internal pure returns (uint256[] r) {
        r = new uint256[](3);
        r[0] = _a;
        r[1] = _b;
        r[2] = _c;
    }

    function arr(uint256 _a, uint256 _b, uint256 _c, uint256 _d) internal pure returns (uint256[] r) {
        r = new uint256[](4);
        r[0] = _a;
        r[1] = _b;
        r[2] = _c;
        r[3] = _d;
    }

    function arr(uint256 _a, uint256 _b, uint256 _c, uint256 _d, uint256 _e) internal pure returns (uint256[] r) {
        r = new uint256[](5);
        r[0] = _a;
        r[1] = _b;
        r[2] = _c;
        r[3] = _d;
        r[4] = _e;
    }
}


contract ACLHelpers {
    function decodeParamOp(uint256 _x) internal pure returns (uint8 b) {
        return uint8(_x >> (8 * 30));
    }

    function decodeParamId(uint256 _x) internal pure returns (uint8 b) {
        return uint8(_x >> (8 * 31));
    }

    function decodeParamsList(uint256 _x) internal pure returns (uint32 a, uint32 b, uint32 c) {
        a = uint32(_x);
        b = uint32(_x >> (8 * 4));
        c = uint32(_x >> (8 * 8));
    }
}

File 13 of 33 : Autopetrified.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.4.24;

import "./Petrifiable.sol";


contract Autopetrified is Petrifiable {
    constructor() public {
        // Immediately petrify base (non-proxy) instances of inherited contracts on deploy.
        // This renders them uninitializable (and unusable without a proxy).
        petrify();
    }
}

File 14 of 33 : ConversionHelpers.sol
pragma solidity ^0.4.24;


library ConversionHelpers {
    string private constant ERROR_IMPROPER_LENGTH = "CONVERSION_IMPROPER_LENGTH";

    function dangerouslyCastUintArrayToBytes(uint256[] memory _input) internal pure returns (bytes memory output) {
        // Force cast the uint256[] into a bytes array, by overwriting its length
        // Note that the bytes array doesn't need to be initialized as we immediately overwrite it
        // with the input and a new length. The input becomes invalid from this point forward.
        uint256 byteLength = _input.length * 32;
        assembly {
            output := _input
            mstore(output, byteLength)
        }
    }

    function dangerouslyCastBytesToUintArray(bytes memory _input) internal pure returns (uint256[] memory output) {
        // Force cast the bytes array into a uint256[], by overwriting its length
        // Note that the uint256[] doesn't need to be initialized as we immediately overwrite it
        // with the input and a new length. The input becomes invalid from this point forward.
        uint256 intsLength = _input.length / 32;
        require(_input.length == intsLength * 32, ERROR_IMPROPER_LENGTH);

        assembly {
            output := _input
            mstore(output, intsLength)
        }
    }
}

File 15 of 33 : ReentrancyGuard.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.4.24;

import "../common/UnstructuredStorage.sol";


contract ReentrancyGuard {
    using UnstructuredStorage for bytes32;

    /* Hardcoded constants to save gas
    bytes32 internal constant REENTRANCY_MUTEX_POSITION = keccak256("aragonOS.reentrancyGuard.mutex");
    */
    bytes32 private constant REENTRANCY_MUTEX_POSITION = 0xe855346402235fdd185c890e68d2c4ecad599b88587635ee285bce2fda58dacb;

    string private constant ERROR_REENTRANT = "REENTRANCY_REENTRANT_CALL";

    modifier nonReentrant() {
        // Ensure mutex is unlocked
        require(!REENTRANCY_MUTEX_POSITION.getStorageBool(), ERROR_REENTRANT);

        // Lock mutex before function call
        REENTRANCY_MUTEX_POSITION.setStorageBool(true);

        // Perform function call
        _;

        // Unlock mutex after function call
        REENTRANCY_MUTEX_POSITION.setStorageBool(false);
    }
}

File 16 of 33 : VaultRecoverable.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.4.24;

import "../lib/token/ERC20.sol";
import "./EtherTokenConstant.sol";
import "./IsContract.sol";
import "./IVaultRecoverable.sol";
import "./SafeERC20.sol";


contract VaultRecoverable is IVaultRecoverable, EtherTokenConstant, IsContract {
    using SafeERC20 for ERC20;

    string private constant ERROR_DISALLOWED = "RECOVER_DISALLOWED";
    string private constant ERROR_VAULT_NOT_CONTRACT = "RECOVER_VAULT_NOT_CONTRACT";
    string private constant ERROR_TOKEN_TRANSFER_FAILED = "RECOVER_TOKEN_TRANSFER_FAILED";

    /**
     * @notice Send funds to recovery Vault. This contract should never receive funds,
     *         but in case it does, this function allows one to recover them.
     * @param _token Token balance to be sent to recovery vault.
     */
    function transferToVault(address _token) external {
        require(allowRecoverability(_token), ERROR_DISALLOWED);
        address vault = getRecoveryVault();
        require(isContract(vault), ERROR_VAULT_NOT_CONTRACT);

        uint256 balance;
        if (_token == ETH) {
            balance = address(this).balance;
            vault.transfer(balance);
        } else {
            ERC20 token = ERC20(_token);
            balance = token.staticBalanceOf(this);
            require(token.safeTransfer(vault, balance), ERROR_TOKEN_TRANSFER_FAILED);
        }

        emit RecoverToVault(vault, _token, balance);
    }

    /**
    * @dev By default deriving from AragonApp makes it recoverable
    * @param token Token address that would be recovered
    * @return bool whether the app allows the recovery
    */
    function allowRecoverability(address token) public view returns (bool) {
        return true;
    }

    // Cast non-implemented interface to be public so we can use it internally
    function getRecoveryVault() public view returns (address);
}

File 17 of 33 : EVMScriptRunner.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.4.24;

import "./IEVMScriptExecutor.sol";
import "./IEVMScriptRegistry.sol";

import "../apps/AppStorage.sol";
import "../kernel/KernelConstants.sol";
import "../common/Initializable.sol";


contract EVMScriptRunner is AppStorage, Initializable, EVMScriptRegistryConstants, KernelNamespaceConstants {
    string private constant ERROR_EXECUTOR_UNAVAILABLE = "EVMRUN_EXECUTOR_UNAVAILABLE";
    string private constant ERROR_PROTECTED_STATE_MODIFIED = "EVMRUN_PROTECTED_STATE_MODIFIED";

    /* This is manually crafted in assembly
    string private constant ERROR_EXECUTOR_INVALID_RETURN = "EVMRUN_EXECUTOR_INVALID_RETURN";
    */

    event ScriptResult(address indexed executor, bytes script, bytes input, bytes returnData);

    function getEVMScriptExecutor(bytes _script) public view returns (IEVMScriptExecutor) {
        return IEVMScriptExecutor(getEVMScriptRegistry().getScriptExecutor(_script));
    }

    function getEVMScriptRegistry() public view returns (IEVMScriptRegistry) {
        address registryAddr = kernel().getApp(KERNEL_APP_ADDR_NAMESPACE, EVMSCRIPT_REGISTRY_APP_ID);
        return IEVMScriptRegistry(registryAddr);
    }

    function runScript(bytes _script, bytes _input, address[] _blacklist)
        internal
        isInitialized
        protectState
        returns (bytes)
    {
        IEVMScriptExecutor executor = getEVMScriptExecutor(_script);
        require(address(executor) != address(0), ERROR_EXECUTOR_UNAVAILABLE);

        bytes4 sig = executor.execScript.selector;
        bytes memory data = abi.encodeWithSelector(sig, _script, _input, _blacklist);

        bytes memory output;
        assembly {
            let success := delegatecall(
                gas,                // forward all gas
                executor,           // address
                add(data, 0x20),    // calldata start
                mload(data),        // calldata length
                0,                  // don't write output (we'll handle this ourselves)
                0                   // don't write output
            )

            output := mload(0x40) // free mem ptr get

            switch success
            case 0 {
                // If the call errored, forward its full error data
                returndatacopy(output, 0, returndatasize)
                revert(output, returndatasize)
            }
            default {
                switch gt(returndatasize, 0x3f)
                case 0 {
                    // Need at least 0x40 bytes returned for properly ABI-encoded bytes values,
                    // revert with "EVMRUN_EXECUTOR_INVALID_RETURN"
                    // See remix: doing a `revert("EVMRUN_EXECUTOR_INVALID_RETURN")` always results in
                    // this memory layout
                    mstore(output, 0x08c379a000000000000000000000000000000000000000000000000000000000)         // error identifier
                    mstore(add(output, 0x04), 0x0000000000000000000000000000000000000000000000000000000000000020) // starting offset
                    mstore(add(output, 0x24), 0x000000000000000000000000000000000000000000000000000000000000001e) // reason length
                    mstore(add(output, 0x44), 0x45564d52554e5f4558454355544f525f494e56414c49445f52455455524e0000) // reason

                    revert(output, 100) // 100 = 4 + 3 * 32 (error identifier + 3 words for the ABI encoded error)
                }
                default {
                    // Copy result
                    //
                    // Needs to perform an ABI decode for the expected `bytes` return type of
                    // `executor.execScript()` as solidity will automatically ABI encode the returned bytes as:
                    //    [ position of the first dynamic length return value = 0x20 (32 bytes) ]
                    //    [ output length (32 bytes) ]
                    //    [ output content (N bytes) ]
                    //
                    // Perform the ABI decode by ignoring the first 32 bytes of the return data
                    let copysize := sub(returndatasize, 0x20)
                    returndatacopy(output, 0x20, copysize)

                    mstore(0x40, add(output, copysize)) // free mem ptr set
                }
            }
        }

        emit ScriptResult(address(executor), _script, _input, output);

        return output;
    }

    modifier protectState {
        address preKernel = address(kernel());
        bytes32 preAppId = appId();
        _; // exec
        require(address(kernel()) == preKernel, ERROR_PROTECTED_STATE_MODIFIED);
        require(appId() == preAppId, ERROR_PROTECTED_STATE_MODIFIED);
    }
}

File 18 of 33 : UnstructuredStorage.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.4.24;


library UnstructuredStorage {
    function getStorageBool(bytes32 position) internal view returns (bool data) {
        assembly { data := sload(position) }
    }

    function getStorageAddress(bytes32 position) internal view returns (address data) {
        assembly { data := sload(position) }
    }

    function getStorageBytes32(bytes32 position) internal view returns (bytes32 data) {
        assembly { data := sload(position) }
    }

    function getStorageUint256(bytes32 position) internal view returns (uint256 data) {
        assembly { data := sload(position) }
    }

    function setStorageBool(bytes32 position, bool data) internal {
        assembly { sstore(position, data) }
    }

    function setStorageAddress(bytes32 position, address data) internal {
        assembly { sstore(position, data) }
    }

    function setStorageBytes32(bytes32 position, bytes32 data) internal {
        assembly { sstore(position, data) }
    }

    function setStorageUint256(bytes32 position, uint256 data) internal {
        assembly { sstore(position, data) }
    }
}

File 19 of 33 : IKernel.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.4.24;

import "../acl/IACL.sol";
import "../common/IVaultRecoverable.sol";


interface IKernelEvents {
    event SetApp(bytes32 indexed namespace, bytes32 indexed appId, address app);
}


// This should be an interface, but interfaces can't inherit yet :(
contract IKernel is IKernelEvents, IVaultRecoverable {
    function acl() public view returns (IACL);
    function hasPermission(address who, address where, bytes32 what, bytes how) public view returns (bool);

    function setApp(bytes32 namespace, bytes32 appId, address app) public;
    function getApp(bytes32 namespace, bytes32 appId) public view returns (address);
}

File 20 of 33 : IACL.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.4.24;


interface IACL {
    function initialize(address permissionsCreator) external;

    // TODO: this should be external
    // See https://github.com/ethereum/solidity/issues/4832
    function hasPermission(address who, address where, bytes32 what, bytes how) public view returns (bool);
}

File 21 of 33 : IVaultRecoverable.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.4.24;


interface IVaultRecoverable {
    event RecoverToVault(address indexed vault, address indexed token, uint256 amount);

    function transferToVault(address token) external;

    function allowRecoverability(address token) external view returns (bool);
    function getRecoveryVault() external view returns (address);
}

File 22 of 33 : Petrifiable.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.4.24;

import "./Initializable.sol";


contract Petrifiable is Initializable {
    // Use block UINT256_MAX (which should be never) as the initializable date
    uint256 internal constant PETRIFIED_BLOCK = uint256(-1);

    function isPetrified() public view returns (bool) {
        return getInitializationBlock() == PETRIFIED_BLOCK;
    }

    /**
    * @dev Function to be called by top level contract to prevent being initialized.
    *      Useful for freezing base contracts when they're used behind proxies.
    */
    function petrify() internal onlyInit {
        initializedAt(PETRIFIED_BLOCK);
    }
}

File 23 of 33 : Initializable.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.4.24;

import "./TimeHelpers.sol";
import "./UnstructuredStorage.sol";


contract Initializable is TimeHelpers {
    using UnstructuredStorage for bytes32;

    // keccak256("aragonOS.initializable.initializationBlock")
    bytes32 internal constant INITIALIZATION_BLOCK_POSITION = 0xebb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e;

    string private constant ERROR_ALREADY_INITIALIZED = "INIT_ALREADY_INITIALIZED";
    string private constant ERROR_NOT_INITIALIZED = "INIT_NOT_INITIALIZED";

    modifier onlyInit {
        require(getInitializationBlock() == 0, ERROR_ALREADY_INITIALIZED);
        _;
    }

    modifier isInitialized {
        require(hasInitialized(), ERROR_NOT_INITIALIZED);
        _;
    }

    /**
    * @return Block number in which the contract was initialized
    */
    function getInitializationBlock() public view returns (uint256) {
        return INITIALIZATION_BLOCK_POSITION.getStorageUint256();
    }

    /**
    * @return Whether the contract has been initialized by the time of the current block
    */
    function hasInitialized() public view returns (bool) {
        uint256 initializationBlock = getInitializationBlock();
        return initializationBlock != 0 && getBlockNumber() >= initializationBlock;
    }

    /**
    * @dev Function to be called by top level contract after initialization has finished.
    */
    function initialized() internal onlyInit {
        INITIALIZATION_BLOCK_POSITION.setStorageUint256(getBlockNumber());
    }

    /**
    * @dev Function to be called by top level contract after initialization to enable the contract
    *      at a future block number rather than immediately.
    */
    function initializedAt(uint256 _blockNumber) internal onlyInit {
        INITIALIZATION_BLOCK_POSITION.setStorageUint256(_blockNumber);
    }
}

File 24 of 33 : TimeHelpers.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.4.24;

import "./Uint256Helpers.sol";


contract TimeHelpers {
    using Uint256Helpers for uint256;

    /**
    * @dev Returns the current block number.
    *      Using a function rather than `block.number` allows us to easily mock the block number in
    *      tests.
    */
    function getBlockNumber() internal view returns (uint256) {
        return block.number;
    }

    /**
    * @dev Returns the current block number, converted to uint64.
    *      Using a function rather than `block.number` allows us to easily mock the block number in
    *      tests.
    */
    function getBlockNumber64() internal view returns (uint64) {
        return getBlockNumber().toUint64();
    }

    /**
    * @dev Returns the current timestamp.
    *      Using a function rather than `block.timestamp` allows us to easily mock it in
    *      tests.
    */
    function getTimestamp() internal view returns (uint256) {
        return block.timestamp; // solium-disable-line security/no-block-members
    }

    /**
    * @dev Returns the current timestamp, converted to uint64.
    *      Using a function rather than `block.timestamp` allows us to easily mock it in
    *      tests.
    */
    function getTimestamp64() internal view returns (uint64) {
        return getTimestamp().toUint64();
    }
}

File 25 of 33 : Uint256Helpers.sol
pragma solidity ^0.4.24;


library Uint256Helpers {
    uint256 private constant MAX_UINT64 = uint64(-1);

    string private constant ERROR_NUMBER_TOO_BIG = "UINT64_NUMBER_TOO_BIG";

    function toUint64(uint256 a) internal pure returns (uint64) {
        require(a <= MAX_UINT64, ERROR_NUMBER_TOO_BIG);
        return uint64(a);
    }
}

File 26 of 33 : ERC20.sol
// See https://github.com/OpenZeppelin/openzeppelin-solidity/blob/a9f910d34f0ab33a1ae5e714f69f9596a02b4d91/contracts/token/ERC20/ERC20.sol

pragma solidity ^0.4.24;


/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
contract ERC20 {
    function totalSupply() public view returns (uint256);

    function balanceOf(address _who) public view returns (uint256);

    function allowance(address _owner, address _spender)
        public view returns (uint256);

    function transfer(address _to, uint256 _value) public returns (bool);

    function approve(address _spender, uint256 _value)
        public returns (bool);

    function transferFrom(address _from, address _to, uint256 _value)
        public returns (bool);

    event Transfer(
        address indexed from,
        address indexed to,
        uint256 value
    );

    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
}

File 27 of 33 : EtherTokenConstant.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.4.24;


// aragonOS and aragon-apps rely on address(0) to denote native ETH, in
// contracts where both tokens and ETH are accepted
contract EtherTokenConstant {
    address internal constant ETH = address(0);
}

File 28 of 33 : SafeERC20.sol
// Inspired by AdEx (https://github.com/AdExNetwork/adex-protocol-eth/blob/b9df617829661a7518ee10f4cb6c4108659dd6d5/contracts/libs/SafeERC20.sol)
// and 0x (https://github.com/0xProject/0x-monorepo/blob/737d1dc54d72872e24abce5a1dbe1b66d35fa21a/contracts/protocol/contracts/protocol/AssetProxy/ERC20Proxy.sol#L143)

pragma solidity ^0.4.24;

import "../lib/token/ERC20.sol";


library SafeERC20 {
    // Before 0.5, solidity has a mismatch between `address.transfer()` and `token.transfer()`:
    // https://github.com/ethereum/solidity/issues/3544
    bytes4 private constant TRANSFER_SELECTOR = 0xa9059cbb;

    string private constant ERROR_TOKEN_BALANCE_REVERTED = "SAFE_ERC_20_BALANCE_REVERTED";
    string private constant ERROR_TOKEN_ALLOWANCE_REVERTED = "SAFE_ERC_20_ALLOWANCE_REVERTED";

    function invokeAndCheckSuccess(address _addr, bytes memory _calldata)
        private
        returns (bool)
    {
        bool ret;
        assembly {
            let ptr := mload(0x40)    // free memory pointer

            let success := call(
                gas,                  // forward all gas
                _addr,                // address
                0,                    // no value
                add(_calldata, 0x20), // calldata start
                mload(_calldata),     // calldata length
                ptr,                  // write output over free memory
                0x20                  // uint256 return
            )

            if gt(success, 0) {
                // Check number of bytes returned from last function call
                switch returndatasize

                // No bytes returned: assume success
                case 0 {
                    ret := 1
                }

                // 32 bytes returned: check if non-zero
                case 0x20 {
                    // Only return success if returned data was true
                    // Already have output in ptr
                    ret := eq(mload(ptr), 1)
                }

                // Not sure what was returned: don't mark as success
                default { }
            }
        }
        return ret;
    }

    function staticInvoke(address _addr, bytes memory _calldata)
        private
        view
        returns (bool, uint256)
    {
        bool success;
        uint256 ret;
        assembly {
            let ptr := mload(0x40)    // free memory pointer

            success := staticcall(
                gas,                  // forward all gas
                _addr,                // address
                add(_calldata, 0x20), // calldata start
                mload(_calldata),     // calldata length
                ptr,                  // write output over free memory
                0x20                  // uint256 return
            )

            if gt(success, 0) {
                ret := mload(ptr)
            }
        }
        return (success, ret);
    }

    /**
    * @dev Same as a standards-compliant ERC20.transfer() that never reverts (returns false).
    *      Note that this makes an external call to the token.
    */
    function safeTransfer(ERC20 _token, address _to, uint256 _amount) internal returns (bool) {
        bytes memory transferCallData = abi.encodeWithSelector(
            TRANSFER_SELECTOR,
            _to,
            _amount
        );
        return invokeAndCheckSuccess(_token, transferCallData);
    }

    /**
    * @dev Same as a standards-compliant ERC20.transferFrom() that never reverts (returns false).
    *      Note that this makes an external call to the token.
    */
    function safeTransferFrom(ERC20 _token, address _from, address _to, uint256 _amount) internal returns (bool) {
        bytes memory transferFromCallData = abi.encodeWithSelector(
            _token.transferFrom.selector,
            _from,
            _to,
            _amount
        );
        return invokeAndCheckSuccess(_token, transferFromCallData);
    }

    /**
    * @dev Same as a standards-compliant ERC20.approve() that never reverts (returns false).
    *      Note that this makes an external call to the token.
    */
    function safeApprove(ERC20 _token, address _spender, uint256 _amount) internal returns (bool) {
        bytes memory approveCallData = abi.encodeWithSelector(
            _token.approve.selector,
            _spender,
            _amount
        );
        return invokeAndCheckSuccess(_token, approveCallData);
    }

    /**
    * @dev Static call into ERC20.balanceOf().
    * Reverts if the call fails for some reason (should never fail).
    */
    function staticBalanceOf(ERC20 _token, address _owner) internal view returns (uint256) {
        bytes memory balanceOfCallData = abi.encodeWithSelector(
            _token.balanceOf.selector,
            _owner
        );

        (bool success, uint256 tokenBalance) = staticInvoke(_token, balanceOfCallData);
        require(success, ERROR_TOKEN_BALANCE_REVERTED);

        return tokenBalance;
    }

    /**
    * @dev Static call into ERC20.allowance().
    * Reverts if the call fails for some reason (should never fail).
    */
    function staticAllowance(ERC20 _token, address _owner, address _spender) internal view returns (uint256) {
        bytes memory allowanceCallData = abi.encodeWithSelector(
            _token.allowance.selector,
            _owner,
            _spender
        );

        (bool success, uint256 allowance) = staticInvoke(_token, allowanceCallData);
        require(success, ERROR_TOKEN_ALLOWANCE_REVERTED);

        return allowance;
    }

    /**
    * @dev Static call into ERC20.totalSupply().
    * Reverts if the call fails for some reason (should never fail).
    */
    function staticTotalSupply(ERC20 _token) internal view returns (uint256) {
        bytes memory totalSupplyCallData = abi.encodeWithSelector(_token.totalSupply.selector);

        (bool success, uint256 totalSupply) = staticInvoke(_token, totalSupplyCallData);
        require(success, ERROR_TOKEN_ALLOWANCE_REVERTED);

        return totalSupply;
    }
}

File 29 of 33 : IEVMScriptExecutor.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.4.24;


interface IEVMScriptExecutor {
    function execScript(bytes script, bytes input, address[] blacklist) external returns (bytes);
    function executorType() external pure returns (bytes32);
}

File 30 of 33 : IEVMScriptRegistry.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.4.24;

import "./IEVMScriptExecutor.sol";


contract EVMScriptRegistryConstants {
    /* Hardcoded constants to save gas
    bytes32 internal constant EVMSCRIPT_REGISTRY_APP_ID = apmNamehash("evmreg");
    */
    bytes32 internal constant EVMSCRIPT_REGISTRY_APP_ID = 0xddbcfd564f642ab5627cf68b9b7d374fb4f8a36e941a75d89c87998cef03bd61;
}


interface IEVMScriptRegistry {
    function addScriptExecutor(IEVMScriptExecutor executor) external returns (uint id);
    function disableScriptExecutor(uint256 executorId) external;

    // TODO: this should be external
    // See https://github.com/ethereum/solidity/issues/4832
    function getScriptExecutor(bytes script) public view returns (IEVMScriptExecutor);
}

File 31 of 33 : KernelConstants.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.4.24;


contract KernelAppIds {
    /* Hardcoded constants to save gas
    bytes32 internal constant KERNEL_CORE_APP_ID = apmNamehash("kernel");
    bytes32 internal constant KERNEL_DEFAULT_ACL_APP_ID = apmNamehash("acl");
    bytes32 internal constant KERNEL_DEFAULT_VAULT_APP_ID = apmNamehash("vault");
    */
    bytes32 internal constant KERNEL_CORE_APP_ID = 0x3b4bf6bf3ad5000ecf0f989d5befde585c6860fea3e574a4fab4c49d1c177d9c;
    bytes32 internal constant KERNEL_DEFAULT_ACL_APP_ID = 0xe3262375f45a6e2026b7e7b18c2b807434f2508fe1a2a3dfb493c7df8f4aad6a;
    bytes32 internal constant KERNEL_DEFAULT_VAULT_APP_ID = 0x7e852e0fcfce6551c13800f1e7476f982525c2b5277ba14b24339c68416336d1;
}


contract KernelNamespaceConstants {
    /* Hardcoded constants to save gas
    bytes32 internal constant KERNEL_CORE_NAMESPACE = keccak256("core");
    bytes32 internal constant KERNEL_APP_BASES_NAMESPACE = keccak256("base");
    bytes32 internal constant KERNEL_APP_ADDR_NAMESPACE = keccak256("app");
    */
    bytes32 internal constant KERNEL_CORE_NAMESPACE = 0xc681a85306374a5ab27f0bbc385296a54bcd314a1948b6cf61c4ea1bc44bb9f8;
    bytes32 internal constant KERNEL_APP_BASES_NAMESPACE = 0xf1f3eb40f5bc1ad1344716ced8b8a0431d840b5783aea1fd01786bc26f35ac0f;
    bytes32 internal constant KERNEL_APP_ADDR_NAMESPACE = 0xd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb;
}

File 32 of 33 : IERC20.sol
pragma solidity ^0.4.24;

/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
interface IERC20 {
  function totalSupply() external view returns (uint256);

  function balanceOf(address who) external view returns (uint256);

  function allowance(address owner, address spender)
    external view returns (uint256);

  function transfer(address to, uint256 value) external returns (bool);

  function approve(address spender, uint256 value)
    external returns (bool);

  function transferFrom(address from, address to, uint256 value)
    external returns (bool);

  event Transfer(
    address indexed from,
    address indexed to,
    uint256 value
  );

  event Approval(
    address indexed owner,
    address indexed spender,
    uint256 value
  );
}

File 33 of 33 : Pausable.sol
// SPDX-FileCopyrightText: 2020 Lido <[email protected]>

// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.4.24;

import "@aragon/os/contracts/common/UnstructuredStorage.sol";


contract Pausable {
    using UnstructuredStorage for bytes32;

    event Stopped();
    event Resumed();

    bytes32 internal constant ACTIVE_FLAG_POSITION = keccak256("lido.Pausable.activeFlag");

    modifier whenNotStopped() {
        require(ACTIVE_FLAG_POSITION.getStorageBool(), "CONTRACT_IS_STOPPED");
        _;
    }

    modifier whenStopped() {
        require(!ACTIVE_FLAG_POSITION.getStorageBool(), "CONTRACT_IS_ACTIVE");
        _;
    }

    function isStopped() external view returns (bool) {
        return !ACTIVE_FLAG_POSITION.getStorageBool();
    }

    function _stop() internal whenNotStopped {
        ACTIVE_FLAG_POSITION.setStorageBool(false);
        emit Stopped();
    }

    function _resume() internal whenStopped {
        ACTIVE_FLAG_POSITION.setStorageBool(true);
        emit Resumed();
    }
}

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

Contract Security Audit

Contract ABI

[{"constant":false,"inputs":[],"name":"resume","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[],"name":"stop","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_amount","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"depositContract","type":"address"},{"name":"_oracle","type":"address"},{"name":"_operators","type":"address"},{"name":"_treasury","type":"address"},{"name":"_insuranceFund","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getInsuranceFund","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_ethAmount","type":"uint256"}],"name":"getSharesByPooledEth","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_sender","type":"address"},{"name":"_recipient","type":"address"},{"name":"_amount","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getOperators","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_script","type":"bytes"}],"name":"getEVMScriptExecutor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"getRecoveryVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"DEPOSIT_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"DEPOSIT_SIZE","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getTotalPooledEther","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PAUSE_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getTreasury","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SET_ORACLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isStopped","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MANAGE_WITHDRAWAL_KEY","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBufferedEther","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SIGNATURE_LENGTH","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getWithdrawalCredentials","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_account","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getFeeDistribution","outputs":[{"name":"treasuryFeeBasisPoints","type":"uint16"},{"name":"insuranceFeeBasisPoints","type":"uint16"},{"name":"operatorsFeeBasisPoints","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_sharesAmount","type":"uint256"}],"name":"getPooledEthByShares","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_oracle","type":"address"}],"name":"setOracle","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"allowRecoverability","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"appId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getOracle","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitializationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_treasuryFeeBasisPoints","type":"uint16"},{"name":"_insuranceFeeBasisPoints","type":"uint16"},{"name":"_operatorsFeeBasisPoints","type":"uint16"}],"name":"setFeeDistribution","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_feeBasisPoints","type":"uint16"}],"name":"setFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_maxDeposits","type":"uint256"}],"name":"depositBufferedEther","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"MANAGE_FEE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"transferToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"SET_TREASURY","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_params","type":"uint256[]"}],"name":"canPerform","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_referral","type":"address"}],"name":"submit","outputs":[{"name":"","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"WITHDRAWAL_CREDENTIALS_LENGTH","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getEVMScriptRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PUBKEY_LENGTH","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_amount","type":"uint256"},{"name":"_pubkeyHash","type":"bytes32"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"address"},{"name":"_amount","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getDepositContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBeaconStat","outputs":[{"name":"depositedValidators","type":"uint256"},{"name":"beaconValidators","type":"uint256"},{"name":"beaconBalance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"BURN_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_insuranceFund","type":"address"}],"name":"setInsuranceFund","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getFee","outputs":[{"name":"feeBasisPoints","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SET_INSURANCE_FUND","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kernel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getTotalShares","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPetrified","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_withdrawalCredentials","type":"bytes32"}],"name":"setWithdrawalCredentials","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"depositBufferedEther","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_account","type":"address"},{"name":"_sharesAmount","type":"uint256"}],"name":"burnShares","outputs":[{"name":"newTotalShares","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_beaconValidators","type":"uint256"},{"name":"_beaconBalance","type":"uint256"}],"name":"pushBeacon","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_account","type":"address"}],"name":"sharesOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"executor","type":"address"},{"indexed":false,"name":"script","type":"bytes"},{"indexed":false,"name":"input","type":"bytes"},{"indexed":false,"name":"returnData","type":"bytes"}],"name":"ScriptResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"vault","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"RecoverToVault","type":"event"},{"anonymous":false,"inputs":[],"name":"Stopped","type":"event"},{"anonymous":false,"inputs":[],"name":"Resumed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"feeBasisPoints","type":"uint16"}],"name":"FeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"treasuryFeeBasisPoints","type":"uint16"},{"indexed":false,"name":"insuranceFeeBasisPoints","type":"uint16"},{"indexed":false,"name":"operatorsFeeBasisPoints","type":"uint16"}],"name":"FeeDistributionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"withdrawalCredentials","type":"bytes32"}],"name":"WithdrawalCredentialsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"referral","type":"address"}],"name":"Submitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"Unbuffered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"sender","type":"address"},{"indexed":false,"name":"tokenAmount","type":"uint256"},{"indexed":false,"name":"sentFromBuffer","type":"uint256"},{"indexed":true,"name":"pubkeyHash","type":"bytes32"},{"indexed":false,"name":"etherAmount","type":"uint256"}],"name":"Withdrawal","type":"event"}]

6080604052620000146200001a60201b60201c565b62000231565b6200002a6200011c60201b60201c565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a454400000000000000006020820152901562000106576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015620000ca578181015183820152602001620000b0565b50505050905090810190601f168015620000f85780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506200011a6000196200014f60201b60201c565b565b60006200014a6000805160206200556783398151915260001b600019166200022960201b62002a261760201c565b905090565b6200015f6200011c60201b60201c565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a4544000000000000000060208201529015620001fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015620000ca578181015183820152602001620000b0565b506200022660008051602062005567833981519152826200022d602090811b62003bbc17901c565b50565b5490565b9055565b61532680620002416000396000f3006080604052600436106102e45760003560e01c63ffffffff168063046f7da21461034757806306fdde031461035e57806307da68f5146103e85780630803fac0146103fd578063095ea7b3146104265780631459457a1461044a578063158626f71461048357806318160ddd146104b457806319208451146104db57806323b872dd146104f357806327a099d81461051d5780632914b9bd14610532578063313ce5671461058b57806332f0a3b5146105b6578063353efdcf146105cb57806336bf3325146105e057806337cfdaca146104b4578063389ed267146105f5578063395093511461060a5780633b19e84a1461062e5780633c1c2dc0146106435780633f683b6a14610658578063435721da1461066d57806347b714e014610682578063540bc5ea1461069757806356396715146106ac57806370a08231146106c1578063752f77f1146106e25780637a28fb881461071d5780637adbf973146107355780637e7db6e11461075657806380afdea814610777578063833b1fce1461078c5780638b3dd749146107a15780638cef3612146107b65780638e005553146107de57806390adc83b146107fa57806395d89b41146108125780639aaa2d15146108275780639d4941d81461083c578063a0654fdc1461085d578063a1658fad14610872578063a1903eab146108d9578063a30448c0146108ed578063a457c2d714610902578063a479e50814610926578063a4d55d1d1461093b578063a8d2021a14610950578063a9059cbb1461096b578063ab94276a1461098f578063ae2e3538146109a4578063b930908f146109d7578063c3c05293146109ec578063ced72f8714610a0d578063d0cc43c514610a39578063d4aae0c414610a4e578063d5002f2e14610a63578063dd62ed3e14610a78578063de4796ed14610a9f578063e97ee8cc14610ab4578063ecc1dcfb14610acc578063ee7a7c0414610ae1578063f0f4426014610b05578063f16ac1fc14610b26578063f5eb42dc14610b41575b361561033a576040805160e560020a62461bcd02815260206004820152600e60248201527f4e4f4e5f454d5054595f44415441000000000000000000000000000000000000604482015290519081900360640190fd5b6103446000610b62565b50005b34801561035357600080fd5b5061035c610c76565b005b34801561036a57600080fd5b50610373610d81565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103ad578181015183820152602001610395565b50505050905090810190601f1680156103da5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103f457600080fd5b5061035c610db8565b34801561040957600080fd5b50610412610e82565b604080519115158252519081900360200190f35b34801561043257600080fd5b50610412600160a060020a0360043516602435610eab565b34801561045657600080fd5b5061035c600160a060020a0360043581169060243581169060443581169060643581169060843516610ec1565b34801561048f57600080fd5b50610498610f8b565b60408051600160a060020a039092168252519081900360200190f35b3480156104c057600080fd5b506104c9610fce565b60408051918252519081900360200190f35b3480156104e757600080fd5b506104c9600435610fd8565b3480156104ff57600080fd5b50610412600160a060020a0360043581169060243516604435611026565b34801561052957600080fd5b506104986110fa565b34801561053e57600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526104989436949293602493928401919081908401838280828437509497506111389650505050505050565b34801561059757600080fd5b506105a061121b565b6040805160ff9092168252519081900360200190f35b3480156105c257600080fd5b50610498611220565b3480156105d757600080fd5b506104c9611295565b3480156105ec57600080fd5b506104c96112ca565b34801561060157600080fd5b506104c96112d7565b34801561061657600080fd5b50610412600160a060020a036004351660243561130c565b34801561063a57600080fd5b50610498611348565b34801561064f57600080fd5b506104c9611386565b34801561066457600080fd5b506104126113bb565b34801561067957600080fd5b506104c96113ed565b34801561068e57600080fd5b506104c9611422565b3480156106a357600080fd5b506104c961142c565b3480156106b857600080fd5b506104c9611431565b3480156106cd57600080fd5b506104c9600160a060020a036004351661146f565b3480156106ee57600080fd5b506106f7611488565b6040805161ffff9485168152928416602084015292168183015290519081900360600190f35b34801561072957600080fd5b506104c96004356114a0565b34801561074157600080fd5b5061035c600160a060020a03600435166114cc565b34801561076257600080fd5b50610412600160a060020a036004351661159b565b34801561078357600080fd5b506104c96115a1565b34801561079857600080fd5b506104986115cc565b3480156107ad57600080fd5b506104c961160a565b3480156107c257600080fd5b5061035c61ffff60043581169060243581169060443516611635565b3480156107ea57600080fd5b5061035c61ffff6004351661187e565b34801561080657600080fd5b5061035c6004356119b7565b34801561081e57600080fd5b50610373611a82565b34801561083357600080fd5b506104c9611ab9565b34801561084857600080fd5b5061035c600160a060020a0360043516611aee565b34801561086957600080fd5b506104c9611d2d565b34801561087e57600080fd5b506040805160206004604435818101358381028086018501909652808552610412958335600160a060020a0316956024803596369695606495939492019291829185019084908082843750949750611d629650505050505050565b6104c9600160a060020a0360043516611ead565b3480156108f957600080fd5b506104c9611eb8565b34801561090e57600080fd5b50610412600160a060020a0360043516602435611ebd565b34801561093257600080fd5b50610498611f5a565b34801561094757600080fd5b506104c961200f565b34801561095c57600080fd5b5061035c600435602435612014565b34801561097757600080fd5b50610412600160a060020a03600435166024356120d1565b34801561099b57600080fd5b506104986120de565b3480156109b057600080fd5b506109b961211c565b60408051938452602084019290925282820152519081900360600190f35b3480156109e357600080fd5b506104c96121ab565b3480156109f857600080fd5b5061035c600160a060020a03600435166121e0565b348015610a1957600080fd5b50610a226122ab565b6040805161ffff9092168252519081900360200190f35b348015610a4557600080fd5b506104c96122b5565b348015610a5a57600080fd5b506104986122ea565b348015610a6f57600080fd5b506104c9612315565b348015610a8457600080fd5b506104c9600160a060020a036004358116906024351661231f565b348015610aab57600080fd5b5061041261234a565b348015610ac057600080fd5b5061035c60043561235d565b348015610ad857600080fd5b5061035c6124f3565b348015610aed57600080fd5b506104c9600160a060020a03600435166024356125bf565b348015610b1157600080fd5b5061035c600160a060020a0360043516612691565b348015610b3257600080fd5b5061035c60043560243561275c565b348015610b4d57600080fd5b506104c9600160a060020a0360043516612a1b565b6040805160008051602061527b83398151915281529051908190036018019020600090819081908190610b9490612a26565b1515610bd8576040805160e560020a62461bcd02815260206004820152601360248201526000805160206152bb833981519152604482015290519081900360640190fd5b339250349150811515610c35576040805160e560020a62461bcd02815260206004820152600c60248201527f5a45524f5f4445504f5349540000000000000000000000000000000000000000604482015290519081900360640190fd5b610c3e82610fd8565b9050801515610c4a5750805b610c548382612a2a565b50610c60838387612b95565b610c6a8382612c2c565b8093505b505050919050565b604080517f50415553455f524f4c45000000000000000000000000000000000000000000008152815190819003600a01812060008083526020830190935291610cc59133918491905b50611d62565b60408051808201909152600f815260008051602061523b8339815191526020820152901515610d755760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610d3a578181015183820152602001610d22565b50505050905090810190601f168015610d675780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50610d7e612c77565b50565b60408051808201909152601781527f4c6971756964207374616b656420457468657220322e30000000000000000000602082015290565b604080517f50415553455f524f4c45000000000000000000000000000000000000000000008152815190819003600a01812060008083526020830190935291610e05913391849190610cbf565b60408051808201909152600f815260008051602061523b8339815191526020820152901515610e795760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b50610d7e612d51565b600080610e8d61160a565b90508015801590610ea5575080610ea2612e1a565b10155b91505090565b6000610eb8338484612e1e565b50600192915050565b610ec961160a565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a4544000000000000000060208201529015610f4e5760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b50610f5885612fad565b610f618461304e565b610f6a836130ef565b610f7382613190565b610f7c81613232565b610f846132d4565b5050505050565b604080517f6c69646f2e4c69646f2e696e737572616e636546756e6400000000000000000081529051908190036017019020600090610fc990612a26565b905090565b6000610fc961339c565b600080610fe361339c565b9050801515610ff55760009150611020565b61101d816110116110046133fe565b869063ffffffff61343c16565b9063ffffffff6134e716565b91505b50919050565b600160a060020a0383166000908152600160209081526040808320338452909152812054828110156110c8576040805160e560020a62461bcd02815260206004820152602160248201527f5452414e534645525f414d4f554e545f455843454544535f414c4c4f57414e4360448201527f4500000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6110d3858585613587565b6110ed85336110e8848763ffffffff6135f016565b612e1e565b600191505b509392505050565b604080517f6c69646f2e4c69646f2e6e6f64654f70657261746f72735265676973747279008152905190819003601f019020600090610fc990612a26565b6000611142611f5a565b600160a060020a03166304bf2a7f836040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561119d578181015183820152602001611185565b50505050905090810190601f1680156111ca5780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b1580156111e957600080fd5b505af11580156111fd573d6000803e3d6000fd5b505050506040513d602081101561121357600080fd5b505192915050565b601290565b600061122a6122ea565b600160a060020a03166332f0a3b56040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561126457600080fd5b505af1158015611278573d6000803e3d6000fd5b505050506040513d602081101561128e57600080fd5b5051905090565b604080517f4445504f5349545f524f4c4500000000000000000000000000000000000000008152905190819003600c01902081565b6801bc16d674ec80000081565b604080517f50415553455f524f4c45000000000000000000000000000000000000000000008152905190819003600a01902081565b336000818152600160209081526040808320600160a060020a03871684529091528120549091610eb89185906110e8908663ffffffff61368416565b604080517f6c69646f2e4c69646f2e7472656173757279000000000000000000000000000081529051908190036012019020600090610fc990612a26565b604080517f5345545f4f5241434c45000000000000000000000000000000000000000000008152905190819003600a01902081565b6040805160008051602061527b833981519152815290519081900360180190206000906113e790612a26565b15905090565b604080517f4d414e4147455f5749544844524157414c5f4b455900000000000000000000008152905190819003601501902081565b6000610fc9613712565b606081565b604080517f6c69646f2e4c69646f2e7769746864726177616c43726564656e7469616c73008152905190819003601f019020600090610fc990612a26565b600061148261147d83613764565b6114a0565b92915050565b600080600061149561377f565b925092509250909192565b6000806114ab6133fe565b90508015156114bd5760009150611020565b61101d8161101161100461339c565b604080517f5345545f4f5241434c45000000000000000000000000000000000000000000008152815190819003600a01812060008083526020830190935291611519913391849190610cbf565b60408051808201909152600f815260008051602061523b833981519152602082015290151561158d5760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b506115978261304e565b5050565b50600190565b6000610fc97fd625496217aa6a3453eecb9c3489dc5a53e6c67b444329ea2b2cbc9ff547639b612a26565b604080517f6c69646f2e4c69646f2e6f7261636c650000000000000000000000000000000081529051908190036010019020600090610fc990612a26565b6000610fc97febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e612a26565b604080517f4d414e4147455f464545000000000000000000000000000000000000000000008152815190819003600a01812060008083526020830190935291611682913391849190610cbf565b60408051808201909152600f815260008051602061523b83398151915260208201529015156116f65760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b506117268261ffff1661171a8561ffff168761ffff1661368490919063ffffffff16565b9063ffffffff61368416565b6127101461177e576040805160e560020a62461bcd02815260206004820152601060248201527f464545535f444f4e545f4144445f555000000000000000000000000000000000604482015290519081900360640190fd5b604080517f6c69646f2e4c69646f2e74726561737572794665650000000000000000000000815290519081900360150190206117ba9085613842565b604080517f6c69646f2e4c69646f2e696e737572616e636546656500000000000000000000815290519081900360160190206117f69084613842565b604080517f6c69646f2e4c69646f2e6e6f64654f70657261746f72734665650000000000008152905190819003601a0190206118329083613842565b6040805161ffff8087168252808616602083015284168183015290517f034529db1bba3830b8877e116871f19c5b96ef86c739f2a05668c860c84668989181900360600190a150505050565b604080517f4d414e4147455f464545000000000000000000000000000000000000000000008152815190819003600a018120600080835260208301909352916118cb913391849190610cbf565b60408051808201909152600f815260008051602061523b833981519152602082015290151561193f5760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b50604080517f6c69646f2e4c69646f2e666565000000000000000000000000000000000000008152905190819003600d01902061197c9083613842565b6040805161ffff8416815290517faab062e3faf62b6c9a0f8e62af66e0310e27127a8c871a67be7dd4d93de6da539181900360200190a15050565b604080517f4445504f5349545f524f4c4500000000000000000000000000000000000000008152815190819003600c01812060008083526020830190935291611a04913391849190610cbf565b60408051808201909152600f815260008051602061523b8339815191526020820152901515611a785760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b50611597826138b4565b60408051808201909152600581527f7374455448000000000000000000000000000000000000000000000000000000602082015290565b604080517f4d414e4147455f464545000000000000000000000000000000000000000000008152905190819003600a01902081565b6000806000611afc8461159b565b1515611b52576040805160e560020a62461bcd02815260206004820152601260248201527f5245434f5645525f444953414c4c4f5745440000000000000000000000000000604482015290519081900360640190fd5b611b5a611220565b9250611b658361399c565b1515611bbb576040805160e560020a62461bcd02815260206004820152601a60248201527f5245434f5645525f5641554c545f4e4f545f434f4e5452414354000000000000604482015290519081900360640190fd5b600160a060020a0384161515611c4f57611bd36139c2565b915082600160a060020a03168260405160006040518083038185875af1925050501515611c4a576040805160e560020a62461bcd02815260206004820152601760248201527f5245434f5645525f5452414e534645525f4641494c4544000000000000000000604482015290519081900360640190fd5b611cdc565b5082611c6a600160a060020a0382163063ffffffff6139dd16565b9150611c86600160a060020a038216848463ffffffff613af216565b1515611cdc576040805160e560020a62461bcd02815260206004820152601d60248201527f5245434f5645525f544f4b454e5f5452414e534645525f4641494c4544000000604482015290519081900360640190fd5b83600160a060020a031683600160a060020a03167f596caf56044b55fb8c4ca640089bbc2b63cae3e978b851f5745cbb7c5b288e02846040518082815260200191505060405180910390a350505050565b604080517f5345545f545245415355525900000000000000000000000000000000000000008152905190819003600c01902081565b600080611d6d610e82565b1515611d7c57600091506110f2565b611d846122ea565b9050600160a060020a0381161515611d9f57600091506110f2565b80600160a060020a031663fdef9106863087611dba88613b74565b60405163ffffffff861660e01b8152600160a060020a03808616600483019081529085166024830152604482018490526080606483019081528351608484015283519192909160a490910190602085019080838360005b83811015611e29578181015183820152602001611e11565b50505050905090810190601f168015611e565780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b158015611e7857600080fd5b505af1158015611e8c573d6000803e3d6000fd5b505050506040513d6020811015611ea257600080fd5b505195945050505050565b600061148282610b62565b602081565b336000908152600160209081526040808320600160a060020a038616845290915281205482811015611f39576040805160e560020a62461bcd02815260206004820152601e60248201527f4445435245415345445f414c4c4f57414e43455f42454c4f575f5a45524f0000604482015290519081900360640190fd5b611f4e33856110e8848763ffffffff6135f016565b600191505b5092915050565b600080611f656122ea565b604080517fbe00bbd80000000000000000000000000000000000000000000000000000000081527fd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb60048201527fddbcfd564f642ab5627cf68b9b7d374fb4f8a36e941a75d89c87998cef03bd6160248201529051600160a060020a03929092169163be00bbd8916044808201926020929091908290030181600087803b1580156111e957600080fd5b603081565b6040805160008051602061527b8339815191528152905190819003601801902061203d90612a26565b1515612081576040805160e560020a62461bcd02815260206004820152601360248201526000805160206152bb833981519152604482015290519081900360640190fd5b6040805160e560020a62461bcd02815260206004820152601360248201527f4e4f545f494d504c454d454e5445445f59455400000000000000000000000000604482015290519081900360640190fd5b6000610eb8338484613587565b604080517f6c69646f2e4c69646f2e6465706f736974436f6e74726163740000000000000081529051908190036019019020600090610fc990612a26565b6040805160008051602061529b8339815191528152905190819003601d0190206000908190819061214c90612a26565b604080516000805160206152db8339815191528152905190819003601a01902090935061217890612a26565b6040805160008051602061525b833981519152815290519081900360170190209092506121a490612a26565b9050909192565b604080517f4255524e5f524f4c4500000000000000000000000000000000000000000000008152905190819003600901902081565b604080517f5345545f494e535552414e43455f46554e440000000000000000000000000000815281519081900360120181206000808352602083019093529161222d913391849190610cbf565b60408051808201909152600f815260008051602061523b83398151915260208201529015156122a15760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b5061159782613232565b6000610fc9613b7e565b604080517f5345545f494e535552414e43455f46554e4400000000000000000000000000008152905190819003601201902081565b6000610fc97f4172f0f7d2289153072b0a6ca36959e0cbe2efc3afe50fc81636caa96338137b612a26565b6000610fc96133fe565b600160a060020a03918216600090815260016020908152604080832093909416825291909152205490565b600060001961235761160a565b14905090565b604080517f4d414e4147455f5749544844524157414c5f4b4559000000000000000000000081528151908190036015018120600080835260208301909352916123aa913391849190610cbf565b60408051808201909152600f815260008051602061523b833981519152602082015290151561241e5760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b50604080517f6c69646f2e4c69646f2e7769746864726177616c43726564656e7469616c73008152905190819003601f019020612461908363ffffffff613bbc16565b6124696110fa565b600160a060020a031663f778021e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156124a357600080fd5b505af11580156124b7573d6000803e3d6000fd5b50506040805185815290517f13eb80e900aa05a2696d50d5de33ef631c73493c4921da233b17335ff6b7b1149350908190036020019150a15050565b604080517f4445504f5349545f524f4c4500000000000000000000000000000000000000008152815190819003600c01812060008083526020830190935291612540913391849190610cbf565b60408051808201909152600f815260008051602061523b83398151915260208201529015156125b45760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b50610d7e60966138b4565b604080517f4255524e5f524f4c450000000000000000000000000000000000000000000000815290519081900360090190206000906125fe8484613bc0565b612609338383611d62565b60408051808201909152600f815260008051602061523b833981519152602082015290151561267d5760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b506126888585613bdc565b95945050505050565b604080517f5345545f545245415355525900000000000000000000000000000000000000008152815190819003600c018120600080835260208301909352916126de913391849190610cbf565b60408051808201909152600f815260008051602061523b83398151915260208201529015156127525760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b5061159782613190565b6000806000806000612794604051808060008051602061527b8339815191528152506018019050604051809103902060001916612a26565b15156127d8576040805160e560020a62461bcd02815260206004820152601360248201526000805160206152bb833981519152604482015290519081900360640190fd5b6127e06115cc565b600160a060020a0316331461282d576040805160e560020a62461bcd02815260206004820152600f602482015260008051602061523b833981519152604482015290519081900360640190fd5b6040805160008051602061529b8339815191528152905190819003601d01902061285690612a26565b9450848711156128b0576040805160e560020a62461bcd02815260206004820152601760248201527f5245504f525445445f4d4f52455f4445504f5349544544000000000000000000604482015290519081900360640190fd5b604080516000805160206152db8339815191528152905190819003601a0190206128d990612a26565b935083871015612933576040805160e560020a62461bcd02815260206004820152601860248201527f5245504f525445445f4c4553535f56414c494441544f52530000000000000000604482015290519081900360640190fd5b612943878563ffffffff6135f016565b6040805160008051602061525b8339815191528152905190819003601701902090935061298c9061297390612a26565b61171a856801bc16d674ec80000063ffffffff61343c16565b6040805160008051602061525b833981519152815290519081900360170190209092506129bf908763ffffffff613bbc16565b604080516000805160206152db8339815191528152905190819003601a0190206129ef908863ffffffff613bbc16565b81861115612a1257612a07868363ffffffff6135f016565b9050612a1281613db4565b50505050505050565b600061148282613764565b5490565b6040805160008051602061527b83398151915281529051908190036018019020600090612a5690612a26565b1515612a9a576040805160e560020a62461bcd02815260206004820152601360248201526000805160206152bb833981519152604482015290519081900360640190fd5b600160a060020a0383161515612afa576040805160e560020a62461bcd02815260206004820152601860248201527f4d494e545f544f5f5448455f5a45524f5f414444524553530000000000000000604482015290519081900360640190fd5b612b068261171a6133fe565b604080517f6c69646f2e53744554482e746f74616c5368617265730000000000000000000081529051908190036016019020909150612b4b908263ffffffff613bbc16565b600160a060020a038316600090815260208190526040902054612b74908363ffffffff61368416565b600160a060020a039093166000908152602081905260409020929092555090565b612be2612ba48361171a613712565b604080517f6c69646f2e4c69646f2e62756666657265644574686572000000000000000000815290519081900360170190209063ffffffff613bbc16565b60408051838152600160a060020a0383811660208301528251908616927f96a25c8ce0baabc1fdefd93e9ed25d8e092a3332f3aa9a41722b5697231d1d1a928290030190a2505050565b600160a060020a03821660007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef612c62846114a0565b60408051918252519081900360200190a35050565b6040805160008051602061527b83398151915281529051908190036018019020612ca090612a26565b15612cf5576040805160e560020a62461bcd02815260206004820152601260248201527f434f4e54524143545f49535f4143544956450000000000000000000000000000604482015290519081900360640190fd5b6040805160008051602061527b83398151915281529051908190036018019020612d2690600163ffffffff613bbc16565b6040517f62451d457bc659158be6e6247f56ec1df424a5c7597f71c20c2bc44e0965c8f990600090a1565b6040805160008051602061527b83398151915281529051908190036018019020612d7a90612a26565b1515612dbe576040805160e560020a62461bcd02815260206004820152601360248201526000805160206152bb833981519152604482015290519081900360640190fd5b6040805160008051602061527b83398151915281529051908190036018019020612def90600063ffffffff613bbc16565b6040517f7acc84e34091ae817647a4c49116f5cc07f319078ba80f8f5fde37ea7e25cbd690600090a1565b4390565b6040805160008051602061527b83398151915281529051908190036018019020612e4790612a26565b1515612e8b576040805160e560020a62461bcd02815260206004820152601360248201526000805160206152bb833981519152604482015290519081900360640190fd5b600160a060020a0383161515612eeb576040805160e560020a62461bcd02815260206004820152601960248201527f415050524f56455f46524f4d5f5a45524f5f4144445245535300000000000000604482015290519081900360640190fd5b600160a060020a0382161515612f4b576040805160e560020a62461bcd02815260206004820152601760248201527f415050524f56455f544f5f5a45524f5f41444452455353000000000000000000604482015290519081900360640190fd5b600160a060020a03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b612fb68161399c565b151561300c576040805160e560020a62461bcd02815260206004820152600e60248201527f4e4f545f415f434f4e5452414354000000000000000000000000000000000000604482015290519081900360640190fd5b604080517f6c69646f2e4c69646f2e6465706f736974436f6e74726163740000000000000081529051908190036019019020610d7e908263ffffffff613bbc16565b6130578161399c565b15156130ad576040805160e560020a62461bcd02815260206004820152600e60248201527f4e4f545f415f434f4e5452414354000000000000000000000000000000000000604482015290519081900360640190fd5b604080517f6c69646f2e4c69646f2e6f7261636c650000000000000000000000000000000081529051908190036010019020610d7e908263ffffffff613bbc16565b6130f88161399c565b151561314e576040805160e560020a62461bcd02815260206004820152600e60248201527f4e4f545f415f434f4e5452414354000000000000000000000000000000000000604482015290519081900360640190fd5b604080517f6c69646f2e4c69646f2e6e6f64654f70657261746f72735265676973747279008152905190819003601f019020610d7e908263ffffffff613bbc16565b600160a060020a03811615156131f0576040805160e560020a62461bcd02815260206004820152601960248201527f5345545f54524541535552595f5a45524f5f4144445245535300000000000000604482015290519081900360640190fd5b604080517f6c69646f2e4c69646f2e7472656173757279000000000000000000000000000081529051908190036012019020610d7e908263ffffffff613bbc16565b600160a060020a0381161515613292576040805160e560020a62461bcd02815260206004820152601f60248201527f5345545f494e535552414e43455f46554e445f5a45524f5f4144445245535300604482015290519081900360640190fd5b604080517f6c69646f2e4c69646f2e696e737572616e636546756e6400000000000000000081529051908190036017019020610d7e908263ffffffff613bbc16565b6132dc61160a565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a45440000000000000000602082015290156133615760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b5061339a61336d612e1a565b7febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e9063ffffffff613bbc16565b565b6000806000806133aa613712565b6040805160008051602061525b833981519152815290519081900360170190209093506133d690612a26565b91506133e0613ed7565b90506133f68161171a858563ffffffff61368416565b935050505090565b604080517f6c69646f2e53744554482e746f74616c5368617265730000000000000000000081529051908190036016019020600090610fc990612a26565b60008083151561344f5760009150611f53565b5082820282848281151561345f57fe5b60408051808201909152601181527f4d4154485f4d554c5f4f564552464c4f57000000000000000000000000000000602082015292919004146110f25760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b60408051808201909152600d81527f4d4154485f4449565f5a45524f00000000000000000000000000000000000000602082015260009081908184116135725760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b50828481151561357e57fe5b04949350505050565b600061359282610fd8565b905061359f848483613f6c565b82600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a350505050565b60408051808201909152601281527f4d4154485f5355425f554e444552464c4f570000000000000000000000000000602082015260009081908484111561367c5760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b505050900390565b60408051808201909152601181527f4d4154485f4144445f4f564552464c4f57000000000000000000000000000000602082015260009083830190848210156110f25760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b604080517f6c69646f2e4c69646f2e6275666665726564457468657200000000000000000081529051908190036017019020600090819061375290612a26565b9050303181111561375f57fe5b919050565b600160a060020a031660009081526020819052604090205490565b60008060006137c260405180807f6c69646f2e4c69646f2e7472656173757279466565000000000000000000000081525060150190506040518091039020614175565b604080517f6c69646f2e4c69646f2e696e737572616e6365466565000000000000000000008152905190819003601601902090935061380090614175565b604080517f6c69646f2e4c69646f2e6e6f64654f70657261746f72734665650000000000008152905190819003601a0190209092506121a490614175565b5490565b61271061ffff821611156138a0576040805160e560020a62461bcd02815260206004820152601660248201527f56414c55455f4f5645525f3130305f50455243454e5400000000000000000000604482015290519081900360640190fd5b6115978261ffff831663ffffffff613bbc16565b6040805160008051602061527b83398151915281529051908190036018019020600090819081906138e490612a26565b1515613928576040805160e560020a62461bcd02815260206004820152601360248201526000805160206152bb833981519152604482015290519081900360640190fd5b613930613712565b92506801bc16d674ec80000083106139965761394a6139c2565b9150613965836801bc16d674ec80000063ffffffff6134e716565b905061398661398185831061397a578561397c565b825b61418f565b61450e565b8161398f6139c2565b1461399657fe5b50505050565b600080600160a060020a03831615156139b85760009150611020565b50506000903b1190565b6000610fc96139cf613712565b30319063ffffffff6135f016565b60408051600160a060020a0383166024808301919091528251808303909101815260449091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a08231000000000000000000000000000000000000000000000000000000001790526000908180613a5d8684614589565b60408051808201909152601c81527f534146455f4552435f32305f42414c414e43455f52455645525445440000000060208201529193509150821515613ae85760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b5095945050505050565b60408051600160a060020a038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905260009061268885826145ba565b8051602002815290565b604080517f6c69646f2e4c69646f2e666565000000000000000000000000000000000000008152905190819003600d019020600090610fc990614175565b9055565b6060613bd583600160a060020a031683614608565b9392505050565b6040805160008051602061527b833981519152815290519081900360180190206000908190613c0a90612a26565b1515613c4e576040805160e560020a62461bcd02815260206004820152601360248201526000805160206152bb833981519152604482015290519081900360640190fd5b600160a060020a0384161515613cae576040805160e560020a62461bcd02815260206004820152601a60248201527f4255524e5f46524f4d5f5448455f5a45524f5f41444452455353000000000000604482015290519081900360640190fd5b50600160a060020a03831660009081526020819052604090205480831115613d20576040805160e560020a62461bcd02815260206004820152601b60248201527f4255524e5f414d4f554e545f455843454544535f42414c414e43450000000000604482015290519081900360640190fd5b613d3883613d2c6133fe565b9063ffffffff6135f016565b604080517f6c69646f2e53744554482e746f74616c5368617265730000000000000000000081529051908190036016019020909250613d7d908363ffffffff613bbc16565b613d8d818463ffffffff6135f016565b600160a060020a0390941660009081526020819052604090209390935592915050565b9055565b6000806000806000806000806000613dca613b7e565b61ffff169850613e1b613e00613de68b8d63ffffffff61343c16565b613d2c612710613df461339c565b9063ffffffff61343c16565b611011613e0b6133fe565b613df48e8e63ffffffff61343c16565b9750613e273089612a2a565b50613e3061377f565b9098509650613e5190506127106110118a61ffff8b1663ffffffff61343c16565b9450613e5b610f8b565b9350613e68308587613f6c565b613e728486612c2c565b613e94613e8f6127106110118b61ffff8b1663ffffffff61343c16565b614663565b9250613eaa83613d2c8a8863ffffffff6135f016565b9150613eb4611348565b9050613ec1308284613f6c565b613ecb8183612c2c565b50505050505050505050565b6040805160008051602061529b8339815191528152905190819003601d019020600090819081908190613f0990612a26565b604080516000805160206152db8339815191528152905190819003601a019020909350613f3590612a26565b915081831015613f4157fe5b613f51838363ffffffff6135f016565b90506133f6816801bc16d674ec80000063ffffffff61343c16565b6040805160008051602061527b83398151915281529051908190036018019020600090613f9890612a26565b1515613fdc576040805160e560020a62461bcd02815260206004820152601360248201526000805160206152bb833981519152604482015290519081900360640190fd5b600160a060020a038416151561403c576040805160e560020a62461bcd02815260206004820152601e60248201527f5452414e534645525f46524f4d5f5448455f5a45524f5f414444524553530000604482015290519081900360640190fd5b600160a060020a038316151561409c576040805160e560020a62461bcd02815260206004820152601c60248201527f5452414e534645525f544f5f5448455f5a45524f5f4144445245535300000000604482015290519081900360640190fd5b50600160a060020a0383166000908152602081905260409020548082111561410e576040805160e560020a62461bcd02815260206004820152601f60248201527f5452414e534645525f414d4f554e545f455843454544535f42414c414e434500604482015290519081900360640190fd5b61411e818363ffffffff6135f016565b600160a060020a038086166000908152602081905260408082209390935590851681522054614153908363ffffffff61368416565b600160a060020a03909316600090815260208190526040902092909255505050565b60008061418183612a26565b905061271081111561148257fe5b60006060806000806060806141a26110fa565b600160a060020a03166341bc716f896040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156141e757600080fd5b505af11580156141fb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604090815281101561422457600080fd5b81019080805164010000000081111561423c57600080fd5b8201602081018481111561424f57600080fd5b815164010000000081118282018710171561426957600080fd5b5050929190602001805164010000000081111561428557600080fd5b8201602081018481111561429857600080fd5b81516401000000008111828201871017156142b257600080fd5b50508451949a509850505090151590506142cf5760009650614503565b85516142e290603063ffffffff61485416565b1561435d576040805160e560020a62461bcd02815260206004820152602160248201527f52454749535452595f494e434f4e53495354454e545f5055424b4559535f4c4560448201527f4e00000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b845161437090606063ffffffff61485416565b156143c5576040805160e560020a62461bcd02815260206004820152601d60248201527f52454749535452595f494e434f4e53495354454e545f5349475f4c454e000000604482015290519081900360640190fd5b85516143d890603063ffffffff6134e716565b85519094506143ee90606063ffffffff6134e716565b8414614444576040805160e560020a62461bcd02815260206004820152601f60248201527f52454749535452595f494e434f4e53495354454e545f5349475f434f554e5400604482015290519081900360640190fd5b600092505b8383101561448857614460866030850260306148f1565b9150614471856060850260606148f1565b905061447d8282614972565b826001019250614449565b6040805160008051602061529b8339815191528152905190819003601d0190206144e7906144bb90869061171a90612a26565b6040805160008051602061529b8339815191528152905190819003601d0190209063ffffffff613bbc16565b614500846801bc16d674ec80000063ffffffff61343c16565b96505b505050505050919050565b604080517f6c69646f2e4c69646f2e627566666572656445746865720000000000000000008152905190819003601701902061455390612ba4908390613d2c90612a26565b6040805182815290517f76a397bea5768d4fca97ef47792796e35f98dc81b16c1de84e28a818e1f971089181900360200190a150565b6000806000806040516020818751602089018a5afa925060008311156145ae57805191505b50909590945092505050565b6000806040516020818551602087016000895af160008111156145fe573d80156145eb57602081146145f4576145fc565b600193506145fc565b600183511493505b505b5090949350505050565b60408051600280825260608083018452926020830190803883390190505090508281600081518110151561463857fe5b60209081029091010152805182908290600190811061465357fe5b6020908102909101015292915050565b600060608060006146726110fa565b600160a060020a03166362dcfda1866040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156146b757600080fd5b505af11580156146cb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160409081528110156146f457600080fd5b81019080805164010000000081111561470c57600080fd5b8201602081018481111561471f57600080fd5b815185602082028301116401000000008211171561473c57600080fd5b5050929190602001805164010000000081111561475857600080fd5b8201602081018481111561476b57600080fd5b815185602082028301116401000000008211171561478857600080fd5b505092919050505092509250815183511415156147a157fe5b5060009250825b8251811015610c6e576147ea3084838151811015156147c357fe5b9060200190602002015184848151811015156147db57fe5b90602001906020020151613f6c565b61482283828151811015156147fb57fe5b90602001906020020151838381518110151561481357fe5b90602001906020020151612c2c565b61484a828281518110151561483357fe5b60209081029091010151859063ffffffff61368416565b93506001016147a8565b60408051808201909152600d81527f4d4154485f4449565f5a45524f0000000000000000000000000000000000000060208201526000908215156148dd5760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b5081838115156148e957fe5b069392505050565b60608082840185511015151561490657600080fd5b8215801561491f57604051915060208201604052614969565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015614958578051835260209283019201614940565b5050858452601f01601f1916604052505b50949350505050565b6000806000806000806000614985611431565b96508615156149de576040805160e560020a62461bcd02815260206004820152601c60248201527f454d5054595f5749544844524157414c5f43524544454e5449414c5300000000604482015290519081900360640190fd5b6801bc16d674ec80000095506149fe86633b9aca0063ffffffff6134e716565b945085614a1586633b9aca0063ffffffff61343c16565b14614a1c57fe5b6002614a278a6150f7565b6040518082805190602001908083835b60208310614a565780518252601f199092019160209182019101614a37565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af1158015614a97573d6000803e3d6000fd5b5050506040513d6020811015614aac57600080fd5b50519350600280614ac08a600060406148f1565b6040518082805190602001908083835b60208310614aef5780518252601f199092019160209182019101614ad0565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af1158015614b30573d6000803e3d6000fd5b5050506040513d6020811015614b4557600080fd5b50516002614b6d614b688c6040614b6360608263ffffffff6135f016565b6148f1565b6150f7565b6040518082805190602001908083835b60208310614b9c5780518252601f199092019160209182019101614b7d565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af1158015614bdd573d6000803e3d6000fd5b5050506040513d6020811015614bf257600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310614c485780518252601f199092019160209182019101614c29565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af1158015614c89573d6000803e3d6000fd5b5050506040513d6020811015614c9e57600080fd5b50516040805160208181018890528183018b905282518083038401815260609092019283905281519396506002938493918291908401908083835b60208310614cf85780518252601f199092019160209182019101614cd9565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af1158015614d39573d6000803e3d6000fd5b5050506040513d6020811015614d4e57600080fd5b50516002614d5b88615187565b60408051602080820193909352808201899052815180820383018152606090910191829052805190928291908401908083835b60208310614dad5780518252601f199092019160209182019101614d8e565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af1158015614dee573d6000803e3d6000fd5b5050506040513d6020811015614e0357600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310614e595780518252601f199092019160209182019101614e3a565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af1158015614e9a573d6000803e3d6000fd5b5050506040513d6020811015614eaf57600080fd5b50519150614ec430318763ffffffff6135f016565b9050614ece6120de565b600160a060020a03166322895118878b8a6040516020018082600019166000191681526020019150506040516020818303038152906040528c876040518663ffffffff1660e01b8152600401808060200180602001806020018560001916600019168152602001848103845288818151815260200191508051906020019080838360005b83811015614f6a578181015183820152602001614f52565b50505050905090810190601f168015614f975780820380516001836020036101000a031916815260200191505b50848103835287518152875160209182019189019080838360005b83811015614fca578181015183820152602001614fb2565b50505050905090810190601f168015614ff75780820380516001836020036101000a031916815260200191505b50848103825286518152865160209182019188019080838360005b8381101561502a578181015183820152602001615012565b50505050905090810190601f1680156150575780820380516001836020036101000a031916815260200191505b509750505050505050506000604051808303818588803b15801561507a57600080fd5b505af115801561508e573d6000803e3d6000fd5b505050503031821490506150ec576040805160e560020a62461bcd02815260206004820152601b60248201527f455850454354494e475f4445504f5349545f544f5f48415050454e0000000000604482015290519081900360640190fd5b505050505050505050565b606080602083511015801561510e57506040835111155b151561511657fe5b82516040141561512857829150611020565b6040805160208082528183019092529080820161040080388339019050509050600060208201528251602014156151635761101d83826151bf565b61101d83615182836000614b63885160406135f090919063ffffffff16565b6151bf565b600081815b60088110156151ad57600892831b60ff831617929190911c9060010161518c565b81156151b557fe5b505060c01b919050565b6060806040519050835180825260208201818101602087015b818310156151f05780518352602092830192016151d8565b50855184518101855292509050808201602086015b8183101561521d578051835260209283019201615205565b509551919091011594909401601f01601f1916604052939250505056004150505f415554485f4641494c454400000000000000000000000000000000006c69646f2e4c69646f2e626561636f6e42616c616e63650000000000000000006c69646f2e5061757361626c652e616374697665466c616700000000000000006c69646f2e4c69646f2e6465706f736974656456616c696461746f7273000000434f4e54524143545f49535f53544f50504544000000000000000000000000006c69646f2e4c69646f2e626561636f6e56616c696461746f7273000000000000a165627a7a72305820e5d1af58d1fe3523853b92051246573e5294059e57fe18edf31c4d03b1f89ffe0029ebb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e

Deployed Bytecode

0x6080604052600436106102e45760003560e01c63ffffffff168063046f7da21461034757806306fdde031461035e57806307da68f5146103e85780630803fac0146103fd578063095ea7b3146104265780631459457a1461044a578063158626f71461048357806318160ddd146104b457806319208451146104db57806323b872dd146104f357806327a099d81461051d5780632914b9bd14610532578063313ce5671461058b57806332f0a3b5146105b6578063353efdcf146105cb57806336bf3325146105e057806337cfdaca146104b4578063389ed267146105f5578063395093511461060a5780633b19e84a1461062e5780633c1c2dc0146106435780633f683b6a14610658578063435721da1461066d57806347b714e014610682578063540bc5ea1461069757806356396715146106ac57806370a08231146106c1578063752f77f1146106e25780637a28fb881461071d5780637adbf973146107355780637e7db6e11461075657806380afdea814610777578063833b1fce1461078c5780638b3dd749146107a15780638cef3612146107b65780638e005553146107de57806390adc83b146107fa57806395d89b41146108125780639aaa2d15146108275780639d4941d81461083c578063a0654fdc1461085d578063a1658fad14610872578063a1903eab146108d9578063a30448c0146108ed578063a457c2d714610902578063a479e50814610926578063a4d55d1d1461093b578063a8d2021a14610950578063a9059cbb1461096b578063ab94276a1461098f578063ae2e3538146109a4578063b930908f146109d7578063c3c05293146109ec578063ced72f8714610a0d578063d0cc43c514610a39578063d4aae0c414610a4e578063d5002f2e14610a63578063dd62ed3e14610a78578063de4796ed14610a9f578063e97ee8cc14610ab4578063ecc1dcfb14610acc578063ee7a7c0414610ae1578063f0f4426014610b05578063f16ac1fc14610b26578063f5eb42dc14610b41575b361561033a576040805160e560020a62461bcd02815260206004820152600e60248201527f4e4f4e5f454d5054595f44415441000000000000000000000000000000000000604482015290519081900360640190fd5b6103446000610b62565b50005b34801561035357600080fd5b5061035c610c76565b005b34801561036a57600080fd5b50610373610d81565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103ad578181015183820152602001610395565b50505050905090810190601f1680156103da5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103f457600080fd5b5061035c610db8565b34801561040957600080fd5b50610412610e82565b604080519115158252519081900360200190f35b34801561043257600080fd5b50610412600160a060020a0360043516602435610eab565b34801561045657600080fd5b5061035c600160a060020a0360043581169060243581169060443581169060643581169060843516610ec1565b34801561048f57600080fd5b50610498610f8b565b60408051600160a060020a039092168252519081900360200190f35b3480156104c057600080fd5b506104c9610fce565b60408051918252519081900360200190f35b3480156104e757600080fd5b506104c9600435610fd8565b3480156104ff57600080fd5b50610412600160a060020a0360043581169060243516604435611026565b34801561052957600080fd5b506104986110fa565b34801561053e57600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526104989436949293602493928401919081908401838280828437509497506111389650505050505050565b34801561059757600080fd5b506105a061121b565b6040805160ff9092168252519081900360200190f35b3480156105c257600080fd5b50610498611220565b3480156105d757600080fd5b506104c9611295565b3480156105ec57600080fd5b506104c96112ca565b34801561060157600080fd5b506104c96112d7565b34801561061657600080fd5b50610412600160a060020a036004351660243561130c565b34801561063a57600080fd5b50610498611348565b34801561064f57600080fd5b506104c9611386565b34801561066457600080fd5b506104126113bb565b34801561067957600080fd5b506104c96113ed565b34801561068e57600080fd5b506104c9611422565b3480156106a357600080fd5b506104c961142c565b3480156106b857600080fd5b506104c9611431565b3480156106cd57600080fd5b506104c9600160a060020a036004351661146f565b3480156106ee57600080fd5b506106f7611488565b6040805161ffff9485168152928416602084015292168183015290519081900360600190f35b34801561072957600080fd5b506104c96004356114a0565b34801561074157600080fd5b5061035c600160a060020a03600435166114cc565b34801561076257600080fd5b50610412600160a060020a036004351661159b565b34801561078357600080fd5b506104c96115a1565b34801561079857600080fd5b506104986115cc565b3480156107ad57600080fd5b506104c961160a565b3480156107c257600080fd5b5061035c61ffff60043581169060243581169060443516611635565b3480156107ea57600080fd5b5061035c61ffff6004351661187e565b34801561080657600080fd5b5061035c6004356119b7565b34801561081e57600080fd5b50610373611a82565b34801561083357600080fd5b506104c9611ab9565b34801561084857600080fd5b5061035c600160a060020a0360043516611aee565b34801561086957600080fd5b506104c9611d2d565b34801561087e57600080fd5b506040805160206004604435818101358381028086018501909652808552610412958335600160a060020a0316956024803596369695606495939492019291829185019084908082843750949750611d629650505050505050565b6104c9600160a060020a0360043516611ead565b3480156108f957600080fd5b506104c9611eb8565b34801561090e57600080fd5b50610412600160a060020a0360043516602435611ebd565b34801561093257600080fd5b50610498611f5a565b34801561094757600080fd5b506104c961200f565b34801561095c57600080fd5b5061035c600435602435612014565b34801561097757600080fd5b50610412600160a060020a03600435166024356120d1565b34801561099b57600080fd5b506104986120de565b3480156109b057600080fd5b506109b961211c565b60408051938452602084019290925282820152519081900360600190f35b3480156109e357600080fd5b506104c96121ab565b3480156109f857600080fd5b5061035c600160a060020a03600435166121e0565b348015610a1957600080fd5b50610a226122ab565b6040805161ffff9092168252519081900360200190f35b348015610a4557600080fd5b506104c96122b5565b348015610a5a57600080fd5b506104986122ea565b348015610a6f57600080fd5b506104c9612315565b348015610a8457600080fd5b506104c9600160a060020a036004358116906024351661231f565b348015610aab57600080fd5b5061041261234a565b348015610ac057600080fd5b5061035c60043561235d565b348015610ad857600080fd5b5061035c6124f3565b348015610aed57600080fd5b506104c9600160a060020a03600435166024356125bf565b348015610b1157600080fd5b5061035c600160a060020a0360043516612691565b348015610b3257600080fd5b5061035c60043560243561275c565b348015610b4d57600080fd5b506104c9600160a060020a0360043516612a1b565b6040805160008051602061527b83398151915281529051908190036018019020600090819081908190610b9490612a26565b1515610bd8576040805160e560020a62461bcd02815260206004820152601360248201526000805160206152bb833981519152604482015290519081900360640190fd5b339250349150811515610c35576040805160e560020a62461bcd02815260206004820152600c60248201527f5a45524f5f4445504f5349540000000000000000000000000000000000000000604482015290519081900360640190fd5b610c3e82610fd8565b9050801515610c4a5750805b610c548382612a2a565b50610c60838387612b95565b610c6a8382612c2c565b8093505b505050919050565b604080517f50415553455f524f4c45000000000000000000000000000000000000000000008152815190819003600a01812060008083526020830190935291610cc59133918491905b50611d62565b60408051808201909152600f815260008051602061523b8339815191526020820152901515610d755760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610d3a578181015183820152602001610d22565b50505050905090810190601f168015610d675780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50610d7e612c77565b50565b60408051808201909152601781527f4c6971756964207374616b656420457468657220322e30000000000000000000602082015290565b604080517f50415553455f524f4c45000000000000000000000000000000000000000000008152815190819003600a01812060008083526020830190935291610e05913391849190610cbf565b60408051808201909152600f815260008051602061523b8339815191526020820152901515610e795760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b50610d7e612d51565b600080610e8d61160a565b90508015801590610ea5575080610ea2612e1a565b10155b91505090565b6000610eb8338484612e1e565b50600192915050565b610ec961160a565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a4544000000000000000060208201529015610f4e5760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b50610f5885612fad565b610f618461304e565b610f6a836130ef565b610f7382613190565b610f7c81613232565b610f846132d4565b5050505050565b604080517f6c69646f2e4c69646f2e696e737572616e636546756e6400000000000000000081529051908190036017019020600090610fc990612a26565b905090565b6000610fc961339c565b600080610fe361339c565b9050801515610ff55760009150611020565b61101d816110116110046133fe565b869063ffffffff61343c16565b9063ffffffff6134e716565b91505b50919050565b600160a060020a0383166000908152600160209081526040808320338452909152812054828110156110c8576040805160e560020a62461bcd02815260206004820152602160248201527f5452414e534645525f414d4f554e545f455843454544535f414c4c4f57414e4360448201527f4500000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6110d3858585613587565b6110ed85336110e8848763ffffffff6135f016565b612e1e565b600191505b509392505050565b604080517f6c69646f2e4c69646f2e6e6f64654f70657261746f72735265676973747279008152905190819003601f019020600090610fc990612a26565b6000611142611f5a565b600160a060020a03166304bf2a7f836040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561119d578181015183820152602001611185565b50505050905090810190601f1680156111ca5780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b1580156111e957600080fd5b505af11580156111fd573d6000803e3d6000fd5b505050506040513d602081101561121357600080fd5b505192915050565b601290565b600061122a6122ea565b600160a060020a03166332f0a3b56040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561126457600080fd5b505af1158015611278573d6000803e3d6000fd5b505050506040513d602081101561128e57600080fd5b5051905090565b604080517f4445504f5349545f524f4c4500000000000000000000000000000000000000008152905190819003600c01902081565b6801bc16d674ec80000081565b604080517f50415553455f524f4c45000000000000000000000000000000000000000000008152905190819003600a01902081565b336000818152600160209081526040808320600160a060020a03871684529091528120549091610eb89185906110e8908663ffffffff61368416565b604080517f6c69646f2e4c69646f2e7472656173757279000000000000000000000000000081529051908190036012019020600090610fc990612a26565b604080517f5345545f4f5241434c45000000000000000000000000000000000000000000008152905190819003600a01902081565b6040805160008051602061527b833981519152815290519081900360180190206000906113e790612a26565b15905090565b604080517f4d414e4147455f5749544844524157414c5f4b455900000000000000000000008152905190819003601501902081565b6000610fc9613712565b606081565b604080517f6c69646f2e4c69646f2e7769746864726177616c43726564656e7469616c73008152905190819003601f019020600090610fc990612a26565b600061148261147d83613764565b6114a0565b92915050565b600080600061149561377f565b925092509250909192565b6000806114ab6133fe565b90508015156114bd5760009150611020565b61101d8161101161100461339c565b604080517f5345545f4f5241434c45000000000000000000000000000000000000000000008152815190819003600a01812060008083526020830190935291611519913391849190610cbf565b60408051808201909152600f815260008051602061523b833981519152602082015290151561158d5760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b506115978261304e565b5050565b50600190565b6000610fc97fd625496217aa6a3453eecb9c3489dc5a53e6c67b444329ea2b2cbc9ff547639b612a26565b604080517f6c69646f2e4c69646f2e6f7261636c650000000000000000000000000000000081529051908190036010019020600090610fc990612a26565b6000610fc97febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e612a26565b604080517f4d414e4147455f464545000000000000000000000000000000000000000000008152815190819003600a01812060008083526020830190935291611682913391849190610cbf565b60408051808201909152600f815260008051602061523b83398151915260208201529015156116f65760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b506117268261ffff1661171a8561ffff168761ffff1661368490919063ffffffff16565b9063ffffffff61368416565b6127101461177e576040805160e560020a62461bcd02815260206004820152601060248201527f464545535f444f4e545f4144445f555000000000000000000000000000000000604482015290519081900360640190fd5b604080517f6c69646f2e4c69646f2e74726561737572794665650000000000000000000000815290519081900360150190206117ba9085613842565b604080517f6c69646f2e4c69646f2e696e737572616e636546656500000000000000000000815290519081900360160190206117f69084613842565b604080517f6c69646f2e4c69646f2e6e6f64654f70657261746f72734665650000000000008152905190819003601a0190206118329083613842565b6040805161ffff8087168252808616602083015284168183015290517f034529db1bba3830b8877e116871f19c5b96ef86c739f2a05668c860c84668989181900360600190a150505050565b604080517f4d414e4147455f464545000000000000000000000000000000000000000000008152815190819003600a018120600080835260208301909352916118cb913391849190610cbf565b60408051808201909152600f815260008051602061523b833981519152602082015290151561193f5760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b50604080517f6c69646f2e4c69646f2e666565000000000000000000000000000000000000008152905190819003600d01902061197c9083613842565b6040805161ffff8416815290517faab062e3faf62b6c9a0f8e62af66e0310e27127a8c871a67be7dd4d93de6da539181900360200190a15050565b604080517f4445504f5349545f524f4c4500000000000000000000000000000000000000008152815190819003600c01812060008083526020830190935291611a04913391849190610cbf565b60408051808201909152600f815260008051602061523b8339815191526020820152901515611a785760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b50611597826138b4565b60408051808201909152600581527f7374455448000000000000000000000000000000000000000000000000000000602082015290565b604080517f4d414e4147455f464545000000000000000000000000000000000000000000008152905190819003600a01902081565b6000806000611afc8461159b565b1515611b52576040805160e560020a62461bcd02815260206004820152601260248201527f5245434f5645525f444953414c4c4f5745440000000000000000000000000000604482015290519081900360640190fd5b611b5a611220565b9250611b658361399c565b1515611bbb576040805160e560020a62461bcd02815260206004820152601a60248201527f5245434f5645525f5641554c545f4e4f545f434f4e5452414354000000000000604482015290519081900360640190fd5b600160a060020a0384161515611c4f57611bd36139c2565b915082600160a060020a03168260405160006040518083038185875af1925050501515611c4a576040805160e560020a62461bcd02815260206004820152601760248201527f5245434f5645525f5452414e534645525f4641494c4544000000000000000000604482015290519081900360640190fd5b611cdc565b5082611c6a600160a060020a0382163063ffffffff6139dd16565b9150611c86600160a060020a038216848463ffffffff613af216565b1515611cdc576040805160e560020a62461bcd02815260206004820152601d60248201527f5245434f5645525f544f4b454e5f5452414e534645525f4641494c4544000000604482015290519081900360640190fd5b83600160a060020a031683600160a060020a03167f596caf56044b55fb8c4ca640089bbc2b63cae3e978b851f5745cbb7c5b288e02846040518082815260200191505060405180910390a350505050565b604080517f5345545f545245415355525900000000000000000000000000000000000000008152905190819003600c01902081565b600080611d6d610e82565b1515611d7c57600091506110f2565b611d846122ea565b9050600160a060020a0381161515611d9f57600091506110f2565b80600160a060020a031663fdef9106863087611dba88613b74565b60405163ffffffff861660e01b8152600160a060020a03808616600483019081529085166024830152604482018490526080606483019081528351608484015283519192909160a490910190602085019080838360005b83811015611e29578181015183820152602001611e11565b50505050905090810190601f168015611e565780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b158015611e7857600080fd5b505af1158015611e8c573d6000803e3d6000fd5b505050506040513d6020811015611ea257600080fd5b505195945050505050565b600061148282610b62565b602081565b336000908152600160209081526040808320600160a060020a038616845290915281205482811015611f39576040805160e560020a62461bcd02815260206004820152601e60248201527f4445435245415345445f414c4c4f57414e43455f42454c4f575f5a45524f0000604482015290519081900360640190fd5b611f4e33856110e8848763ffffffff6135f016565b600191505b5092915050565b600080611f656122ea565b604080517fbe00bbd80000000000000000000000000000000000000000000000000000000081527fd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb60048201527fddbcfd564f642ab5627cf68b9b7d374fb4f8a36e941a75d89c87998cef03bd6160248201529051600160a060020a03929092169163be00bbd8916044808201926020929091908290030181600087803b1580156111e957600080fd5b603081565b6040805160008051602061527b8339815191528152905190819003601801902061203d90612a26565b1515612081576040805160e560020a62461bcd02815260206004820152601360248201526000805160206152bb833981519152604482015290519081900360640190fd5b6040805160e560020a62461bcd02815260206004820152601360248201527f4e4f545f494d504c454d454e5445445f59455400000000000000000000000000604482015290519081900360640190fd5b6000610eb8338484613587565b604080517f6c69646f2e4c69646f2e6465706f736974436f6e74726163740000000000000081529051908190036019019020600090610fc990612a26565b6040805160008051602061529b8339815191528152905190819003601d0190206000908190819061214c90612a26565b604080516000805160206152db8339815191528152905190819003601a01902090935061217890612a26565b6040805160008051602061525b833981519152815290519081900360170190209092506121a490612a26565b9050909192565b604080517f4255524e5f524f4c4500000000000000000000000000000000000000000000008152905190819003600901902081565b604080517f5345545f494e535552414e43455f46554e440000000000000000000000000000815281519081900360120181206000808352602083019093529161222d913391849190610cbf565b60408051808201909152600f815260008051602061523b83398151915260208201529015156122a15760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b5061159782613232565b6000610fc9613b7e565b604080517f5345545f494e535552414e43455f46554e4400000000000000000000000000008152905190819003601201902081565b6000610fc97f4172f0f7d2289153072b0a6ca36959e0cbe2efc3afe50fc81636caa96338137b612a26565b6000610fc96133fe565b600160a060020a03918216600090815260016020908152604080832093909416825291909152205490565b600060001961235761160a565b14905090565b604080517f4d414e4147455f5749544844524157414c5f4b4559000000000000000000000081528151908190036015018120600080835260208301909352916123aa913391849190610cbf565b60408051808201909152600f815260008051602061523b833981519152602082015290151561241e5760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b50604080517f6c69646f2e4c69646f2e7769746864726177616c43726564656e7469616c73008152905190819003601f019020612461908363ffffffff613bbc16565b6124696110fa565b600160a060020a031663f778021e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156124a357600080fd5b505af11580156124b7573d6000803e3d6000fd5b50506040805185815290517f13eb80e900aa05a2696d50d5de33ef631c73493c4921da233b17335ff6b7b1149350908190036020019150a15050565b604080517f4445504f5349545f524f4c4500000000000000000000000000000000000000008152815190819003600c01812060008083526020830190935291612540913391849190610cbf565b60408051808201909152600f815260008051602061523b83398151915260208201529015156125b45760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b50610d7e60966138b4565b604080517f4255524e5f524f4c450000000000000000000000000000000000000000000000815290519081900360090190206000906125fe8484613bc0565b612609338383611d62565b60408051808201909152600f815260008051602061523b833981519152602082015290151561267d5760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b506126888585613bdc565b95945050505050565b604080517f5345545f545245415355525900000000000000000000000000000000000000008152815190819003600c018120600080835260208301909352916126de913391849190610cbf565b60408051808201909152600f815260008051602061523b83398151915260208201529015156127525760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b5061159782613190565b6000806000806000612794604051808060008051602061527b8339815191528152506018019050604051809103902060001916612a26565b15156127d8576040805160e560020a62461bcd02815260206004820152601360248201526000805160206152bb833981519152604482015290519081900360640190fd5b6127e06115cc565b600160a060020a0316331461282d576040805160e560020a62461bcd02815260206004820152600f602482015260008051602061523b833981519152604482015290519081900360640190fd5b6040805160008051602061529b8339815191528152905190819003601d01902061285690612a26565b9450848711156128b0576040805160e560020a62461bcd02815260206004820152601760248201527f5245504f525445445f4d4f52455f4445504f5349544544000000000000000000604482015290519081900360640190fd5b604080516000805160206152db8339815191528152905190819003601a0190206128d990612a26565b935083871015612933576040805160e560020a62461bcd02815260206004820152601860248201527f5245504f525445445f4c4553535f56414c494441544f52530000000000000000604482015290519081900360640190fd5b612943878563ffffffff6135f016565b6040805160008051602061525b8339815191528152905190819003601701902090935061298c9061297390612a26565b61171a856801bc16d674ec80000063ffffffff61343c16565b6040805160008051602061525b833981519152815290519081900360170190209092506129bf908763ffffffff613bbc16565b604080516000805160206152db8339815191528152905190819003601a0190206129ef908863ffffffff613bbc16565b81861115612a1257612a07868363ffffffff6135f016565b9050612a1281613db4565b50505050505050565b600061148282613764565b5490565b6040805160008051602061527b83398151915281529051908190036018019020600090612a5690612a26565b1515612a9a576040805160e560020a62461bcd02815260206004820152601360248201526000805160206152bb833981519152604482015290519081900360640190fd5b600160a060020a0383161515612afa576040805160e560020a62461bcd02815260206004820152601860248201527f4d494e545f544f5f5448455f5a45524f5f414444524553530000000000000000604482015290519081900360640190fd5b612b068261171a6133fe565b604080517f6c69646f2e53744554482e746f74616c5368617265730000000000000000000081529051908190036016019020909150612b4b908263ffffffff613bbc16565b600160a060020a038316600090815260208190526040902054612b74908363ffffffff61368416565b600160a060020a039093166000908152602081905260409020929092555090565b612be2612ba48361171a613712565b604080517f6c69646f2e4c69646f2e62756666657265644574686572000000000000000000815290519081900360170190209063ffffffff613bbc16565b60408051838152600160a060020a0383811660208301528251908616927f96a25c8ce0baabc1fdefd93e9ed25d8e092a3332f3aa9a41722b5697231d1d1a928290030190a2505050565b600160a060020a03821660007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef612c62846114a0565b60408051918252519081900360200190a35050565b6040805160008051602061527b83398151915281529051908190036018019020612ca090612a26565b15612cf5576040805160e560020a62461bcd02815260206004820152601260248201527f434f4e54524143545f49535f4143544956450000000000000000000000000000604482015290519081900360640190fd5b6040805160008051602061527b83398151915281529051908190036018019020612d2690600163ffffffff613bbc16565b6040517f62451d457bc659158be6e6247f56ec1df424a5c7597f71c20c2bc44e0965c8f990600090a1565b6040805160008051602061527b83398151915281529051908190036018019020612d7a90612a26565b1515612dbe576040805160e560020a62461bcd02815260206004820152601360248201526000805160206152bb833981519152604482015290519081900360640190fd5b6040805160008051602061527b83398151915281529051908190036018019020612def90600063ffffffff613bbc16565b6040517f7acc84e34091ae817647a4c49116f5cc07f319078ba80f8f5fde37ea7e25cbd690600090a1565b4390565b6040805160008051602061527b83398151915281529051908190036018019020612e4790612a26565b1515612e8b576040805160e560020a62461bcd02815260206004820152601360248201526000805160206152bb833981519152604482015290519081900360640190fd5b600160a060020a0383161515612eeb576040805160e560020a62461bcd02815260206004820152601960248201527f415050524f56455f46524f4d5f5a45524f5f4144445245535300000000000000604482015290519081900360640190fd5b600160a060020a0382161515612f4b576040805160e560020a62461bcd02815260206004820152601760248201527f415050524f56455f544f5f5a45524f5f41444452455353000000000000000000604482015290519081900360640190fd5b600160a060020a03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b612fb68161399c565b151561300c576040805160e560020a62461bcd02815260206004820152600e60248201527f4e4f545f415f434f4e5452414354000000000000000000000000000000000000604482015290519081900360640190fd5b604080517f6c69646f2e4c69646f2e6465706f736974436f6e74726163740000000000000081529051908190036019019020610d7e908263ffffffff613bbc16565b6130578161399c565b15156130ad576040805160e560020a62461bcd02815260206004820152600e60248201527f4e4f545f415f434f4e5452414354000000000000000000000000000000000000604482015290519081900360640190fd5b604080517f6c69646f2e4c69646f2e6f7261636c650000000000000000000000000000000081529051908190036010019020610d7e908263ffffffff613bbc16565b6130f88161399c565b151561314e576040805160e560020a62461bcd02815260206004820152600e60248201527f4e4f545f415f434f4e5452414354000000000000000000000000000000000000604482015290519081900360640190fd5b604080517f6c69646f2e4c69646f2e6e6f64654f70657261746f72735265676973747279008152905190819003601f019020610d7e908263ffffffff613bbc16565b600160a060020a03811615156131f0576040805160e560020a62461bcd02815260206004820152601960248201527f5345545f54524541535552595f5a45524f5f4144445245535300000000000000604482015290519081900360640190fd5b604080517f6c69646f2e4c69646f2e7472656173757279000000000000000000000000000081529051908190036012019020610d7e908263ffffffff613bbc16565b600160a060020a0381161515613292576040805160e560020a62461bcd02815260206004820152601f60248201527f5345545f494e535552414e43455f46554e445f5a45524f5f4144445245535300604482015290519081900360640190fd5b604080517f6c69646f2e4c69646f2e696e737572616e636546756e6400000000000000000081529051908190036017019020610d7e908263ffffffff613bbc16565b6132dc61160a565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a45440000000000000000602082015290156133615760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b5061339a61336d612e1a565b7febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e9063ffffffff613bbc16565b565b6000806000806133aa613712565b6040805160008051602061525b833981519152815290519081900360170190209093506133d690612a26565b91506133e0613ed7565b90506133f68161171a858563ffffffff61368416565b935050505090565b604080517f6c69646f2e53744554482e746f74616c5368617265730000000000000000000081529051908190036016019020600090610fc990612a26565b60008083151561344f5760009150611f53565b5082820282848281151561345f57fe5b60408051808201909152601181527f4d4154485f4d554c5f4f564552464c4f57000000000000000000000000000000602082015292919004146110f25760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b60408051808201909152600d81527f4d4154485f4449565f5a45524f00000000000000000000000000000000000000602082015260009081908184116135725760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b50828481151561357e57fe5b04949350505050565b600061359282610fd8565b905061359f848483613f6c565b82600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a350505050565b60408051808201909152601281527f4d4154485f5355425f554e444552464c4f570000000000000000000000000000602082015260009081908484111561367c5760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b505050900390565b60408051808201909152601181527f4d4154485f4144445f4f564552464c4f57000000000000000000000000000000602082015260009083830190848210156110f25760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b604080517f6c69646f2e4c69646f2e6275666665726564457468657200000000000000000081529051908190036017019020600090819061375290612a26565b9050303181111561375f57fe5b919050565b600160a060020a031660009081526020819052604090205490565b60008060006137c260405180807f6c69646f2e4c69646f2e7472656173757279466565000000000000000000000081525060150190506040518091039020614175565b604080517f6c69646f2e4c69646f2e696e737572616e6365466565000000000000000000008152905190819003601601902090935061380090614175565b604080517f6c69646f2e4c69646f2e6e6f64654f70657261746f72734665650000000000008152905190819003601a0190209092506121a490614175565b5490565b61271061ffff821611156138a0576040805160e560020a62461bcd02815260206004820152601660248201527f56414c55455f4f5645525f3130305f50455243454e5400000000000000000000604482015290519081900360640190fd5b6115978261ffff831663ffffffff613bbc16565b6040805160008051602061527b83398151915281529051908190036018019020600090819081906138e490612a26565b1515613928576040805160e560020a62461bcd02815260206004820152601360248201526000805160206152bb833981519152604482015290519081900360640190fd5b613930613712565b92506801bc16d674ec80000083106139965761394a6139c2565b9150613965836801bc16d674ec80000063ffffffff6134e716565b905061398661398185831061397a578561397c565b825b61418f565b61450e565b8161398f6139c2565b1461399657fe5b50505050565b600080600160a060020a03831615156139b85760009150611020565b50506000903b1190565b6000610fc96139cf613712565b30319063ffffffff6135f016565b60408051600160a060020a0383166024808301919091528251808303909101815260449091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a08231000000000000000000000000000000000000000000000000000000001790526000908180613a5d8684614589565b60408051808201909152601c81527f534146455f4552435f32305f42414c414e43455f52455645525445440000000060208201529193509150821515613ae85760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b5095945050505050565b60408051600160a060020a038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905260009061268885826145ba565b8051602002815290565b604080517f6c69646f2e4c69646f2e666565000000000000000000000000000000000000008152905190819003600d019020600090610fc990614175565b9055565b6060613bd583600160a060020a031683614608565b9392505050565b6040805160008051602061527b833981519152815290519081900360180190206000908190613c0a90612a26565b1515613c4e576040805160e560020a62461bcd02815260206004820152601360248201526000805160206152bb833981519152604482015290519081900360640190fd5b600160a060020a0384161515613cae576040805160e560020a62461bcd02815260206004820152601a60248201527f4255524e5f46524f4d5f5448455f5a45524f5f41444452455353000000000000604482015290519081900360640190fd5b50600160a060020a03831660009081526020819052604090205480831115613d20576040805160e560020a62461bcd02815260206004820152601b60248201527f4255524e5f414d4f554e545f455843454544535f42414c414e43450000000000604482015290519081900360640190fd5b613d3883613d2c6133fe565b9063ffffffff6135f016565b604080517f6c69646f2e53744554482e746f74616c5368617265730000000000000000000081529051908190036016019020909250613d7d908363ffffffff613bbc16565b613d8d818463ffffffff6135f016565b600160a060020a0390941660009081526020819052604090209390935592915050565b9055565b6000806000806000806000806000613dca613b7e565b61ffff169850613e1b613e00613de68b8d63ffffffff61343c16565b613d2c612710613df461339c565b9063ffffffff61343c16565b611011613e0b6133fe565b613df48e8e63ffffffff61343c16565b9750613e273089612a2a565b50613e3061377f565b9098509650613e5190506127106110118a61ffff8b1663ffffffff61343c16565b9450613e5b610f8b565b9350613e68308587613f6c565b613e728486612c2c565b613e94613e8f6127106110118b61ffff8b1663ffffffff61343c16565b614663565b9250613eaa83613d2c8a8863ffffffff6135f016565b9150613eb4611348565b9050613ec1308284613f6c565b613ecb8183612c2c565b50505050505050505050565b6040805160008051602061529b8339815191528152905190819003601d019020600090819081908190613f0990612a26565b604080516000805160206152db8339815191528152905190819003601a019020909350613f3590612a26565b915081831015613f4157fe5b613f51838363ffffffff6135f016565b90506133f6816801bc16d674ec80000063ffffffff61343c16565b6040805160008051602061527b83398151915281529051908190036018019020600090613f9890612a26565b1515613fdc576040805160e560020a62461bcd02815260206004820152601360248201526000805160206152bb833981519152604482015290519081900360640190fd5b600160a060020a038416151561403c576040805160e560020a62461bcd02815260206004820152601e60248201527f5452414e534645525f46524f4d5f5448455f5a45524f5f414444524553530000604482015290519081900360640190fd5b600160a060020a038316151561409c576040805160e560020a62461bcd02815260206004820152601c60248201527f5452414e534645525f544f5f5448455f5a45524f5f4144445245535300000000604482015290519081900360640190fd5b50600160a060020a0383166000908152602081905260409020548082111561410e576040805160e560020a62461bcd02815260206004820152601f60248201527f5452414e534645525f414d4f554e545f455843454544535f42414c414e434500604482015290519081900360640190fd5b61411e818363ffffffff6135f016565b600160a060020a038086166000908152602081905260408082209390935590851681522054614153908363ffffffff61368416565b600160a060020a03909316600090815260208190526040902092909255505050565b60008061418183612a26565b905061271081111561148257fe5b60006060806000806060806141a26110fa565b600160a060020a03166341bc716f896040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156141e757600080fd5b505af11580156141fb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604090815281101561422457600080fd5b81019080805164010000000081111561423c57600080fd5b8201602081018481111561424f57600080fd5b815164010000000081118282018710171561426957600080fd5b5050929190602001805164010000000081111561428557600080fd5b8201602081018481111561429857600080fd5b81516401000000008111828201871017156142b257600080fd5b50508451949a509850505090151590506142cf5760009650614503565b85516142e290603063ffffffff61485416565b1561435d576040805160e560020a62461bcd02815260206004820152602160248201527f52454749535452595f494e434f4e53495354454e545f5055424b4559535f4c4560448201527f4e00000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b845161437090606063ffffffff61485416565b156143c5576040805160e560020a62461bcd02815260206004820152601d60248201527f52454749535452595f494e434f4e53495354454e545f5349475f4c454e000000604482015290519081900360640190fd5b85516143d890603063ffffffff6134e716565b85519094506143ee90606063ffffffff6134e716565b8414614444576040805160e560020a62461bcd02815260206004820152601f60248201527f52454749535452595f494e434f4e53495354454e545f5349475f434f554e5400604482015290519081900360640190fd5b600092505b8383101561448857614460866030850260306148f1565b9150614471856060850260606148f1565b905061447d8282614972565b826001019250614449565b6040805160008051602061529b8339815191528152905190819003601d0190206144e7906144bb90869061171a90612a26565b6040805160008051602061529b8339815191528152905190819003601d0190209063ffffffff613bbc16565b614500846801bc16d674ec80000063ffffffff61343c16565b96505b505050505050919050565b604080517f6c69646f2e4c69646f2e627566666572656445746865720000000000000000008152905190819003601701902061455390612ba4908390613d2c90612a26565b6040805182815290517f76a397bea5768d4fca97ef47792796e35f98dc81b16c1de84e28a818e1f971089181900360200190a150565b6000806000806040516020818751602089018a5afa925060008311156145ae57805191505b50909590945092505050565b6000806040516020818551602087016000895af160008111156145fe573d80156145eb57602081146145f4576145fc565b600193506145fc565b600183511493505b505b5090949350505050565b60408051600280825260608083018452926020830190803883390190505090508281600081518110151561463857fe5b60209081029091010152805182908290600190811061465357fe5b6020908102909101015292915050565b600060608060006146726110fa565b600160a060020a03166362dcfda1866040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156146b757600080fd5b505af11580156146cb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160409081528110156146f457600080fd5b81019080805164010000000081111561470c57600080fd5b8201602081018481111561471f57600080fd5b815185602082028301116401000000008211171561473c57600080fd5b5050929190602001805164010000000081111561475857600080fd5b8201602081018481111561476b57600080fd5b815185602082028301116401000000008211171561478857600080fd5b505092919050505092509250815183511415156147a157fe5b5060009250825b8251811015610c6e576147ea3084838151811015156147c357fe5b9060200190602002015184848151811015156147db57fe5b90602001906020020151613f6c565b61482283828151811015156147fb57fe5b90602001906020020151838381518110151561481357fe5b90602001906020020151612c2c565b61484a828281518110151561483357fe5b60209081029091010151859063ffffffff61368416565b93506001016147a8565b60408051808201909152600d81527f4d4154485f4449565f5a45524f0000000000000000000000000000000000000060208201526000908215156148dd5760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015610d3a578181015183820152602001610d22565b5081838115156148e957fe5b069392505050565b60608082840185511015151561490657600080fd5b8215801561491f57604051915060208201604052614969565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015614958578051835260209283019201614940565b5050858452601f01601f1916604052505b50949350505050565b6000806000806000806000614985611431565b96508615156149de576040805160e560020a62461bcd02815260206004820152601c60248201527f454d5054595f5749544844524157414c5f43524544454e5449414c5300000000604482015290519081900360640190fd5b6801bc16d674ec80000095506149fe86633b9aca0063ffffffff6134e716565b945085614a1586633b9aca0063ffffffff61343c16565b14614a1c57fe5b6002614a278a6150f7565b6040518082805190602001908083835b60208310614a565780518252601f199092019160209182019101614a37565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af1158015614a97573d6000803e3d6000fd5b5050506040513d6020811015614aac57600080fd5b50519350600280614ac08a600060406148f1565b6040518082805190602001908083835b60208310614aef5780518252601f199092019160209182019101614ad0565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af1158015614b30573d6000803e3d6000fd5b5050506040513d6020811015614b4557600080fd5b50516002614b6d614b688c6040614b6360608263ffffffff6135f016565b6148f1565b6150f7565b6040518082805190602001908083835b60208310614b9c5780518252601f199092019160209182019101614b7d565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af1158015614bdd573d6000803e3d6000fd5b5050506040513d6020811015614bf257600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310614c485780518252601f199092019160209182019101614c29565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af1158015614c89573d6000803e3d6000fd5b5050506040513d6020811015614c9e57600080fd5b50516040805160208181018890528183018b905282518083038401815260609092019283905281519396506002938493918291908401908083835b60208310614cf85780518252601f199092019160209182019101614cd9565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af1158015614d39573d6000803e3d6000fd5b5050506040513d6020811015614d4e57600080fd5b50516002614d5b88615187565b60408051602080820193909352808201899052815180820383018152606090910191829052805190928291908401908083835b60208310614dad5780518252601f199092019160209182019101614d8e565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af1158015614dee573d6000803e3d6000fd5b5050506040513d6020811015614e0357600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310614e595780518252601f199092019160209182019101614e3a565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af1158015614e9a573d6000803e3d6000fd5b5050506040513d6020811015614eaf57600080fd5b50519150614ec430318763ffffffff6135f016565b9050614ece6120de565b600160a060020a03166322895118878b8a6040516020018082600019166000191681526020019150506040516020818303038152906040528c876040518663ffffffff1660e01b8152600401808060200180602001806020018560001916600019168152602001848103845288818151815260200191508051906020019080838360005b83811015614f6a578181015183820152602001614f52565b50505050905090810190601f168015614f975780820380516001836020036101000a031916815260200191505b50848103835287518152875160209182019189019080838360005b83811015614fca578181015183820152602001614fb2565b50505050905090810190601f168015614ff75780820380516001836020036101000a031916815260200191505b50848103825286518152865160209182019188019080838360005b8381101561502a578181015183820152602001615012565b50505050905090810190601f1680156150575780820380516001836020036101000a031916815260200191505b509750505050505050506000604051808303818588803b15801561507a57600080fd5b505af115801561508e573d6000803e3d6000fd5b505050503031821490506150ec576040805160e560020a62461bcd02815260206004820152601b60248201527f455850454354494e475f4445504f5349545f544f5f48415050454e0000000000604482015290519081900360640190fd5b505050505050505050565b606080602083511015801561510e57506040835111155b151561511657fe5b82516040141561512857829150611020565b6040805160208082528183019092529080820161040080388339019050509050600060208201528251602014156151635761101d83826151bf565b61101d83615182836000614b63885160406135f090919063ffffffff16565b6151bf565b600081815b60088110156151ad57600892831b60ff831617929190911c9060010161518c565b81156151b557fe5b505060c01b919050565b6060806040519050835180825260208201818101602087015b818310156151f05780518352602092830192016151d8565b50855184518101855292509050808201602086015b8183101561521d578051835260209283019201615205565b509551919091011594909401601f01601f1916604052939250505056004150505f415554485f4641494c454400000000000000000000000000000000006c69646f2e4c69646f2e626561636f6e42616c616e63650000000000000000006c69646f2e5061757361626c652e616374697665466c616700000000000000006c69646f2e4c69646f2e6465706f736974656456616c696461746f7273000000434f4e54524143545f49535f53544f50504544000000000000000000000000006c69646f2e4c69646f2e626561636f6e56616c696461746f7273000000000000a165627a7a72305820e5d1af58d1fe3523853b92051246573e5294059e57fe18edf31c4d03b1f89ffe0029

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.