false
true
0

Contract Address Details

0x7EB3748A86D13f175fdB33eb2a8B07D05aF6B4d9

Contract Name
LegacyOracle
Creator
0x9f3caf–c84a70 at 0xec409d–2f4560
Balance
0 tPLS
Tokens
Fetching tokens...
Transactions
Fetching transactions...
Transfers
Fetching transfers...
Gas Used
Fetching gas used...
Last Balance Update
25353957
Contract is not verified. However, we found a verified contract with the same bytecode in Blockscout DB 0x1ca71ecb7b90514e81cf7f5b3db9047ccfb517ad.
All metadata displayed below is from that contract. In order to verify current contract, click Verify & Publish button
Verify & Publish
Contract name:
LegacyOracle




Optimization enabled
true
Compiler version
v0.4.24+commit.e67f0147




Optimization runs
200
Verified at
2024-10-13T19:49:55.150315Z

contracts/0.4.24/oracle/LegacyOracle.sol

// SPDX-FileCopyrightText: 2023 Lido <info@lido.fi>
// SPDX-License-Identifier: GPL-3.0

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

import "@aragon/os/contracts/apps/AragonApp.sol";

import "../../common/interfaces/ILidoLocator.sol";

import "../utils/Versioned.sol";


interface IAccountingOracle {
    function getConsensusContract() external view returns (address);
}


interface IHashConsensus {
    function getChainConfig() external view returns (
        uint256 slotsPerEpoch,
        uint256 secondsPerSlot,
        uint256 genesisTime
    );

    function getFrameConfig() external view returns (
        uint256 initialEpoch,
        uint256 epochsPerFrame
    );

    function getCurrentFrame() external view returns (
        uint256 refSlot,
        uint256 reportProcessingDeadlineSlot
    );
}


/**
 * @title DEPRECATED legacy oracle contract stub kept for compatibility purposes only.
 * Should not be used in new code.
 *
 * Previously, the oracle contract was located at this address. Currently, the oracle lives
 * at a different address, and this contract is kept for the compatibility, supporting a
 * limited subset of view functions and events.
 *
 * See docs.lido.fi for more info.
 */
contract LegacyOracle is Versioned, AragonApp {

    struct ChainSpec {
        uint64 epochsPerFrame;
        uint64 slotsPerEpoch;
        uint64 secondsPerSlot;
        uint64 genesisTime;
    }

    /// @notice DEPRECATED, kept for compatibility purposes only. The new Rebase event emitted
    /// from the main Lido contract should be used instead.
    ///
    /// This event is still emitted after oracle committee reaches consensus on a report, but
    /// only for compatibility purposes. The values in this event are not enough to calculate
    /// APR or TVL anymore due to withdrawals, execution layer rewards, and consensus layer
    /// rewards skimming.
    event Completed(
        uint256 epochId,
        uint128 beaconBalance,
        uint128 beaconValidators
    );

    /// @notice DEPRECATED, kept for compatibility purposes only. The new Rebase event emitted
    /// from the main Lido contract should be used instead.
    ///
    /// This event is still emitted after each rebase but only for compatibility purposes.
    /// The values in this event are not enough to correctly calculate the rebase APR since
    /// a rebase can result from shares burning without changing total ETH held by the
    /// protocol.
    event PostTotalShares(
        uint256 postTotalPooledEther,
        uint256 preTotalPooledEther,
        uint256 timeElapsed,
        uint256 totalShares
    );

    /// Address of the Lido contract
    bytes32 internal constant LIDO_POSITION =
        0xf6978a4f7e200f6d3a24d82d44c48bddabce399a3b8ec42a480ea8a2d5fe6ec5; // keccak256("lido.LidoOracle.lido")

    /// Address of the new accounting oracle contract
    bytes32 internal constant ACCOUNTING_ORACLE_POSITION =
        0xea0b659bb027a76ad14e51fad85cb5d4cedf3fd9dc4531be67b31d6d8725e9c6; // keccak256("lido.LidoOracle.accountingOracle");

    /// Storage for the Ethereum chain specification
    bytes32 internal constant BEACON_SPEC_POSITION =
        0x805e82d53a51be3dfde7cfed901f1f96f5dad18e874708b082adb8841e8ca909; // keccak256("lido.LidoOracle.beaconSpec")

    /// Version of the initialized contract data (DEPRECATED)
    bytes32 internal constant CONTRACT_VERSION_POSITION_DEPRECATED =
        0x75be19a3f314d89bd1f84d30a6c84e2f1cd7afc7b6ca21876564c265113bb7e4; // keccak256("lido.LidoOracle.contractVersion")

    /// Historic data about 2 last completed reports and their times
    bytes32 internal constant POST_COMPLETED_TOTAL_POOLED_ETHER_POSITION =
        0xaa8433b13d2b111d4f84f6f374bc7acbe20794944308876aa250fa9a73dc7f53; // keccak256("lido.LidoOracle.postCompletedTotalPooledEther")
    bytes32 internal constant PRE_COMPLETED_TOTAL_POOLED_ETHER_POSITION =
        0x1043177539af09a67d747435df3ff1155a64cd93a347daaac9132a591442d43e; // keccak256("lido.LidoOracle.preCompletedTotalPooledEther")
    bytes32 internal constant LAST_COMPLETED_EPOCH_ID_POSITION =
        0xdad15c0beecd15610092d84427258e369d2582df22869138b4c5265f049f574c; // keccak256("lido.LidoOracle.lastCompletedEpochId")
    bytes32 internal constant TIME_ELAPSED_POSITION =
        0x8fe323f4ecd3bf0497252a90142003855cc5125cee76a5b5ba5d508c7ec28c3a; // keccak256("lido.LidoOracle.timeElapsed")

    /**
     * @notice Returns the Lido contract address.
     */
    function getLido() public view returns (address) {
        return LIDO_POSITION.getStorageAddress();
    }

    /**
     * @notice Returns the accounting (new) oracle contract address.
     */
    function getAccountingOracle() public view returns (address) {
        return ACCOUNTING_ORACLE_POSITION.getStorageAddress();
    }

    ///
    /// Compatibility interface (DEPRECATED)
    ///

    /**
     * @notice Returns the initialized version of this contract starting from 0.
     */
    function getVersion() external view returns (uint256) {
        return getContractVersion();
    }

    /**
     * @notice DEPRECATED, kept for compatibility purposes only.
     *
     * Returns the Ethereum chain specification.
     */
    function getBeaconSpec()
        external
        view
        returns (
            uint64 epochsPerFrame,
            uint64 slotsPerEpoch,
            uint64 secondsPerSlot,
            uint64 genesisTime
        )
    {
        (, uint256 epochsPerFrame_) = _getAccountingConsensusContract().getFrameConfig();
        epochsPerFrame = uint64(epochsPerFrame_);

        ChainSpec memory spec = _getChainSpec();
        slotsPerEpoch = spec.slotsPerEpoch;
        secondsPerSlot = spec.secondsPerSlot;
        genesisTime = spec.genesisTime;
    }

    /**
     * @notice DEPRECATED, kept for compatibility purposes only.
     *
     * Returns the epoch calculated from current timestamp
     */
    function getCurrentEpochId() external view returns (uint256) {
        ChainSpec memory spec = _getChainSpec();
        // solhint-disable-line not-rely-on-time
        return (_getTime() - spec.genesisTime) / (spec.slotsPerEpoch * spec.secondsPerSlot);
    }

    /**
     * @notice DEPRECATED, kept for compatibility purposes only.
     *
     * Returns the first epoch of the current reporting frame as well as its start and end
     * times in seconds.
     */
    function getCurrentFrame()
        external
        view
        returns (
            uint256 frameEpochId,
            uint256 frameStartTime,
            uint256 frameEndTime
        )
    {
        return _getCurrentFrameFromAccountingOracle();
    }

    /**
     * @notice DEPRECATED, kept for compatibility purposes only.
     *
     * Returns the starting epoch of the last frame in which an oracle report was received
     * and applied.
     */
    function getLastCompletedEpochId() external view returns (uint256) {
        return LAST_COMPLETED_EPOCH_ID_POSITION.getStorageUint256();
    }

    /**
     * @notice DEPRECATED, kept for compatibility purposes only.
     *
     * The change of the protocol TVL that the last rebase resulted in. Notice that, during
     * a rebase, stETH shares can be minted to distribute protocol fees and burnt to apply
     * cover for losses incurred by slashed or unresponsive validators. A rebase might be
     * triggered without changing the protocol TVL. Thus, it's impossible to correctly
     * calculate APR from the numbers returned by this function.
     *
     * See docs.lido.fi for the correct way of onchain and offchain APR calculation.
     */
    function getLastCompletedReportDelta()
        external
        view
        returns (
            uint256 postTotalPooledEther,
            uint256 preTotalPooledEther,
            uint256 timeElapsed
        )
    {
        postTotalPooledEther = POST_COMPLETED_TOTAL_POOLED_ETHER_POSITION.getStorageUint256();
        preTotalPooledEther = PRE_COMPLETED_TOTAL_POOLED_ETHER_POSITION.getStorageUint256();
        timeElapsed = TIME_ELAPSED_POSITION.getStorageUint256();
    }

    ///
    /// Internal interface & implementation.
    ///

    /**
     * @notice Called by Lido on each rebase.
     */
    function handlePostTokenRebase(
        uint256 /* reportTimestamp */,
        uint256 timeElapsed,
        uint256 /* preTotalShares */,
        uint256 preTotalEther,
        uint256 postTotalShares,
        uint256 postTotalEther,
        uint256 /* totalSharesMintedAsFees */
    )
        external
    {
        require(msg.sender == getLido(), "SENDER_NOT_ALLOWED");

        PRE_COMPLETED_TOTAL_POOLED_ETHER_POSITION.setStorageUint256(preTotalEther);
        POST_COMPLETED_TOTAL_POOLED_ETHER_POSITION.setStorageUint256(postTotalEther);
        TIME_ELAPSED_POSITION.setStorageUint256(timeElapsed);

        emit PostTotalShares(postTotalEther, preTotalEther, timeElapsed, postTotalShares);
    }

    /**
     * @notice Called by the new accounting oracle on each report.
     */
    function handleConsensusLayerReport(uint256 _refSlot, uint256 _clBalance, uint256 _clValidators)
        external
    {
        require(msg.sender == getAccountingOracle(), "SENDER_NOT_ALLOWED");

        // new accounting oracle's ref. slot is the last slot of the epoch preceding the one the frame starts at
        uint256 epochId = (_refSlot + 1) / _getChainSpec().slotsPerEpoch;
        LAST_COMPLETED_EPOCH_ID_POSITION.setStorageUint256(epochId);

        emit Completed(epochId, uint128(_clBalance), uint128(_clValidators));
    }

    /**
     * @notice Initializes the contract (the compat-only deprecated version 4) from scratch.
     * @param _lidoLocator Address of the Lido Locator contract.
     * @param _accountingOracleConsensusContract Address of consensus contract of the new accounting oracle contract.
     */
    function initialize(
        address _lidoLocator,
        address _accountingOracleConsensusContract
    ) external onlyInit {
        // Initializations for v0 --> v3
        _checkContractVersion(0);
        // deprecated version slot must be empty
        require(CONTRACT_VERSION_POSITION_DEPRECATED.getStorageUint256() == 0, "WRONG_BASE_VERSION");
        require(_lidoLocator != address(0), "ZERO_LOCATOR_ADDRESS");
        ILidoLocator locator = ILidoLocator(_lidoLocator);

        LIDO_POSITION.setStorageAddress(locator.lido());

        // Initializations for v3 --> v4
        _initialize_v4(locator.accountingOracle());

        // Cannot get consensus contract from new oracle because at this point new oracle is
        // not initialized with consensus contract address yet
        _setChainSpec(_getAccountingOracleChainSpec(_accountingOracleConsensusContract));

        // Needed to finish the Aragon part of initialization (otherwise auth() modifiers will fail)
        initialized();
    }

    /**
     * @notice A function to finalize upgrade v3 -> v4 (the compat-only deprecated impl).
     * Can be called only once.
     */
    function finalizeUpgrade_v4(address _accountingOracle) external {
        // deprecated version slot must be set to v3
        require(CONTRACT_VERSION_POSITION_DEPRECATED.getStorageUint256() == 3, "WRONG_BASE_VERSION");
        // current version slot must not be initialized yet
        _checkContractVersion(0);

        IHashConsensus consensus = IHashConsensus(IAccountingOracle(_accountingOracle).getConsensusContract());

        _initialize_v4(_accountingOracle);

        ChainSpec memory spec = _getChainSpec();
        ChainSpec memory newSpec = _getAccountingOracleChainSpec(consensus);

        require(
            spec.slotsPerEpoch == newSpec.slotsPerEpoch &&
            spec.secondsPerSlot == newSpec.secondsPerSlot &&
            spec.genesisTime == newSpec.genesisTime,
            "UNEXPECTED_CHAIN_SPEC"
        );
    }

    function _initialize_v4(address _accountingOracle) internal {
        require(_accountingOracle != address(0), "ZERO_ACCOUNTING_ORACLE_ADDRESS");
        ACCOUNTING_ORACLE_POSITION.setStorageAddress(_accountingOracle);
        // write current version slot
        _setContractVersion(4);
        // reset deprecated version slot
        CONTRACT_VERSION_POSITION_DEPRECATED.setStorageUint256(0);
    }

    function _getTime() internal view returns (uint256) {
        return block.timestamp; // solhint-disable-line not-rely-on-time
    }

    function _getChainSpec()
        internal
        view
        returns (ChainSpec memory chainSpec)
    {
        uint256 data = BEACON_SPEC_POSITION.getStorageUint256();
        chainSpec.epochsPerFrame = uint64(data >> 192);
        chainSpec.slotsPerEpoch = uint64(data >> 128);
        chainSpec.secondsPerSlot = uint64(data >> 64);
        chainSpec.genesisTime = uint64(data);
        return chainSpec;
    }

    function _setChainSpec(ChainSpec memory _chainSpec) internal {
        require(_chainSpec.slotsPerEpoch > 0, "BAD_SLOTS_PER_EPOCH");
        require(_chainSpec.secondsPerSlot > 0, "BAD_SECONDS_PER_SLOT");
        require(_chainSpec.genesisTime > 0, "BAD_GENESIS_TIME");
        require(_chainSpec.epochsPerFrame > 0, "BAD_EPOCHS_PER_FRAME");

        uint256 data = (
            uint256(_chainSpec.epochsPerFrame) << 192 |
            uint256(_chainSpec.slotsPerEpoch) << 128 |
            uint256(_chainSpec.secondsPerSlot) << 64 |
            uint256(_chainSpec.genesisTime)
        );

        BEACON_SPEC_POSITION.setStorageUint256(data);
    }

    function _getAccountingOracleChainSpec(address _accountingOracleConsensusContract)
        internal
        view
        returns (ChainSpec memory spec)
    {
        IHashConsensus consensus = IHashConsensus(_accountingOracleConsensusContract);
        (uint256 slotsPerEpoch, uint256 secondsPerSlot, uint256 genesisTime) = consensus.getChainConfig();
        (, uint256 epochsPerFrame_) = consensus.getFrameConfig();

        spec.epochsPerFrame = uint64(epochsPerFrame_);
        spec.slotsPerEpoch = uint64(slotsPerEpoch);
        spec.secondsPerSlot = uint64(secondsPerSlot);
        spec.genesisTime = uint64(genesisTime);
    }

    function _getCurrentFrameFromAccountingOracle()
        internal
        view
        returns (
            uint256 frameEpochId,
            uint256 frameStartTime,
            uint256 frameEndTime
        )
    {
        ChainSpec memory spec = _getChainSpec();
        IHashConsensus consensus = _getAccountingConsensusContract();
        uint256 refSlot;
        (refSlot,) =  consensus.getCurrentFrame();

        // new accounting oracle's ref. slot is the last slot of the epoch preceding the one the frame starts at
        frameStartTime = spec.genesisTime + (refSlot + 1) * spec.secondsPerSlot;
        // new accounting oracle's frame ends at the timestamp of the frame's last slot; old oracle's frame
        // ended a second before the timestamp of the first slot of the next frame
        frameEndTime = frameStartTime + spec.secondsPerSlot * spec.slotsPerEpoch * spec.epochsPerFrame - 1;
        frameEpochId = (refSlot + 1) / spec.slotsPerEpoch;
    }

    function _getAccountingConsensusContract() internal view returns (IHashConsensus) {
        return IHashConsensus(IAccountingOracle(getAccountingOracle()).getConsensusContract());
    }
}
        

@aragon/os/contracts/common/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;
    }
}
          

@aragon/os/contracts/common/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);
    }
}
          

@aragon/os/contracts/kernel/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);
}
          

@aragon/os/contracts/acl/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));
    }
}
          

@aragon/os/contracts/acl/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);
}
          

@aragon/os/contracts/apps/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);
    }
}
          

@aragon/os/contracts/apps/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
    }
}
          

@aragon/os/contracts/common/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();
    }
}
          

@aragon/os/contracts/common/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)
        }
    }
}
          

@aragon/os/contracts/common/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);
}
          

@aragon/os/contracts/common/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);
}
          

@aragon/os/contracts/common/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);
    }
}
          

@aragon/os/contracts/common/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);
    }
}
          

@aragon/os/contracts/common/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;
    }
}
          

@aragon/os/contracts/common/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();
    }
}
          

@aragon/os/contracts/common/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);
    }
}
          

@aragon/os/contracts/common/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) }
    }
}
          

@aragon/os/contracts/common/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);
}
          

@aragon/os/contracts/evmscript/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);
    }
}
          

@aragon/os/contracts/evmscript/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);
}
          

@aragon/os/contracts/evmscript/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);
}
          

@aragon/os/contracts/kernel/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;
}
          

@aragon/os/contracts/lib/token/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
    );
}
          

contracts/0.4.24/utils/Versioned.sol

// SPDX-FileCopyrightText: 2023 Lido <info@lido.fi>
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.4.24;

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

/**
 * @title Adapted code of /contracts/0.8.9/utils/Versioned.sol
 *
 * This contract contains only core part of original Versioned.sol
 * to reduce contract size
 */
contract Versioned {
    using UnstructuredStorage for bytes32;

    event ContractVersionSet(uint256 version);

    /// @dev Storage slot: uint256 version
    /// Version of the initialized contract storage.
    /// The version stored in CONTRACT_VERSION_POSITION equals to:
    /// - 0 right after the deployment, before an initializer is invoked (and only at that moment);
    /// - N after calling initialize(), where N is the initially deployed contract version;
    /// - N after upgrading contract by calling finalizeUpgrade_vN().
    bytes32 internal constant CONTRACT_VERSION_POSITION =
        0x4dd0f6662ba1d6b081f08b350f5e9a6a7b15cf586926ba66f753594928fa64a6; // keccak256("lido.Versioned.contractVersion");

    uint256 internal constant PETRIFIED_VERSION_MARK = uint256(-1);

    constructor() public {
        // lock version in the implementation's storage to prevent initialization
        CONTRACT_VERSION_POSITION.setStorageUint256(PETRIFIED_VERSION_MARK);
    }

    /// @notice Returns the current contract version.
    function getContractVersion() public view returns (uint256) {
        return CONTRACT_VERSION_POSITION.getStorageUint256();
    }

    function _checkContractVersion(uint256 version) internal view {
        require(version == getContractVersion(), "UNEXPECTED_CONTRACT_VERSION");
    }

    function _setContractVersion(uint256 version) internal {
        CONTRACT_VERSION_POSITION.setStorageUint256(version);
        emit ContractVersionSet(version);
    }
}
          

contracts/common/interfaces/ILidoLocator.sol

// SPDX-FileCopyrightText: 2023 Lido <info@lido.fi>
// SPDX-License-Identifier: GPL-3.0

// See contracts/COMPILERS.md
// solhint-disable-next-line
pragma solidity >=0.4.24 <0.9.0;

interface ILidoLocator {
    function accountingOracle() external view returns(address);
    function depositSecurityModule() external view returns(address);
    function elRewardsVault() external view returns(address);
    function legacyOracle() external view returns(address);
    function lido() external view returns(address);
    function oracleReportSanityChecker() external view returns(address);
    function burner() external view returns(address);
    function stakingRouter() external view returns(address);
    function treasury() external view returns(address);
    function validatorsExitBusOracle() external view returns(address);
    function withdrawalQueue() external view returns(address);
    function withdrawalVault() external view returns(address);
    function postTokenRebaseReceiver() external view returns(address);
    function oracleDaemonConfig() external view returns(address);
    function coreComponents() external view returns(
        address elRewardsVault,
        address oracleReportSanityChecker,
        address stakingRouter,
        address treasury,
        address withdrawalQueue,
        address withdrawalVault
    );
    function oracleReportComponentsForLido() external view returns(
        address accountingOracle,
        address elRewardsVault,
        address oracleReportSanityChecker,
        address burner,
        address withdrawalQueue,
        address withdrawalVault,
        address postTokenRebaseReceiver
    );
}
          

Compiler Settings

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

Contract ABI

[{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"hasInitialized","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getVersion","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"getEVMScriptExecutor","inputs":[{"type":"bytes","name":"_script"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"getRecoveryVault","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"initialize","inputs":[{"type":"address","name":"_lidoLocator"},{"type":"address","name":"_accountingOracleConsensusContract"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"finalizeUpgrade_v4","inputs":[{"type":"address","name":"_accountingOracle"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"postTotalPooledEther"},{"type":"uint256","name":"preTotalPooledEther"},{"type":"uint256","name":"timeElapsed"}],"name":"getLastCompletedReportDelta","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"getLido","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"frameEpochId"},{"type":"uint256","name":"frameStartTime"},{"type":"uint256","name":"frameEndTime"}],"name":"getCurrentFrame","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"allowRecoverability","inputs":[{"type":"address","name":"token"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bytes32","name":""}],"name":"appId","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"handlePostTokenRebase","inputs":[{"type":"uint256","name":""},{"type":"uint256","name":"timeElapsed"},{"type":"uint256","name":""},{"type":"uint256","name":"preTotalEther"},{"type":"uint256","name":"postTotalShares"},{"type":"uint256","name":"postTotalEther"},{"type":"uint256","name":""}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getLastCompletedEpochId","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getContractVersion","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getInitializationBlock","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"handleConsensusLayerReport","inputs":[{"type":"uint256","name":"_refSlot"},{"type":"uint256","name":"_clBalance"},{"type":"uint256","name":"_clValidators"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"transferToVault","inputs":[{"type":"address","name":"_token"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"getAccountingOracle","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"canPerform","inputs":[{"type":"address","name":"_sender"},{"type":"bytes32","name":"_role"},{"type":"uint256[]","name":"_params"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getCurrentEpochId","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"getEVMScriptRegistry","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"kernel","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"isPetrified","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint64","name":"epochsPerFrame"},{"type":"uint64","name":"slotsPerEpoch"},{"type":"uint64","name":"secondsPerSlot"},{"type":"uint64","name":"genesisTime"}],"name":"getBeaconSpec","inputs":[],"constant":true},{"type":"event","name":"Completed","inputs":[{"type":"uint256","name":"epochId","indexed":false},{"type":"uint128","name":"beaconBalance","indexed":false},{"type":"uint128","name":"beaconValidators","indexed":false}],"anonymous":false},{"type":"event","name":"PostTotalShares","inputs":[{"type":"uint256","name":"postTotalPooledEther","indexed":false},{"type":"uint256","name":"preTotalPooledEther","indexed":false},{"type":"uint256","name":"timeElapsed","indexed":false},{"type":"uint256","name":"totalShares","indexed":false}],"anonymous":false},{"type":"event","name":"ScriptResult","inputs":[{"type":"address","name":"executor","indexed":true},{"type":"bytes","name":"script","indexed":false},{"type":"bytes","name":"input","indexed":false},{"type":"bytes","name":"returnData","indexed":false}],"anonymous":false},{"type":"event","name":"RecoverToVault","inputs":[{"type":"address","name":"vault","indexed":true},{"type":"address","name":"token","indexed":true},{"type":"uint256","name":"amount","indexed":false}],"anonymous":false},{"type":"event","name":"ContractVersionSet","inputs":[{"type":"uint256","name":"version","indexed":false}],"anonymous":false}]
              

Contract Creation Code

Verify & Publish
0x60806040526200003e7f4dd0f6662ba1d6b081f08b350f5e9a6a7b15cf586926ba66f753594928fa64a660001962000054602090811b6200153317901c565b6200004e6200005860201b60201c565b6200026b565b9055565b620000686200015a60201b60201c565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a454400000000000000006020820152901562000144576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101562000108578181015183820152602001620000ee565b50505050905090810190601f168015620001365780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50620001586000196200018d60201b60201c565b565b6000620001886000805160206200212c83398151915260001b600019166200026760201b6200152f1760201c565b905090565b6200019d6200015a60201b60201c565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a45440000000000000000602082015290156200023c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360008381101562000108578181015183820152602001620000ee565b50620002646000805160206200212c8339815191528262000054602090811b6200153317901c565b50565b5490565b611eb1806200027b6000396000f3006080604052600436106101215760003560e01c63ffffffff1680630803fac0146101265780630d8e6e2c1461014f5780632914b9bd1461017657806332f0a3b5146101eb578063485cc955146102005780634a5d23bb14610229578063534649c41461024a5780636a516b471461027d57806372f79b13146102925780637e7db6e1146102a757806380afdea8146102c857806389136ec0146102dd57806389896aef146103075780638aa104351461031c5780638b3dd7491461033157806391d2247c146103465780639d4941d814610364578063a096704c14610385578063a1658fad1461039a578063a29a839f14610401578063a479e50814610416578063d4aae0c41461042b578063de4796ed14610440578063e547c77c14610455575b600080fd5b34801561013257600080fd5b5061013b61049f565b604080519115158252519081900360200190f35b34801561015b57600080fd5b506101646104c8565b60408051918252519081900360200190f35b34801561018257600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526101cf9436949293602493928401919081908401838280828437509497506104d79650505050505050565b60408051600160a060020a039092168252519081900360200190f35b3480156101f757600080fd5b506101cf6105ba565b34801561020c57600080fd5b50610227600160a060020a036004358116906024351661062f565b005b34801561023557600080fd5b50610227600160a060020a036004351661090a565b34801561025657600080fd5b5061025f610af6565b60408051938452602084019290925282820152519081900360600190f35b34801561028957600080fd5b506101cf610b80565b34801561029e57600080fd5b5061025f610bab565b3480156102b357600080fd5b5061013b600160a060020a0360043516610bc3565b3480156102d457600080fd5b50610164610bc9565b3480156102e957600080fd5b5061022760043560243560443560643560843560a43560c435610bf4565b34801561031357600080fd5b50610164610d3b565b34801561032857600080fd5b50610164610d66565b34801561033d57600080fd5b50610164610d91565b34801561035257600080fd5b50610227600435602435604435610dbc565b34801561037057600080fd5b50610227600160a060020a0360043516610ed3565b34801561039157600080fd5b506101cf611162565b3480156103a657600080fd5b50604080516020600460443581810135838102808601850190965280855261013b958335600160a060020a031695602480359636969560649593949201929182918501908490808284375094975061118d9650505050505050565b34801561040d57600080fd5b506101646112da565b34801561042257600080fd5b506101cf61132b565b34801561043757600080fd5b506101cf6113e0565b34801561044c57600080fd5b5061013b61140b565b34801561046157600080fd5b5061046a61141e565b6040805167ffffffffffffffff9586168152938516602085015291841683830152909216606082015290519081900360800190f35b6000806104aa610d91565b905080158015906104c25750806104bf6114ca565b10155b91505090565b60006104d2610d66565b905090565b60006104e161132b565b600160a060020a03166304bf2a7f836040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561053c578181015183820152602001610524565b50505050905090810190601f1680156105695780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b15801561058857600080fd5b505af115801561059c573d6000803e3d6000fd5b505050506040513d60208110156105b257600080fd5b505192915050565b60006105c46113e0565b600160a060020a03166332f0a3b56040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156105fe57600080fd5b505af1158015610612573d6000803e3d6000fd5b505050506040513d602081101561062857600080fd5b5051905090565b6000610639610d91565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a45440000000000000000602082015290156106fa5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360005b838110156106bf5781810151838201526020016106a7565b50505050905090810190601f1680156106ec5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5061070560006114ce565b61072e7f75be19a3f314d89bd1f84d30a6c84e2f1cd7afc7b6ca21876564c265113bb7e461152f565b15610783576040805160e560020a62461bcd02815260206004820152601260248201527f57524f4e475f424153455f56455253494f4e0000000000000000000000000000604482015290519081900360640190fd5b600160a060020a03831615156107e3576040805160e560020a62461bcd02815260206004820152601460248201527f5a45524f5f4c4f4341544f525f41444452455353000000000000000000000000604482015290519081900360640190fd5b82905061087d81600160a060020a03166323509a2d6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561082457600080fd5b505af1158015610838573d6000803e3d6000fd5b505050506040513d602081101561084e57600080fd5b50517ff6978a4f7e200f6d3a24d82d44c48bddabce399a3b8ec42a480ea8a2d5fe6ec59063ffffffff61153316565b6108ec81600160a060020a0316635a2031f96040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156108bb57600080fd5b505af11580156108cf573d6000803e3d6000fd5b505050506040513d60208110156108e557600080fd5b5051611537565b6108fd6108f883611602565b61173f565b610905611947565b505050565b6000610914611e5e565b61091c611e5e565b6109457f75be19a3f314d89bd1f84d30a6c84e2f1cd7afc7b6ca21876564c265113bb7e461152f565b60031461099c576040805160e560020a62461bcd02815260206004820152601260248201527f57524f4e475f424153455f56455253494f4e0000000000000000000000000000604482015290519081900360640190fd5b6109a660006114ce565b83600160a060020a0316638f55b5716040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156109e157600080fd5b505af11580156109f5573d6000803e3d6000fd5b505050506040513d6020811015610a0b57600080fd5b50519250610a1884611537565b610a20611a0f565b9150610a2b83611602565b9050806020015167ffffffffffffffff16826020015167ffffffffffffffff16148015610a735750806040015167ffffffffffffffff16826040015167ffffffffffffffff16145b8015610a9a5750806060015167ffffffffffffffff16826060015167ffffffffffffffff16145b1515610af0576040805160e560020a62461bcd02815260206004820152601560248201527f554e45585045435445445f434841494e5f535045430000000000000000000000604482015290519081900360640190fd5b50505050565b60008080610b237faa8433b13d2b111d4f84f6f374bc7acbe20794944308876aa250fa9a73dc7f5361152f565b9250610b4e7f1043177539af09a67d747435df3ff1155a64cd93a347daaac9132a591442d43e61152f565b9150610b797f8fe323f4ecd3bf0497252a90142003855cc5125cee76a5b5ba5d508c7ec28c3a61152f565b9050909192565b60006104d27ff6978a4f7e200f6d3a24d82d44c48bddabce399a3b8ec42a480ea8a2d5fe6ec561152f565b6000806000610bb8611a75565b925092509250909192565b50600190565b60006104d27fd625496217aa6a3453eecb9c3489dc5a53e6c67b444329ea2b2cbc9ff547639b61152f565b610bfc610b80565b600160a060020a03163314610c5b576040805160e560020a62461bcd02815260206004820152601260248201527f53454e4445525f4e4f545f414c4c4f5745440000000000000000000000000000604482015290519081900360640190fd5b610c8b7f1043177539af09a67d747435df3ff1155a64cd93a347daaac9132a591442d43e8563ffffffff61153316565b610cbb7faa8433b13d2b111d4f84f6f374bc7acbe20794944308876aa250fa9a73dc7f538363ffffffff61153316565b610ceb7f8fe323f4ecd3bf0497252a90142003855cc5125cee76a5b5ba5d508c7ec28c3a8763ffffffff61153316565b60408051838152602081018690528082018890526060810185905290517fdafd48d1eba2a416b2aca45e9ead3ad18b84e868fa6d2e1a3048bfd37ed10a329181900360800190a150505050505050565b60006104d27fdad15c0beecd15610092d84427258e369d2582df22869138b4c5265f049f574c61152f565b60006104d27f4dd0f6662ba1d6b081f08b350f5e9a6a7b15cf586926ba66f753594928fa64a661152f565b60006104d27febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e61152f565b6000610dc6611162565b600160a060020a03163314610e25576040805160e560020a62461bcd02815260206004820152601260248201527f53454e4445525f4e4f545f414c4c4f5745440000000000000000000000000000604482015290519081900360640190fd5b610e2d611a0f565b6020015167ffffffffffffffff1684600101811515610e4857fe5b049050610e7b7fdad15c0beecd15610092d84427258e369d2582df22869138b4c5265f049f574c8263ffffffff61153316565b604080518281526fffffffffffffffffffffffffffffffff808616602083015284168183015290517f95423529aa0b2867e02676b0bb4766cde576fb31ea77056f683bc236c7c15f9d9181900360600190a150505050565b6000806000610ee184610bc3565b60408051808201909152601281527f5245434f5645525f444953414c4c4f57454400000000000000000000000000006020820152901515610f675760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156106bf5781810151838201526020016106a7565b50610f706105ba565b9250610f7b83611b5a565b60408051808201909152601a81527f5245434f5645525f5641554c545f4e4f545f434f4e545241435400000000000060208201529015156110015760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156106bf5781810151838201526020016106a7565b50600160a060020a03841615156110525760405130319250600160a060020a0384169083156108fc029084906000818181858888f1935050505015801561104c573d6000803e3d6000fd5b50611111565b508261106d600160a060020a0382163063ffffffff611b8716565b9150611089600160a060020a038216848463ffffffff611c9c16565b60408051808201909152601d81527f5245434f5645525f544f4b454e5f5452414e534645525f4641494c4544000000602082015290151561110f5760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156106bf5781810151838201526020016106a7565b505b83600160a060020a031683600160a060020a03167f596caf56044b55fb8c4ca640089bbc2b63cae3e978b851f5745cbb7c5b288e02846040518082815260200191505060405180910390a350505050565b60006104d27fea0b659bb027a76ad14e51fad85cb5d4cedf3fd9dc4531be67b31d6d8725e9c661152f565b60008061119861049f565b15156111a757600091506112d2565b6111af6113e0565b9050600160a060020a03811615156111ca57600091506112d2565b80600160a060020a031663fdef91068630876111e588611d27565b60405163ffffffff861660e01b8152600160a060020a03808616600483019081529085166024830152604482018490526080606483019081528351608484015283519192909160a490910190602085019080838360005b8381101561125457818101518382015260200161123c565b50505050905090810190601f1680156112815780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b1580156112a357600080fd5b505af11580156112b7573d6000803e3d6000fd5b505050506040513d60208110156112cd57600080fd5b505191505b509392505050565b60006112e4611e5e565b6112ec611a0f565b9050806040015181602001510267ffffffffffffffff16816060015167ffffffffffffffff1661131a611d31565b0381151561132457fe5b0491505090565b6000806113366113e0565b604080517fbe00bbd80000000000000000000000000000000000000000000000000000000081527fd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb60048201527fddbcfd564f642ab5627cf68b9b7d374fb4f8a36e941a75d89c87998cef03bd6160248201529051600160a060020a03929092169163be00bbd8916044808201926020929091908290030181600087803b15801561058857600080fd5b60006104d27f4172f0f7d2289153072b0a6ca36959e0cbe2efc3afe50fc81636caa96338137b61152f565b6000600019611418610d91565b14905090565b600080600080600061142e611e5e565b611436611d35565b600160a060020a0316636fb1bf666040518163ffffffff1660e01b81526004016040805180830381600087803b15801561146f57600080fd5b505af1158015611483573d6000803e3d6000fd5b505050506040513d604081101561149957600080fd5b506020015195508591506114ab611a0f565b9050806020015194508060400151935080606001519250505090919293565b4390565b6114d6610d66565b811461152c576040805160e560020a62461bcd02815260206004820152601b60248201527f554e45585045435445445f434f4e54524143545f56455253494f4e0000000000604482015290519081900360640190fd5b50565b5490565b9055565b600160a060020a0381161515611597576040805160e560020a62461bcd02815260206004820152601e60248201527f5a45524f5f4143434f554e54494e475f4f5241434c455f414444524553530000604482015290519081900360640190fd5b6115c77fea0b659bb027a76ad14e51fad85cb5d4cedf3fd9dc4531be67b31d6d8725e9c68263ffffffff61153316565b6115d16004611d79565b61152c7f75be19a3f314d89bd1f84d30a6c84e2f1cd7afc7b6ca21876564c265113bb7e4600063ffffffff61153316565b61160a611e5e565b600080600080600086945084600160a060020a031663606c0c946040518163ffffffff1660e01b8152600401606060405180830381600087803b15801561165057600080fd5b505af1158015611664573d6000803e3d6000fd5b505050506040513d606081101561167a57600080fd5b508051602082015160409283015183517f6fb1bf6600000000000000000000000000000000000000000000000000000000815284519398509196509450600160a060020a03881692636fb1bf66926004808401938290030181600087803b1580156116e457600080fd5b505af11580156116f8573d6000803e3d6000fd5b505050506040513d604081101561170e57600080fd5b5060209081015167ffffffffffffffff90811688529485169087015250908216604085015216606083015250919050565b600080826020015167ffffffffffffffff161115156117a8576040805160e560020a62461bcd02815260206004820152601360248201527f4241445f534c4f54535f5045525f45504f434800000000000000000000000000604482015290519081900360640190fd5b6000826040015167ffffffffffffffff16111515611810576040805160e560020a62461bcd02815260206004820152601460248201527f4241445f5345434f4e44535f5045525f534c4f54000000000000000000000000604482015290519081900360640190fd5b6000826060015167ffffffffffffffff16111515611878576040805160e560020a62461bcd02815260206004820152601060248201527f4241445f47454e455349535f54494d4500000000000000000000000000000000604482015290519081900360640190fd5b8151600067ffffffffffffffff909116116118dd576040805160e560020a62461bcd02815260206004820152601460248201527f4241445f45504f4348535f5045525f4652414d45000000000000000000000000604482015290519081900360640190fd5b5060608101516040808301516020840151845167ffffffffffffffff90811660c01b91811660801b9190911791811690921b179116176119437f805e82d53a51be3dfde7cfed901f1f96f5dad18e874708b082adb8841e8ca9098263ffffffff61153316565b5050565b61194f610d91565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a45440000000000000000602082015290156119d45760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156106bf5781810151838201526020016106a7565b50611a0d6119e06114ca565b7febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e9063ffffffff61153316565b565b611a17611e5e565b6000611a427f805e82d53a51be3dfde7cfed901f1f96f5dad18e874708b082adb8841e8ca90961152f565b67ffffffffffffffff60c082901c81168452608082901c81166020850152604082811c8216908501521660608301525090565b6000806000611a82611e5e565b600080611a8d611a0f565b9250611a97611d35565b915081600160a060020a03166372f79b136040518163ffffffff1660e01b81526004016040805180830381600087803b158015611ad357600080fd5b505af1158015611ae7573d6000803e3d6000fd5b505050506040513d6040811015611afd57600080fd5b5051604084015160608501518551602087015167ffffffffffffffff80851660018701908102948216949094019a5093810290910283168901600019019750929350911690811515611b4b57fe5b049550505050909192565b9055565b600080600160a060020a0383161515611b765760009150611b81565b823b90506000811191505b50919050565b60408051600160a060020a0383166024808301919091528251808303909101815260449091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a08231000000000000000000000000000000000000000000000000000000001790526000908180611c078684611ddf565b60408051808201909152601c81527f534146455f4552435f32305f42414c414e43455f52455645525445440000000060208201529193509150821515611c925760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156106bf5781810151838201526020016106a7565b5095945050505050565b60408051600160a060020a038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052600090611d1e8582611e10565b95945050505050565b8051602002815290565b4290565b6000611d3f611162565b600160a060020a0316638f55b5716040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156105fe57600080fd5b611da97f4dd0f6662ba1d6b081f08b350f5e9a6a7b15cf586926ba66f753594928fa64a68263ffffffff61153316565b6040805182815290517ffddcded6b4f4730c226821172046b48372d3cd963c159701ae1b7c3bcac541bb9181900360200190a150565b6000806000806040516020818751602089018a5afa92506000831115611e0457805191505b50909590945092505050565b6000806040516020818551602087016000895af16000811115611e54573d8015611e415760208114611e4a57611e52565b60019350611e52565b600183511493505b505b5090949350505050565b604080516080810182526000808252602082018190529181018290526060810191909152905600a165627a7a72305820a04d72a99617c7d199e565aec644c292a2f1a258a32742e5ae55b110bc8149fa0029ebb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e

Deployed ByteCode

0x6080604052600436106101215760003560e01c63ffffffff1680630803fac0146101265780630d8e6e2c1461014f5780632914b9bd1461017657806332f0a3b5146101eb578063485cc955146102005780634a5d23bb14610229578063534649c41461024a5780636a516b471461027d57806372f79b13146102925780637e7db6e1146102a757806380afdea8146102c857806389136ec0146102dd57806389896aef146103075780638aa104351461031c5780638b3dd7491461033157806391d2247c146103465780639d4941d814610364578063a096704c14610385578063a1658fad1461039a578063a29a839f14610401578063a479e50814610416578063d4aae0c41461042b578063de4796ed14610440578063e547c77c14610455575b600080fd5b34801561013257600080fd5b5061013b61049f565b604080519115158252519081900360200190f35b34801561015b57600080fd5b506101646104c8565b60408051918252519081900360200190f35b34801561018257600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526101cf9436949293602493928401919081908401838280828437509497506104d79650505050505050565b60408051600160a060020a039092168252519081900360200190f35b3480156101f757600080fd5b506101cf6105ba565b34801561020c57600080fd5b50610227600160a060020a036004358116906024351661062f565b005b34801561023557600080fd5b50610227600160a060020a036004351661090a565b34801561025657600080fd5b5061025f610af6565b60408051938452602084019290925282820152519081900360600190f35b34801561028957600080fd5b506101cf610b80565b34801561029e57600080fd5b5061025f610bab565b3480156102b357600080fd5b5061013b600160a060020a0360043516610bc3565b3480156102d457600080fd5b50610164610bc9565b3480156102e957600080fd5b5061022760043560243560443560643560843560a43560c435610bf4565b34801561031357600080fd5b50610164610d3b565b34801561032857600080fd5b50610164610d66565b34801561033d57600080fd5b50610164610d91565b34801561035257600080fd5b50610227600435602435604435610dbc565b34801561037057600080fd5b50610227600160a060020a0360043516610ed3565b34801561039157600080fd5b506101cf611162565b3480156103a657600080fd5b50604080516020600460443581810135838102808601850190965280855261013b958335600160a060020a031695602480359636969560649593949201929182918501908490808284375094975061118d9650505050505050565b34801561040d57600080fd5b506101646112da565b34801561042257600080fd5b506101cf61132b565b34801561043757600080fd5b506101cf6113e0565b34801561044c57600080fd5b5061013b61140b565b34801561046157600080fd5b5061046a61141e565b6040805167ffffffffffffffff9586168152938516602085015291841683830152909216606082015290519081900360800190f35b6000806104aa610d91565b905080158015906104c25750806104bf6114ca565b10155b91505090565b60006104d2610d66565b905090565b60006104e161132b565b600160a060020a03166304bf2a7f836040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561053c578181015183820152602001610524565b50505050905090810190601f1680156105695780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b15801561058857600080fd5b505af115801561059c573d6000803e3d6000fd5b505050506040513d60208110156105b257600080fd5b505192915050565b60006105c46113e0565b600160a060020a03166332f0a3b56040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156105fe57600080fd5b505af1158015610612573d6000803e3d6000fd5b505050506040513d602081101561062857600080fd5b5051905090565b6000610639610d91565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a45440000000000000000602082015290156106fa5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360005b838110156106bf5781810151838201526020016106a7565b50505050905090810190601f1680156106ec5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5061070560006114ce565b61072e7f75be19a3f314d89bd1f84d30a6c84e2f1cd7afc7b6ca21876564c265113bb7e461152f565b15610783576040805160e560020a62461bcd02815260206004820152601260248201527f57524f4e475f424153455f56455253494f4e0000000000000000000000000000604482015290519081900360640190fd5b600160a060020a03831615156107e3576040805160e560020a62461bcd02815260206004820152601460248201527f5a45524f5f4c4f4341544f525f41444452455353000000000000000000000000604482015290519081900360640190fd5b82905061087d81600160a060020a03166323509a2d6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561082457600080fd5b505af1158015610838573d6000803e3d6000fd5b505050506040513d602081101561084e57600080fd5b50517ff6978a4f7e200f6d3a24d82d44c48bddabce399a3b8ec42a480ea8a2d5fe6ec59063ffffffff61153316565b6108ec81600160a060020a0316635a2031f96040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156108bb57600080fd5b505af11580156108cf573d6000803e3d6000fd5b505050506040513d60208110156108e557600080fd5b5051611537565b6108fd6108f883611602565b61173f565b610905611947565b505050565b6000610914611e5e565b61091c611e5e565b6109457f75be19a3f314d89bd1f84d30a6c84e2f1cd7afc7b6ca21876564c265113bb7e461152f565b60031461099c576040805160e560020a62461bcd02815260206004820152601260248201527f57524f4e475f424153455f56455253494f4e0000000000000000000000000000604482015290519081900360640190fd5b6109a660006114ce565b83600160a060020a0316638f55b5716040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156109e157600080fd5b505af11580156109f5573d6000803e3d6000fd5b505050506040513d6020811015610a0b57600080fd5b50519250610a1884611537565b610a20611a0f565b9150610a2b83611602565b9050806020015167ffffffffffffffff16826020015167ffffffffffffffff16148015610a735750806040015167ffffffffffffffff16826040015167ffffffffffffffff16145b8015610a9a5750806060015167ffffffffffffffff16826060015167ffffffffffffffff16145b1515610af0576040805160e560020a62461bcd02815260206004820152601560248201527f554e45585045435445445f434841494e5f535045430000000000000000000000604482015290519081900360640190fd5b50505050565b60008080610b237faa8433b13d2b111d4f84f6f374bc7acbe20794944308876aa250fa9a73dc7f5361152f565b9250610b4e7f1043177539af09a67d747435df3ff1155a64cd93a347daaac9132a591442d43e61152f565b9150610b797f8fe323f4ecd3bf0497252a90142003855cc5125cee76a5b5ba5d508c7ec28c3a61152f565b9050909192565b60006104d27ff6978a4f7e200f6d3a24d82d44c48bddabce399a3b8ec42a480ea8a2d5fe6ec561152f565b6000806000610bb8611a75565b925092509250909192565b50600190565b60006104d27fd625496217aa6a3453eecb9c3489dc5a53e6c67b444329ea2b2cbc9ff547639b61152f565b610bfc610b80565b600160a060020a03163314610c5b576040805160e560020a62461bcd02815260206004820152601260248201527f53454e4445525f4e4f545f414c4c4f5745440000000000000000000000000000604482015290519081900360640190fd5b610c8b7f1043177539af09a67d747435df3ff1155a64cd93a347daaac9132a591442d43e8563ffffffff61153316565b610cbb7faa8433b13d2b111d4f84f6f374bc7acbe20794944308876aa250fa9a73dc7f538363ffffffff61153316565b610ceb7f8fe323f4ecd3bf0497252a90142003855cc5125cee76a5b5ba5d508c7ec28c3a8763ffffffff61153316565b60408051838152602081018690528082018890526060810185905290517fdafd48d1eba2a416b2aca45e9ead3ad18b84e868fa6d2e1a3048bfd37ed10a329181900360800190a150505050505050565b60006104d27fdad15c0beecd15610092d84427258e369d2582df22869138b4c5265f049f574c61152f565b60006104d27f4dd0f6662ba1d6b081f08b350f5e9a6a7b15cf586926ba66f753594928fa64a661152f565b60006104d27febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e61152f565b6000610dc6611162565b600160a060020a03163314610e25576040805160e560020a62461bcd02815260206004820152601260248201527f53454e4445525f4e4f545f414c4c4f5745440000000000000000000000000000604482015290519081900360640190fd5b610e2d611a0f565b6020015167ffffffffffffffff1684600101811515610e4857fe5b049050610e7b7fdad15c0beecd15610092d84427258e369d2582df22869138b4c5265f049f574c8263ffffffff61153316565b604080518281526fffffffffffffffffffffffffffffffff808616602083015284168183015290517f95423529aa0b2867e02676b0bb4766cde576fb31ea77056f683bc236c7c15f9d9181900360600190a150505050565b6000806000610ee184610bc3565b60408051808201909152601281527f5245434f5645525f444953414c4c4f57454400000000000000000000000000006020820152901515610f675760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156106bf5781810151838201526020016106a7565b50610f706105ba565b9250610f7b83611b5a565b60408051808201909152601a81527f5245434f5645525f5641554c545f4e4f545f434f4e545241435400000000000060208201529015156110015760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156106bf5781810151838201526020016106a7565b50600160a060020a03841615156110525760405130319250600160a060020a0384169083156108fc029084906000818181858888f1935050505015801561104c573d6000803e3d6000fd5b50611111565b508261106d600160a060020a0382163063ffffffff611b8716565b9150611089600160a060020a038216848463ffffffff611c9c16565b60408051808201909152601d81527f5245434f5645525f544f4b454e5f5452414e534645525f4641494c4544000000602082015290151561110f5760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156106bf5781810151838201526020016106a7565b505b83600160a060020a031683600160a060020a03167f596caf56044b55fb8c4ca640089bbc2b63cae3e978b851f5745cbb7c5b288e02846040518082815260200191505060405180910390a350505050565b60006104d27fea0b659bb027a76ad14e51fad85cb5d4cedf3fd9dc4531be67b31d6d8725e9c661152f565b60008061119861049f565b15156111a757600091506112d2565b6111af6113e0565b9050600160a060020a03811615156111ca57600091506112d2565b80600160a060020a031663fdef91068630876111e588611d27565b60405163ffffffff861660e01b8152600160a060020a03808616600483019081529085166024830152604482018490526080606483019081528351608484015283519192909160a490910190602085019080838360005b8381101561125457818101518382015260200161123c565b50505050905090810190601f1680156112815780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b1580156112a357600080fd5b505af11580156112b7573d6000803e3d6000fd5b505050506040513d60208110156112cd57600080fd5b505191505b509392505050565b60006112e4611e5e565b6112ec611a0f565b9050806040015181602001510267ffffffffffffffff16816060015167ffffffffffffffff1661131a611d31565b0381151561132457fe5b0491505090565b6000806113366113e0565b604080517fbe00bbd80000000000000000000000000000000000000000000000000000000081527fd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb60048201527fddbcfd564f642ab5627cf68b9b7d374fb4f8a36e941a75d89c87998cef03bd6160248201529051600160a060020a03929092169163be00bbd8916044808201926020929091908290030181600087803b15801561058857600080fd5b60006104d27f4172f0f7d2289153072b0a6ca36959e0cbe2efc3afe50fc81636caa96338137b61152f565b6000600019611418610d91565b14905090565b600080600080600061142e611e5e565b611436611d35565b600160a060020a0316636fb1bf666040518163ffffffff1660e01b81526004016040805180830381600087803b15801561146f57600080fd5b505af1158015611483573d6000803e3d6000fd5b505050506040513d604081101561149957600080fd5b506020015195508591506114ab611a0f565b9050806020015194508060400151935080606001519250505090919293565b4390565b6114d6610d66565b811461152c576040805160e560020a62461bcd02815260206004820152601b60248201527f554e45585045435445445f434f4e54524143545f56455253494f4e0000000000604482015290519081900360640190fd5b50565b5490565b9055565b600160a060020a0381161515611597576040805160e560020a62461bcd02815260206004820152601e60248201527f5a45524f5f4143434f554e54494e475f4f5241434c455f414444524553530000604482015290519081900360640190fd5b6115c77fea0b659bb027a76ad14e51fad85cb5d4cedf3fd9dc4531be67b31d6d8725e9c68263ffffffff61153316565b6115d16004611d79565b61152c7f75be19a3f314d89bd1f84d30a6c84e2f1cd7afc7b6ca21876564c265113bb7e4600063ffffffff61153316565b61160a611e5e565b600080600080600086945084600160a060020a031663606c0c946040518163ffffffff1660e01b8152600401606060405180830381600087803b15801561165057600080fd5b505af1158015611664573d6000803e3d6000fd5b505050506040513d606081101561167a57600080fd5b508051602082015160409283015183517f6fb1bf6600000000000000000000000000000000000000000000000000000000815284519398509196509450600160a060020a03881692636fb1bf66926004808401938290030181600087803b1580156116e457600080fd5b505af11580156116f8573d6000803e3d6000fd5b505050506040513d604081101561170e57600080fd5b5060209081015167ffffffffffffffff90811688529485169087015250908216604085015216606083015250919050565b600080826020015167ffffffffffffffff161115156117a8576040805160e560020a62461bcd02815260206004820152601360248201527f4241445f534c4f54535f5045525f45504f434800000000000000000000000000604482015290519081900360640190fd5b6000826040015167ffffffffffffffff16111515611810576040805160e560020a62461bcd02815260206004820152601460248201527f4241445f5345434f4e44535f5045525f534c4f54000000000000000000000000604482015290519081900360640190fd5b6000826060015167ffffffffffffffff16111515611878576040805160e560020a62461bcd02815260206004820152601060248201527f4241445f47454e455349535f54494d4500000000000000000000000000000000604482015290519081900360640190fd5b8151600067ffffffffffffffff909116116118dd576040805160e560020a62461bcd02815260206004820152601460248201527f4241445f45504f4348535f5045525f4652414d45000000000000000000000000604482015290519081900360640190fd5b5060608101516040808301516020840151845167ffffffffffffffff90811660c01b91811660801b9190911791811690921b179116176119437f805e82d53a51be3dfde7cfed901f1f96f5dad18e874708b082adb8841e8ca9098263ffffffff61153316565b5050565b61194f610d91565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a45440000000000000000602082015290156119d45760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156106bf5781810151838201526020016106a7565b50611a0d6119e06114ca565b7febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e9063ffffffff61153316565b565b611a17611e5e565b6000611a427f805e82d53a51be3dfde7cfed901f1f96f5dad18e874708b082adb8841e8ca90961152f565b67ffffffffffffffff60c082901c81168452608082901c81166020850152604082811c8216908501521660608301525090565b6000806000611a82611e5e565b600080611a8d611a0f565b9250611a97611d35565b915081600160a060020a03166372f79b136040518163ffffffff1660e01b81526004016040805180830381600087803b158015611ad357600080fd5b505af1158015611ae7573d6000803e3d6000fd5b505050506040513d6040811015611afd57600080fd5b5051604084015160608501518551602087015167ffffffffffffffff80851660018701908102948216949094019a5093810290910283168901600019019750929350911690811515611b4b57fe5b049550505050909192565b9055565b600080600160a060020a0383161515611b765760009150611b81565b823b90506000811191505b50919050565b60408051600160a060020a0383166024808301919091528251808303909101815260449091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a08231000000000000000000000000000000000000000000000000000000001790526000908180611c078684611ddf565b60408051808201909152601c81527f534146455f4552435f32305f42414c414e43455f52455645525445440000000060208201529193509150821515611c925760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156106bf5781810151838201526020016106a7565b5095945050505050565b60408051600160a060020a038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052600090611d1e8582611e10565b95945050505050565b8051602002815290565b4290565b6000611d3f611162565b600160a060020a0316638f55b5716040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156105fe57600080fd5b611da97f4dd0f6662ba1d6b081f08b350f5e9a6a7b15cf586926ba66f753594928fa64a68263ffffffff61153316565b6040805182815290517ffddcded6b4f4730c226821172046b48372d3cd963c159701ae1b7c3bcac541bb9181900360200190a150565b6000806000806040516020818751602089018a5afa92506000831115611e0457805191505b50909590945092505050565b6000806040516020818551602087016000895af16000811115611e54573d8015611e415760208114611e4a57611e52565b60019350611e52565b600183511493505b505b5090949350505050565b604080516080810182526000808252602082018190529181018290526060810191909152905600a165627a7a72305820a04d72a99617c7d199e565aec644c292a2f1a258a32742e5ae55b110bc8149fa0029