false
true
0

Contract Address Details

0x38f7635C2583588e7a37aa67e95E543ffFc49BF9

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




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




Optimization runs
200
Verified at
2024-10-13T19:53:31.903069Z

@aragon/apps-lido/apps/voting/contracts/Voting.sol

/*
 * SPDX-License-Identitifer:    GPL-3.0-or-later
 */

pragma solidity 0.4.24;

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

import "@aragon/os/contracts/lib/math/SafeMath.sol";
import "@aragon/os/contracts/lib/math/SafeMath64.sol";

import "@aragon/minime/contracts/MiniMeToken.sol";


contract Voting is IForwarder, AragonApp {
    using SafeMath for uint256;
    using SafeMath64 for uint64;

    bytes32 public constant CREATE_VOTES_ROLE = keccak256("CREATE_VOTES_ROLE");
    bytes32 public constant MODIFY_SUPPORT_ROLE = keccak256("MODIFY_SUPPORT_ROLE");
    bytes32 public constant MODIFY_QUORUM_ROLE = keccak256("MODIFY_QUORUM_ROLE");
    bytes32 public constant UNSAFELY_MODIFY_VOTE_TIME_ROLE = keccak256("UNSAFELY_MODIFY_VOTE_TIME_ROLE");

    uint64 public constant PCT_BASE = 10 ** 18; // 0% = 0; 1% = 10^16; 100% = 10^18

    string private constant ERROR_NO_VOTE = "VOTING_NO_VOTE";
    string private constant ERROR_INIT_PCTS = "VOTING_INIT_PCTS";
    string private constant ERROR_CHANGE_SUPPORT_PCTS = "VOTING_CHANGE_SUPPORT_PCTS";
    string private constant ERROR_CHANGE_QUORUM_PCTS = "VOTING_CHANGE_QUORUM_PCTS";
    string private constant ERROR_INIT_SUPPORT_TOO_BIG = "VOTING_INIT_SUPPORT_TOO_BIG";
    string private constant ERROR_CHANGE_SUPPORT_TOO_BIG = "VOTING_CHANGE_SUPP_TOO_BIG";
    string private constant ERROR_CAN_NOT_VOTE = "VOTING_CAN_NOT_VOTE";
    string private constant ERROR_CAN_NOT_EXECUTE = "VOTING_CAN_NOT_EXECUTE";
    string private constant ERROR_CAN_NOT_FORWARD = "VOTING_CAN_NOT_FORWARD";
    string private constant ERROR_NO_VOTING_POWER = "VOTING_NO_VOTING_POWER";
    string private constant ERROR_CHANGE_VOTE_TIME = "VOTING_VOTE_TIME_TOO_SMALL";
    string private constant ERROR_CHANGE_OBJECTION_TIME = "VOTING_OBJ_TIME_TOO_BIG";
    string private constant ERROR_INIT_OBJ_TIME_TOO_BIG = "VOTING_INIT_OBJ_TIME_TOO_BIG";

    enum VoterState { Absent, Yea, Nay }

    enum VotePhase { Main, Objection, Closed }

    struct Vote {
        bool executed;
        uint64 startDate;
        uint64 snapshotBlock;
        uint64 supportRequiredPct;
        uint64 minAcceptQuorumPct;
        uint256 yea;
        uint256 nay;
        uint256 votingPower;
        bytes executionScript;
        mapping (address => VoterState) voters;
    }

    MiniMeToken public token;
    uint64 public supportRequiredPct;
    uint64 public minAcceptQuorumPct;
    uint64 public voteTime;

    // We are mimicing an array, we use a mapping instead to make app upgrade more graceful
    mapping (uint256 => Vote) internal votes;
    uint256 public votesLength;
    uint64 public objectionPhaseTime;

    event StartVote(uint256 indexed voteId, address indexed creator, string metadata);
    event CastVote(uint256 indexed voteId, address indexed voter, bool supports, uint256 stake);
    event CastObjection(uint256 indexed voteId, address indexed voter, uint256 stake);
    event ExecuteVote(uint256 indexed voteId);
    event ChangeSupportRequired(uint64 supportRequiredPct);
    event ChangeMinQuorum(uint64 minAcceptQuorumPct);
    event ChangeVoteTime(uint64 voteTime);
    event ChangeObjectionPhaseTime(uint64 objectionPhaseTime);

    modifier voteExists(uint256 _voteId) {
        require(_voteId < votesLength, ERROR_NO_VOTE);
        _;
    }

    /**
    * @notice Initialize Voting app with `_token.symbol(): string` for governance, minimum support of `@formatPct(_supportRequiredPct)`%, minimum acceptance quorum of `@formatPct(_minAcceptQuorumPct)`%, and a voting duration of `@transformTime(_voteTime)`
    * @param _token MiniMeToken Address that will be used as governance token
    * @param _supportRequiredPct Percentage of yeas in casted votes for a vote to succeed (expressed as a percentage of 10^18; eg. 10^16 = 1%, 10^18 = 100%)
    * @param _minAcceptQuorumPct Percentage of yeas in total possible votes for a vote to succeed (expressed as a percentage of 10^18; eg. 10^16 = 1%, 10^18 = 100%)
    * @param _voteTime Total duration of voting in seconds.
    * @param _objectionPhaseTime The duration of the objection vote phase, i.e. seconds that a vote will be open after the main vote phase ends for token holders to object to the outcome. Main phase duration is calculated as `voteTime - objectionPhaseTime`.
    */
    function initialize(MiniMeToken _token, uint64 _supportRequiredPct, uint64 _minAcceptQuorumPct, uint64 _voteTime, uint64 _objectionPhaseTime)
        external
        onlyInit
    {
        initialized();

        require(_minAcceptQuorumPct <= _supportRequiredPct, ERROR_INIT_PCTS);
        require(_supportRequiredPct < PCT_BASE, ERROR_INIT_SUPPORT_TOO_BIG);
        require(_voteTime > _objectionPhaseTime, ERROR_INIT_OBJ_TIME_TOO_BIG);

        token = _token;
        supportRequiredPct = _supportRequiredPct;
        minAcceptQuorumPct = _minAcceptQuorumPct;
        voteTime = _voteTime;
        objectionPhaseTime = _objectionPhaseTime;
    }

    /**
    * @notice Change required support to `@formatPct(_supportRequiredPct)`%
    * @param _supportRequiredPct New required support
    */
    function changeSupportRequiredPct(uint64 _supportRequiredPct)
        external
        authP(MODIFY_SUPPORT_ROLE, arr(uint256(_supportRequiredPct), uint256(supportRequiredPct)))
    {
        require(minAcceptQuorumPct <= _supportRequiredPct, ERROR_CHANGE_SUPPORT_PCTS);
        require(_supportRequiredPct < PCT_BASE, ERROR_CHANGE_SUPPORT_TOO_BIG);
        supportRequiredPct = _supportRequiredPct;

        emit ChangeSupportRequired(_supportRequiredPct);
    }

    /**
    * @notice Change minimum acceptance quorum to `@formatPct(_minAcceptQuorumPct)`%
    * @param _minAcceptQuorumPct New acceptance quorum
    */
    function changeMinAcceptQuorumPct(uint64 _minAcceptQuorumPct)
        external
        authP(MODIFY_QUORUM_ROLE, arr(uint256(_minAcceptQuorumPct), uint256(minAcceptQuorumPct)))
    {
        require(_minAcceptQuorumPct <= supportRequiredPct, ERROR_CHANGE_QUORUM_PCTS);
        minAcceptQuorumPct = _minAcceptQuorumPct;

        emit ChangeMinQuorum(_minAcceptQuorumPct);
    }

    /**
    * @notice Change vote time to `_voteTime` sec. The change affects all existing unexecuted votes, so be really careful with it
    * @param _voteTime New vote time
    */
    function unsafelyChangeVoteTime(uint64 _voteTime)
        external
        auth(UNSAFELY_MODIFY_VOTE_TIME_ROLE)
    {
        require(_voteTime > objectionPhaseTime, ERROR_CHANGE_VOTE_TIME);
        voteTime = _voteTime;

        emit ChangeVoteTime(_voteTime);
    }

    /**
    * @notice Change the objection phase duration to `_objectionPhaseTime` sec. The change affects all existing unexecuted votes, so be really careful with it
    * @param _objectionPhaseTime New objection time
    */
    function unsafelyChangeObjectionPhaseTime(uint64 _objectionPhaseTime)
        external
        auth(UNSAFELY_MODIFY_VOTE_TIME_ROLE)
    {
        require(voteTime > _objectionPhaseTime, ERROR_CHANGE_OBJECTION_TIME);
        objectionPhaseTime = _objectionPhaseTime;

        emit ChangeObjectionPhaseTime(_objectionPhaseTime);
    }

    /**
    * @notice Create a new vote about "`_metadata`"
    * @param _executionScript EVM script to be executed on approval
    * @param _metadata Vote metadata
    * @return voteId Id for newly created vote
    */
    function newVote(bytes _executionScript, string _metadata) external auth(CREATE_VOTES_ROLE) returns (uint256 voteId) {
        return _newVote(_executionScript, _metadata, true);
    }

    /**
    * @notice Create a new vote about "`_metadata`"
    * @dev  _executesIfDecided was deprecated to introduce a proper lock period between decision and execution.
    * @param _executionScript EVM script to be executed on approval
    * @param _metadata Vote metadata
    * @param _castVote Whether to also cast newly created vote
    * @param _executesIfDecided_deprecated Whether to also immediately execute newly created vote if decided
    * @return voteId id for newly created vote
    */
    function newVote(bytes _executionScript, string _metadata, bool _castVote, bool _executesIfDecided_deprecated)
        external
        auth(CREATE_VOTES_ROLE)
        returns (uint256 voteId)
    {
        return _newVote(_executionScript, _metadata, _castVote);
    }

    /**
    * @notice Vote `_supports ? 'yes' : 'no'` in vote #`_voteId`. During objection phase one can only vote 'no'
    * @dev Initialization check is implicitly provided by `voteExists()` as new votes can only be
    *      created via `newVote(),` which requires initialization
    * @dev  _executesIfDecided was deprecated to introduce a proper lock period between decision and execution.
    * @param _voteId Id for vote
    * @param _supports Whether voter supports the vote
    * @param _executesIfDecided_deprecated Whether the vote should execute its action if it becomes decided
    */
    function vote(uint256 _voteId, bool _supports, bool _executesIfDecided_deprecated) external voteExists(_voteId) {
        require(_canVote(_voteId, msg.sender), ERROR_CAN_NOT_VOTE);
        require(!_supports || _getVotePhase(votes[_voteId]) == VotePhase.Main, ERROR_CAN_NOT_VOTE);
        _vote(_voteId, _supports, msg.sender);
    }

    /**
    * @notice Execute vote #`_voteId`
    * @dev Initialization check is implicitly provided by `voteExists()` as new votes can only be
    *      created via `newVote(),` which requires initialization
    * @param _voteId Id for vote
    */
    function executeVote(uint256 _voteId) external voteExists(_voteId) {
        _executeVote(_voteId);
    }

    // Forwarding fns

    /**
    * @notice Tells whether the Voting app is a forwarder or not
    * @dev IForwarder interface conformance
    * @return Always true
    */
    function isForwarder() external pure returns (bool) {
        return true;
    }

    /**
    * @notice Creates a vote to execute the desired action, and casts a support vote if possible
    * @dev IForwarder interface conformance
    * @param _evmScript Start vote with script
    */
    function forward(bytes _evmScript) public {
        require(canForward(msg.sender, _evmScript), ERROR_CAN_NOT_FORWARD);
        _newVote(_evmScript, "", true);
    }

    /**
    * @notice Tells whether `_sender` can forward actions or not
    * @dev IForwarder interface conformance
    * @param _sender Address of the account intending to forward an action
    * @return True if the given address can create votes, false otherwise
    */
    function canForward(address _sender, bytes) public view returns (bool) {
        // Note that `canPerform()` implicitly does an initialization check itself
        return canPerform(_sender, CREATE_VOTES_ROLE, arr());
    }

    // Getter fns

    /**
    * @notice Tells whether a vote #`_voteId` can be executed or not
    * @dev Initialization check is implicitly provided by `voteExists()` as new votes can only be
    *      created via `newVote(),` which requires initialization
    * @param _voteId Vote identifier
    * @return True if the given vote can be executed, false otherwise
    */
    function canExecute(uint256 _voteId) public view voteExists(_voteId) returns (bool) {
        return _canExecute(_voteId);
    }

    /**
    * @notice Tells whether `_voter` can participate in the main or objection phase of the vote #`_voteId`
    * @dev Initialization check is implicitly provided by `voteExists()` as new votes can only be
    *      created via `newVote(),` which requires initialization
    * @param _voteId Vote identifier
    * @param _voter address of the voter to check
    * @return True if the given voter can participate in the main phase of a certain vote, false otherwise
    */
    function canVote(uint256 _voteId, address _voter) external view voteExists(_voteId) returns (bool) {
        return _canVote(_voteId, _voter);
    }

    /**
    * @notice Tells the current phase of the vote #`_voteId`
    * @dev Initialization check is implicitly provided by `voteExists()` as new votes can only be
    *      created via `newVote(),` which requires initialization
    * @param _voteId Vote identifier
    * @return VotePhase.Main if one can vote yes or no and VotePhase.Objection if one can vote only no and VotingPhase.Closed if no votes are accepted
    */
    function getVotePhase(uint256 _voteId) external view voteExists(_voteId) returns (VotePhase) {
        return _getVotePhase(votes[_voteId]);
    }

    /**
    * @dev Return all information for a vote by its ID
    * @param _voteId Vote identifier
    * @return true if the vote is open
    * @return Vote executed status
    * @return Vote start date
    * @return Vote snapshot block
    * @return Vote support required
    * @return Vote minimum acceptance quorum
    * @return Vote yeas amount
    * @return Vote nays amount
    * @return Vote power
    * @return Vote script
    * @return Vote phase
    */
    function getVote(uint256 _voteId)
        public
        view
        voteExists(_voteId)
        returns (
            bool open,
            bool executed,
            uint64 startDate,
            uint64 snapshotBlock,
            uint64 supportRequired,
            uint64 minAcceptQuorum,
            uint256 yea,
            uint256 nay,
            uint256 votingPower,
            bytes script,
            VotePhase phase
        )
    {
        Vote storage vote_ = votes[_voteId];

        open = _isVoteOpen(vote_);
        executed = vote_.executed;
        startDate = vote_.startDate;
        snapshotBlock = vote_.snapshotBlock;
        supportRequired = vote_.supportRequiredPct;
        minAcceptQuorum = vote_.minAcceptQuorumPct;
        yea = vote_.yea;
        nay = vote_.nay;
        votingPower = vote_.votingPower;
        script = vote_.executionScript;
        phase = _getVotePhase(vote_);
    }

    /**
    * @dev Return the state of a voter for a given vote by its ID
    * @param _voteId Vote identifier
    * @param _voter address of the voter
    * @return VoterState of the requested voter for a certain vote
    */
    function getVoterState(uint256 _voteId, address _voter) public view voteExists(_voteId) returns (VoterState) {
        return votes[_voteId].voters[_voter];
    }

    // Internal fns

    /**
    * @dev Internal function to create a new vote
    * @return voteId id for newly created vote
    */
    function _newVote(bytes _executionScript, string _metadata, bool _castVote) internal returns (uint256 voteId) {
        uint64 snapshotBlock = getBlockNumber64() - 1; // avoid double voting in this very block
        uint256 votingPower = token.totalSupplyAt(snapshotBlock);
        require(votingPower > 0, ERROR_NO_VOTING_POWER);

        voteId = votesLength++;

        Vote storage vote_ = votes[voteId];
        vote_.startDate = getTimestamp64();
        vote_.snapshotBlock = snapshotBlock;
        vote_.supportRequiredPct = supportRequiredPct;
        vote_.minAcceptQuorumPct = minAcceptQuorumPct;
        vote_.votingPower = votingPower;
        vote_.executionScript = _executionScript;

        emit StartVote(voteId, msg.sender, _metadata);

        if (_castVote && _canVote(voteId, msg.sender)) {
            _vote(voteId, true, msg.sender);
        }
    }

    /**
    * @dev Internal function to cast a vote or object to.
      @dev It assumes that voter can support or object to the vote
    */
    function _vote(uint256 _voteId, bool _supports, address _voter) internal {
        Vote storage vote_ = votes[_voteId];

        // This could re-enter, though we can assume the governance token is not malicious
        uint256 voterStake = token.balanceOfAt(_voter, vote_.snapshotBlock);
        VoterState state = vote_.voters[_voter];

        // If voter had previously voted, decrease count
        if (state == VoterState.Yea) {
            vote_.yea = vote_.yea.sub(voterStake);
        } else if (state == VoterState.Nay) {
            vote_.nay = vote_.nay.sub(voterStake);
        }

        if (_supports) {
            vote_.yea = vote_.yea.add(voterStake);
            vote_.voters[_voter] = VoterState.Yea;
        } else {
            vote_.nay = vote_.nay.add(voterStake);
            vote_.voters[_voter] = VoterState.Nay;
        }

        emit CastVote(_voteId, _voter, _supports, voterStake);

        if (_getVotePhase(vote_) == VotePhase.Objection) {
            emit CastObjection(_voteId, _voter, voterStake);
        }
    }

    /**
    * @dev Internal function to execute a vote. It assumes the queried vote exists.
    */
    function _executeVote(uint256 _voteId) internal {
        require(_canExecute(_voteId), ERROR_CAN_NOT_EXECUTE);
        _unsafeExecuteVote(_voteId);
    }

    /**
    * @dev Unsafe version of _executeVote that assumes you have already checked if the vote can be executed and exists
    */
    function _unsafeExecuteVote(uint256 _voteId) internal {
        Vote storage vote_ = votes[_voteId];

        vote_.executed = true;

        bytes memory input = new bytes(0); // TODO: Consider input for voting scripts
        runScript(vote_.executionScript, input, new address[](0));

        emit ExecuteVote(_voteId);
    }

    /**
    * @dev Internal function to check if a vote can be executed. It assumes the queried vote exists.
    * @return True if the given vote can be executed, false otherwise
    */
    function _canExecute(uint256 _voteId) internal view returns (bool) {
        Vote storage vote_ = votes[_voteId];

        if (vote_.executed) {
            return false;
        }

        // Vote ended?
        if (_isVoteOpen(vote_)) {
            return false;
        }

        // Has enough support?
        uint256 voteYea = vote_.yea;
        uint256 totalVotes = voteYea.add(vote_.nay);
        if (!_isValuePct(voteYea, totalVotes, vote_.supportRequiredPct)) {
            return false;
        }
        // Has min quorum?
        if (!_isValuePct(voteYea, vote_.votingPower, vote_.minAcceptQuorumPct)) {
            return false;
        }

        return true;
    }

    /**
    * @dev Internal function to check if a voter can participate on a vote. It assumes the queried vote exists.
    * @return True if the given voter can participate a certain vote, false otherwise
    */
    function _canVote(uint256 _voteId, address _voter) internal view returns (bool) {
        Vote storage vote_ = votes[_voteId];
        return _isVoteOpen(vote_) && token.balanceOfAt(_voter, vote_.snapshotBlock) > 0;
    }

    /**
    * @dev Internal function to get the current phase of the vote. It assumes the queried vote exists.
    * @return VotePhase.Main if one can vote 'yes' or 'no', VotePhase.Objection if one can vote only 'no' or VotePhase.Closed if no votes are accepted
    */
    function _getVotePhase(Vote storage vote_) internal view returns (VotePhase) {
        uint64 timestamp = getTimestamp64();
        uint64 voteTimeEnd = vote_.startDate.add(voteTime);
        if (timestamp < voteTimeEnd.sub(objectionPhaseTime)) {
            return VotePhase.Main;
        }
        if (timestamp < voteTimeEnd) {
            return VotePhase.Objection;
        }
        return VotePhase.Closed;
    }

    /**
    * @dev Internal function to check if a vote is still open for both support and objection
    * @return True if less than voteTime has passed since the vote start
    */
    function _isVoteOpen(Vote storage vote_) internal view returns (bool) {
        return getTimestamp64() < vote_.startDate.add(voteTime) && !vote_.executed;
    }

    /**
    * @dev Calculates whether `_value` is more than a percentage `_pct` of `_total`
    */
    function _isValuePct(uint256 _value, uint256 _total, uint256 _pct) internal pure returns (bool) {
        if (_total == 0) {
            return false;
        }

        uint256 computedPct = _value.mul(PCT_BASE) / _total;
        return computedPct > _pct;
    }
}
        

@aragon/os/contracts/common/IForwarder.sol

/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.4.24;


interface IForwarder {
    function isForwarder() external pure returns (bool);

    // TODO: this should be external
    // See https://github.com/ethereum/solidity/issues/4832
    function canForward(address sender, bytes evmCallScript) public view returns (bool);

    // TODO: this should be external
    // See https://github.com/ethereum/solidity/issues/4832
    function forward(bytes evmCallScript) public;
}
          

@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/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/minime/contracts/ITokenController.sol

pragma solidity ^0.4.24;

/// @dev The token controller contract must implement these functions


interface ITokenController {
    /// @notice Called when `_owner` sends ether to the MiniMe Token contract
    /// @param _owner The address that sent the ether to create tokens
    /// @return True if the ether is accepted, false if it throws
    function proxyPayment(address _owner) external payable returns(bool);

    /// @notice Notifies the controller about a token transfer allowing the
    ///  controller to react if desired
    /// @param _from The origin of the transfer
    /// @param _to The destination of the transfer
    /// @param _amount The amount of the transfer
    /// @return False if the controller does not authorize the transfer
    function onTransfer(address _from, address _to, uint _amount) external returns(bool);

    /// @notice Notifies the controller about an approval allowing the
    ///  controller to react if desired
    /// @param _owner The address that calls `approve()`
    /// @param _spender The spender in the `approve()` call
    /// @param _amount The amount in the `approve()` call
    /// @return False if the controller does not authorize the approval
    function onApprove(address _owner, address _spender, uint _amount) external returns(bool);
}
          

@aragon/minime/contracts/MiniMeToken.sol

pragma solidity ^0.4.24;

/*
    Copyright 2016, Jordi Baylina
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/// @title MiniMeToken Contract
/// @author Jordi Baylina
/// @dev This token contract's goal is to make it easy for anyone to clone this
///  token using the token distribution at a given block, this will allow DAO's
///  and DApps to upgrade their features in a decentralized manner without
///  affecting the original token
/// @dev It is ERC20 compliant, but still needs to under go further testing.

import "./ITokenController.sol";

contract Controlled {
    /// @notice The address of the controller is the only address that can call
    ///  a function with this modifier
    modifier onlyController {
        require(msg.sender == controller);
        _;
    }

    address public controller;

    function Controlled()  public { controller = msg.sender;}

    /// @notice Changes the controller of the contract
    /// @param _newController The new controller of the contract
    function changeController(address _newController) onlyController  public {
        controller = _newController;
    }
}

contract ApproveAndCallFallBack {
    function receiveApproval(
        address from,
        uint256 _amount,
        address _token,
        bytes _data
    ) public;
}

/// @dev The actual token contract, the default controller is the msg.sender
///  that deploys the contract, so usually this token will be deployed by a
///  token controller contract, which Giveth will call a "Campaign"
contract MiniMeToken is Controlled {

    string public name;                //The Token's name: e.g. DigixDAO Tokens
    uint8 public decimals;             //Number of decimals of the smallest unit
    string public symbol;              //An identifier: e.g. REP
    string public version = "MMT_0.1"; //An arbitrary versioning scheme


    /// @dev `Checkpoint` is the structure that attaches a block number to a
    ///  given value, the block number attached is the one that last changed the
    ///  value
    struct Checkpoint {

        // `fromBlock` is the block number that the value was generated from
        uint128 fromBlock;

        // `value` is the amount of tokens at a specific block number
        uint128 value;
    }

    // `parentToken` is the Token address that was cloned to produce this token;
    //  it will be 0x0 for a token that was not cloned
    MiniMeToken public parentToken;

    // `parentSnapShotBlock` is the block number from the Parent Token that was
    //  used to determine the initial distribution of the Clone Token
    uint public parentSnapShotBlock;

    // `creationBlock` is the block number that the Clone Token was created
    uint public creationBlock;

    // `balances` is the map that tracks the balance of each address, in this
    //  contract when the balance changes the block number that the change
    //  occurred is also included in the map
    mapping (address => Checkpoint[]) balances;

    // `allowed` tracks any extra transfer rights as in all ERC20 tokens
    mapping (address => mapping (address => uint256)) allowed;

    // Tracks the history of the `totalSupply` of the token
    Checkpoint[] totalSupplyHistory;

    // Flag that determines if the token is transferable or not.
    bool public transfersEnabled;

    // The factory used to create new clone tokens
    MiniMeTokenFactory public tokenFactory;

////////////////
// Constructor
////////////////

    /// @notice Constructor to create a MiniMeToken
    /// @param _tokenFactory The address of the MiniMeTokenFactory contract that
    ///  will create the Clone token contracts, the token factory needs to be
    ///  deployed first
    /// @param _parentToken Address of the parent token, set to 0x0 if it is a
    ///  new token
    /// @param _parentSnapShotBlock Block of the parent token that will
    ///  determine the initial distribution of the clone token, set to 0 if it
    ///  is a new token
    /// @param _tokenName Name of the new token
    /// @param _decimalUnits Number of decimals of the new token
    /// @param _tokenSymbol Token Symbol for the new token
    /// @param _transfersEnabled If true, tokens will be able to be transferred
    function MiniMeToken(
        MiniMeTokenFactory _tokenFactory,
        MiniMeToken _parentToken,
        uint _parentSnapShotBlock,
        string _tokenName,
        uint8 _decimalUnits,
        string _tokenSymbol,
        bool _transfersEnabled
    )  public
    {
        tokenFactory = _tokenFactory;
        name = _tokenName;                                 // Set the name
        decimals = _decimalUnits;                          // Set the decimals
        symbol = _tokenSymbol;                             // Set the symbol
        parentToken = _parentToken;
        parentSnapShotBlock = _parentSnapShotBlock;
        transfersEnabled = _transfersEnabled;
        creationBlock = block.number;
    }


///////////////////
// ERC20 Methods
///////////////////

    /// @notice Send `_amount` tokens to `_to` from `msg.sender`
    /// @param _to The address of the recipient
    /// @param _amount The amount of tokens to be transferred
    /// @return Whether the transfer was successful or not
    function transfer(address _to, uint256 _amount) public returns (bool success) {
        require(transfersEnabled);
        return doTransfer(msg.sender, _to, _amount);
    }

    /// @notice Send `_amount` tokens to `_to` from `_from` on the condition it
    ///  is approved by `_from`
    /// @param _from The address holding the tokens being transferred
    /// @param _to The address of the recipient
    /// @param _amount The amount of tokens to be transferred
    /// @return True if the transfer was successful
    function transferFrom(address _from, address _to, uint256 _amount) public returns (bool success) {

        // The controller of this contract can move tokens around at will,
        //  this is important to recognize! Confirm that you trust the
        //  controller of this contract, which in most situations should be
        //  another open source smart contract or 0x0
        if (msg.sender != controller) {
            require(transfersEnabled);

            // The standard ERC 20 transferFrom functionality
            if (allowed[_from][msg.sender] < _amount)
                return false;
            allowed[_from][msg.sender] -= _amount;
        }
        return doTransfer(_from, _to, _amount);
    }

    /// @dev This is the actual transfer function in the token contract, it can
    ///  only be called by other functions in this contract.
    /// @param _from The address holding the tokens being transferred
    /// @param _to The address of the recipient
    /// @param _amount The amount of tokens to be transferred
    /// @return True if the transfer was successful
    function doTransfer(address _from, address _to, uint _amount) internal returns(bool) {
        if (_amount == 0) {
            return true;
        }
        require(parentSnapShotBlock < block.number);
        // Do not allow transfer to 0x0 or the token contract itself
        require((_to != 0) && (_to != address(this)));
        // If the amount being transfered is more than the balance of the
        //  account the transfer returns false
        var previousBalanceFrom = balanceOfAt(_from, block.number);
        if (previousBalanceFrom < _amount) {
            return false;
        }
        // Alerts the token controller of the transfer
        if (isContract(controller)) {
            // Adding the ` == true` makes the linter shut up so...
            require(ITokenController(controller).onTransfer(_from, _to, _amount) == true);
        }
        // First update the balance array with the new value for the address
        //  sending the tokens
        updateValueAtNow(balances[_from], previousBalanceFrom - _amount);
        // Then update the balance array with the new value for the address
        //  receiving the tokens
        var previousBalanceTo = balanceOfAt(_to, block.number);
        require(previousBalanceTo + _amount >= previousBalanceTo); // Check for overflow
        updateValueAtNow(balances[_to], previousBalanceTo + _amount);
        // An event to make the transfer easy to find on the blockchain
        Transfer(_from, _to, _amount);
        return true;
    }

    /// @param _owner The address that's balance is being requested
    /// @return The balance of `_owner` at the current block
    function balanceOf(address _owner) public constant returns (uint256 balance) {
        return balanceOfAt(_owner, block.number);
    }

    /// @notice `msg.sender` approves `_spender` to spend `_amount` tokens on
    ///  its behalf. This is a modified version of the ERC20 approve function
    ///  to be a little bit safer
    /// @param _spender The address of the account able to transfer the tokens
    /// @param _amount The amount of tokens to be approved for transfer
    /// @return True if the approval was successful
    function approve(address _spender, uint256 _amount) public returns (bool success) {
        require(transfersEnabled);

        // To change the approve amount you first have to reduce the addresses`
        //  allowance to zero by calling `approve(_spender,0)` if it is not
        //  already 0 to mitigate the race condition described here:
        //  https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
        require((_amount == 0) || (allowed[msg.sender][_spender] == 0));

        // Alerts the token controller of the approve function call
        if (isContract(controller)) {
            // Adding the ` == true` makes the linter shut up so...
            require(ITokenController(controller).onApprove(msg.sender, _spender, _amount) == true);
        }

        allowed[msg.sender][_spender] = _amount;
        Approval(msg.sender, _spender, _amount);
        return true;
    }

    /// @dev This function makes it easy to read the `allowed[]` map
    /// @param _owner The address of the account that owns the token
    /// @param _spender The address of the account able to transfer the tokens
    /// @return Amount of remaining tokens of _owner that _spender is allowed
    ///  to spend
    function allowance(address _owner, address _spender) public constant returns (uint256 remaining) {
        return allowed[_owner][_spender];
    }

    /// @notice `msg.sender` approves `_spender` to send `_amount` tokens on
    ///  its behalf, and then a function is triggered in the contract that is
    ///  being approved, `_spender`. This allows users to use their tokens to
    ///  interact with contracts in one function call instead of two
    /// @param _spender The address of the contract able to transfer the tokens
    /// @param _amount The amount of tokens to be approved for transfer
    /// @return True if the function call was successful
    function approveAndCall(ApproveAndCallFallBack _spender, uint256 _amount, bytes _extraData) public returns (bool success) {
        require(approve(_spender, _amount));

        _spender.receiveApproval(
            msg.sender,
            _amount,
            this,
            _extraData
        );

        return true;
    }

    /// @dev This function makes it easy to get the total number of tokens
    /// @return The total number of tokens
    function totalSupply() public constant returns (uint) {
        return totalSupplyAt(block.number);
    }


////////////////
// Query balance and totalSupply in History
////////////////

    /// @dev Queries the balance of `_owner` at a specific `_blockNumber`
    /// @param _owner The address from which the balance will be retrieved
    /// @param _blockNumber The block number when the balance is queried
    /// @return The balance at `_blockNumber`
    function balanceOfAt(address _owner, uint _blockNumber) public constant returns (uint) {

        // These next few lines are used when the balance of the token is
        //  requested before a check point was ever created for this token, it
        //  requires that the `parentToken.balanceOfAt` be queried at the
        //  genesis block for that token as this contains initial balance of
        //  this token
        if ((balances[_owner].length == 0) || (balances[_owner][0].fromBlock > _blockNumber)) {
            if (address(parentToken) != 0) {
                return parentToken.balanceOfAt(_owner, min(_blockNumber, parentSnapShotBlock));
            } else {
                // Has no parent
                return 0;
            }

        // This will return the expected balance during normal situations
        } else {
            return getValueAt(balances[_owner], _blockNumber);
        }
    }

    /// @notice Total amount of tokens at a specific `_blockNumber`.
    /// @param _blockNumber The block number when the totalSupply is queried
    /// @return The total amount of tokens at `_blockNumber`
    function totalSupplyAt(uint _blockNumber) public constant returns(uint) {

        // These next few lines are used when the totalSupply of the token is
        //  requested before a check point was ever created for this token, it
        //  requires that the `parentToken.totalSupplyAt` be queried at the
        //  genesis block for this token as that contains totalSupply of this
        //  token at this block number.
        if ((totalSupplyHistory.length == 0) || (totalSupplyHistory[0].fromBlock > _blockNumber)) {
            if (address(parentToken) != 0) {
                return parentToken.totalSupplyAt(min(_blockNumber, parentSnapShotBlock));
            } else {
                return 0;
            }

        // This will return the expected totalSupply during normal situations
        } else {
            return getValueAt(totalSupplyHistory, _blockNumber);
        }
    }

////////////////
// Clone Token Method
////////////////

    /// @notice Creates a new clone token with the initial distribution being
    ///  this token at `_snapshotBlock`
    /// @param _cloneTokenName Name of the clone token
    /// @param _cloneDecimalUnits Number of decimals of the smallest unit
    /// @param _cloneTokenSymbol Symbol of the clone token
    /// @param _snapshotBlock Block when the distribution of the parent token is
    ///  copied to set the initial distribution of the new clone token;
    ///  if the block is zero than the actual block, the current block is used
    /// @param _transfersEnabled True if transfers are allowed in the clone
    /// @return The address of the new MiniMeToken Contract
    function createCloneToken(
        string _cloneTokenName,
        uint8 _cloneDecimalUnits,
        string _cloneTokenSymbol,
        uint _snapshotBlock,
        bool _transfersEnabled
    ) public returns(MiniMeToken)
    {
        uint256 snapshot = _snapshotBlock == 0 ? block.number - 1 : _snapshotBlock;

        MiniMeToken cloneToken = tokenFactory.createCloneToken(
            this,
            snapshot,
            _cloneTokenName,
            _cloneDecimalUnits,
            _cloneTokenSymbol,
            _transfersEnabled
        );

        cloneToken.changeController(msg.sender);

        // An event to make the token easy to find on the blockchain
        NewCloneToken(address(cloneToken), snapshot);
        return cloneToken;
    }

////////////////
// Generate and destroy tokens
////////////////

    /// @notice Generates `_amount` tokens that are assigned to `_owner`
    /// @param _owner The address that will be assigned the new tokens
    /// @param _amount The quantity of tokens generated
    /// @return True if the tokens are generated correctly
    function generateTokens(address _owner, uint _amount) onlyController public returns (bool) {
        uint curTotalSupply = totalSupply();
        require(curTotalSupply + _amount >= curTotalSupply); // Check for overflow
        uint previousBalanceTo = balanceOf(_owner);
        require(previousBalanceTo + _amount >= previousBalanceTo); // Check for overflow
        updateValueAtNow(totalSupplyHistory, curTotalSupply + _amount);
        updateValueAtNow(balances[_owner], previousBalanceTo + _amount);
        Transfer(0, _owner, _amount);
        return true;
    }


    /// @notice Burns `_amount` tokens from `_owner`
    /// @param _owner The address that will lose the tokens
    /// @param _amount The quantity of tokens to burn
    /// @return True if the tokens are burned correctly
    function destroyTokens(address _owner, uint _amount) onlyController public returns (bool) {
        uint curTotalSupply = totalSupply();
        require(curTotalSupply >= _amount);
        uint previousBalanceFrom = balanceOf(_owner);
        require(previousBalanceFrom >= _amount);
        updateValueAtNow(totalSupplyHistory, curTotalSupply - _amount);
        updateValueAtNow(balances[_owner], previousBalanceFrom - _amount);
        Transfer(_owner, 0, _amount);
        return true;
    }

////////////////
// Enable tokens transfers
////////////////


    /// @notice Enables token holders to transfer their tokens freely if true
    /// @param _transfersEnabled True if transfers are allowed in the clone
    function enableTransfers(bool _transfersEnabled) onlyController public {
        transfersEnabled = _transfersEnabled;
    }

////////////////
// Internal helper functions to query and set a value in a snapshot array
////////////////

    /// @dev `getValueAt` retrieves the number of tokens at a given block number
    /// @param checkpoints The history of values being queried
    /// @param _block The block number to retrieve the value at
    /// @return The number of tokens being queried
    function getValueAt(Checkpoint[] storage checkpoints, uint _block) constant internal returns (uint) {
        if (checkpoints.length == 0)
            return 0;

        // Shortcut for the actual value
        if (_block >= checkpoints[checkpoints.length-1].fromBlock)
            return checkpoints[checkpoints.length-1].value;
        if (_block < checkpoints[0].fromBlock)
            return 0;

        // Binary search of the value in the array
        uint min = 0;
        uint max = checkpoints.length-1;
        while (max > min) {
            uint mid = (max + min + 1) / 2;
            if (checkpoints[mid].fromBlock<=_block) {
                min = mid;
            } else {
                max = mid-1;
            }
        }
        return checkpoints[min].value;
    }

    /// @dev `updateValueAtNow` used to update the `balances` map and the
    ///  `totalSupplyHistory`
    /// @param checkpoints The history of data being updated
    /// @param _value The new number of tokens
    function updateValueAtNow(Checkpoint[] storage checkpoints, uint _value) internal {
        require(_value <= uint128(-1));

        if ((checkpoints.length == 0) || (checkpoints[checkpoints.length - 1].fromBlock < block.number)) {
            Checkpoint storage newCheckPoint = checkpoints[checkpoints.length++];
            newCheckPoint.fromBlock = uint128(block.number);
            newCheckPoint.value = uint128(_value);
        } else {
            Checkpoint storage oldCheckPoint = checkpoints[checkpoints.length - 1];
            oldCheckPoint.value = uint128(_value);
        }
    }

    /// @dev Internal function to determine if an address is a contract
    /// @param _addr The address being queried
    /// @return True if `_addr` is a contract
    function isContract(address _addr) constant internal returns(bool) {
        uint size;
        if (_addr == 0)
            return false;

        assembly {
            size := extcodesize(_addr)
        }

        return size>0;
    }

    /// @dev Helper function to return a min betwen the two uints
    function min(uint a, uint b) pure internal returns (uint) {
        return a < b ? a : b;
    }

    /// @notice The fallback function: If the contract's controller has not been
    ///  set to 0, then the `proxyPayment` method is called which relays the
    ///  ether and creates tokens as described in the token controller contract
    function () external payable {
        require(isContract(controller));
        // Adding the ` == true` makes the linter shut up so...
        require(ITokenController(controller).proxyPayment.value(msg.value)(msg.sender) == true);
    }

//////////
// Safety Methods
//////////

    /// @notice This method can be used by the controller to extract mistakenly
    ///  sent tokens to this contract.
    /// @param _token The address of the token contract that you want to recover
    ///  set to 0 in case you want to extract ether.
    function claimTokens(address _token) onlyController public {
        if (_token == 0x0) {
            controller.transfer(this.balance);
            return;
        }

        MiniMeToken token = MiniMeToken(_token);
        uint balance = token.balanceOf(this);
        token.transfer(controller, balance);
        ClaimedTokens(_token, controller, balance);
    }

////////////////
// Events
////////////////
    event ClaimedTokens(address indexed _token, address indexed _controller, uint _amount);
    event Transfer(address indexed _from, address indexed _to, uint256 _amount);
    event NewCloneToken(address indexed _cloneToken, uint _snapshotBlock);
    event Approval(
        address indexed _owner,
        address indexed _spender,
        uint256 _amount
        );

}


////////////////
// MiniMeTokenFactory
////////////////

/// @dev This contract is used to generate clone contracts from a contract.
///  In solidity this is the way to create a contract from a contract of the
///  same class
contract MiniMeTokenFactory {
    event NewFactoryCloneToken(address indexed _cloneToken, address indexed _parentToken, uint _snapshotBlock);

    /// @notice Update the DApp by creating a new token with new functionalities
    ///  the msg.sender becomes the controller of this clone token
    /// @param _parentToken Address of the token being cloned
    /// @param _snapshotBlock Block of the parent token that will
    ///  determine the initial distribution of the clone token
    /// @param _tokenName Name of the new token
    /// @param _decimalUnits Number of decimals of the new token
    /// @param _tokenSymbol Token Symbol for the new token
    /// @param _transfersEnabled If true, tokens will be able to be transferred
    /// @return The address of the new token contract
    function createCloneToken(
        MiniMeToken _parentToken,
        uint _snapshotBlock,
        string _tokenName,
        uint8 _decimalUnits,
        string _tokenSymbol,
        bool _transfersEnabled
    ) public returns (MiniMeToken)
    {
        MiniMeToken newToken = new MiniMeToken(
            this,
            _parentToken,
            _snapshotBlock,
            _tokenName,
            _decimalUnits,
            _tokenSymbol,
            _transfersEnabled
        );

        newToken.changeController(msg.sender);
        NewFactoryCloneToken(address(newToken), address(_parentToken), _snapshotBlock);
        return newToken;
    }
}
          

@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/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/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/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/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/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/math/SafeMath.sol

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

pragma solidity ^0.4.24;


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

    /**
    * @dev Multiplies two numbers, reverts on overflow.
    */
    function mul(uint256 _a, uint256 _b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
        if (_a == 0) {
            return 0;
        }

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

        return c;
    }

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

        return c;
    }

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

        return c;
    }

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

        return c;
    }

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

@aragon/os/contracts/lib/math/SafeMath64.sol

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

pragma solidity ^0.4.24;


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

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

        return uint64(c);
    }

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

        return c;
    }

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

        return c;
    }

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

        return c;
    }

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

@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
    );
}
          

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":"nonpayable","payable":false,"outputs":[],"name":"unsafelyChangeObjectionPhaseTime","inputs":[{"type":"uint64","name":"_objectionPhaseTime"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"initialize","inputs":[{"type":"address","name":"_token"},{"type":"uint64","name":"_supportRequiredPct"},{"type":"uint64","name":"_minAcceptQuorumPct"},{"type":"uint64","name":"_voteTime"},{"type":"uint64","name":"_objectionPhaseTime"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bytes32","name":""}],"name":"UNSAFELY_MODIFY_VOTE_TIME_ROLE","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"unsafelyChangeVoteTime","inputs":[{"type":"uint64","name":"_voteTime"}],"constant":false},{"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":"view","payable":false,"outputs":[{"type":"bytes32","name":""}],"name":"MODIFY_QUORUM_ROLE","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint64","name":""}],"name":"objectionPhaseTime","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint8","name":""}],"name":"getVoterState","inputs":[{"type":"uint256","name":"_voteId"},{"type":"address","name":"_voter"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":"open"},{"type":"bool","name":"executed"},{"type":"uint64","name":"startDate"},{"type":"uint64","name":"snapshotBlock"},{"type":"uint64","name":"supportRequired"},{"type":"uint64","name":"minAcceptQuorum"},{"type":"uint256","name":"yea"},{"type":"uint256","name":"nay"},{"type":"uint256","name":"votingPower"},{"type":"bytes","name":"script"},{"type":"uint8","name":"phase"}],"name":"getVote","inputs":[{"type":"uint256","name":"_voteId"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"changeMinAcceptQuorumPct","inputs":[{"type":"uint64","name":"_minAcceptQuorumPct"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bytes32","name":""}],"name":"MODIFY_SUPPORT_ROLE","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"changeSupportRequiredPct","inputs":[{"type":"uint64","name":"_supportRequiredPct"}],"constant":false},{"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":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getInitializationBlock","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"transferToVault","inputs":[{"type":"address","name":"_token"}],"constant":false},{"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":"address","name":""}],"name":"getEVMScriptRegistry","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint64","name":""}],"name":"voteTime","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bytes32","name":""}],"name":"CREATE_VOTES_ROLE","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"canForward","inputs":[{"type":"address","name":"_sender"},{"type":"bytes","name":""}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"canExecute","inputs":[{"type":"uint256","name":"_voteId"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"canVote","inputs":[{"type":"uint256","name":"_voteId"},{"type":"address","name":"_voter"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"kernel","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"uint256","name":"voteId"}],"name":"newVote","inputs":[{"type":"bytes","name":"_executionScript"},{"type":"string","name":"_metadata"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"forward","inputs":[{"type":"bytes","name":"_evmScript"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint64","name":""}],"name":"minAcceptQuorumPct","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":"uint256","name":""}],"name":"votesLength","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"vote","inputs":[{"type":"uint256","name":"_voteId"},{"type":"bool","name":"_supports"},{"type":"bool","name":"_executesIfDecided_deprecated"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"uint256","name":"voteId"}],"name":"newVote","inputs":[{"type":"bytes","name":"_executionScript"},{"type":"string","name":"_metadata"},{"type":"bool","name":"_castVote"},{"type":"bool","name":"_executesIfDecided_deprecated"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint8","name":""}],"name":"getVotePhase","inputs":[{"type":"uint256","name":"_voteId"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"executeVote","inputs":[{"type":"uint256","name":"_voteId"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint64","name":""}],"name":"supportRequiredPct","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"token","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint64","name":""}],"name":"PCT_BASE","inputs":[],"constant":true},{"type":"function","stateMutability":"pure","payable":false,"outputs":[{"type":"bool","name":""}],"name":"isForwarder","inputs":[],"constant":true},{"type":"event","name":"StartVote","inputs":[{"type":"uint256","name":"voteId","indexed":true},{"type":"address","name":"creator","indexed":true},{"type":"string","name":"metadata","indexed":false}],"anonymous":false},{"type":"event","name":"CastVote","inputs":[{"type":"uint256","name":"voteId","indexed":true},{"type":"address","name":"voter","indexed":true},{"type":"bool","name":"supports","indexed":false},{"type":"uint256","name":"stake","indexed":false}],"anonymous":false},{"type":"event","name":"CastObjection","inputs":[{"type":"uint256","name":"voteId","indexed":true},{"type":"address","name":"voter","indexed":true},{"type":"uint256","name":"stake","indexed":false}],"anonymous":false},{"type":"event","name":"ExecuteVote","inputs":[{"type":"uint256","name":"voteId","indexed":true}],"anonymous":false},{"type":"event","name":"ChangeSupportRequired","inputs":[{"type":"uint64","name":"supportRequiredPct","indexed":false}],"anonymous":false},{"type":"event","name":"ChangeMinQuorum","inputs":[{"type":"uint64","name":"minAcceptQuorumPct","indexed":false}],"anonymous":false},{"type":"event","name":"ChangeVoteTime","inputs":[{"type":"uint64","name":"voteTime","indexed":false}],"anonymous":false},{"type":"event","name":"ChangeObjectionPhaseTime","inputs":[{"type":"uint64","name":"objectionPhaseTime","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}]
              

Contract Creation Code

Verify & Publish
0x6080604052620000146200001a60201b60201c565b62000231565b6200002a6200011c60201b60201c565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a454400000000000000006020820152901562000106576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015620000ca578181015183820152602001620000b0565b50505050905090810190601f168015620000f85780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506200011a6000196200014f60201b60201c565b565b60006200014a6000805160206200400483398151915260001b600019166200022960201b620027a61760201c565b905090565b6200015f6200011c60201b60201c565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a4544000000000000000060208201529015620001fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015620000ca578181015183820152602001620000b0565b506200022660008051602062004004833981519152826200022d602090811b6200312617901c565b50565b5490565b9055565b613dc380620002416000396000f3006080604052600436106101c65760003560e01c63ffffffff1680630803fac0146101cb5780631351c2f5146101f457806313e094531461021857806321ab25ed1461025857806324b2c7c41461027f5780632914b9bd146102a157806332f0a3b5146103165780633c624c751461032b5780633fe1614e146103405780634b12311c146103725780635a55c1f0146103ba5780635eb24332146104bc57806362de7e5a146104de5780637c1d0b87146104f35780637e7db6e11461051557806380afdea8146105365780638b3dd7491461054b5780639d4941d814610560578063a1658fad14610581578063a479e508146105e8578063bcf93dd6146105fd578063be2c64d414610612578063c0774df314610627578063cc63604a1461068e578063cdb2867b146106a6578063d4aae0c4146106ca578063d5db2c80146106df578063d948d4681461070b578063dc474b1a14610764578063de4796ed14610779578063de4f63471461078e578063df133bca146107a3578063f4b00513146107c5578063f5edb03a146107fb578063f98a4eca14610813578063fad167ab1461082b578063fc0c546a14610840578063fc157cb414610855578063fd64eccb1461086a575b600080fd5b3480156101d757600080fd5b506101e061087f565b604080519115158252519081900360200190f35b34801561020057600080fd5b5061021667ffffffffffffffff600435166108a9565b005b34801561022457600080fd5b50610216600160a060020a036004351667ffffffffffffffff60243581169060443581169060643581169060843516610aa3565b34801561026457600080fd5b5061026d610db0565b60408051918252519081900360200190f35b34801561028b57600080fd5b5061021667ffffffffffffffff60043516610de5565b3480156102ad57600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526102fa943694929360249392840191908190840183828082843750949750610fac9650505050505050565b60408051600160a060020a039092168252519081900360200190f35b34801561032257600080fd5b506102fa61108f565b34801561033757600080fd5b5061026d611105565b34801561034c57600080fd5b5061035561113a565b6040805167ffffffffffffffff9092168252519081900360200190f35b34801561037e57600080fd5b50610396600435600160a060020a036024351661114a565b604051808260028111156103a657fe5b60ff16815260200191505060405180910390f35b3480156103c657600080fd5b506103d26004356111fa565b604080518c151581528b1515602082015267ffffffffffffffff808c16928201929092528982166060820152888216608082015290871660a082015260c0810186905260e0810185905261010081018490526101208101610140820183600281111561043a57fe5b60ff168152602001828103825284818151815260200191508051906020019080838360005b8381101561047757818101518382015260200161045f565b50505050905090810190601f1680156104a45780820380516001836020036101000a031916815260200191505b509c5050505050505050505050505060405180910390f35b3480156104c857600080fd5b5061021667ffffffffffffffff600435166113f5565b3480156104ea57600080fd5b5061026d6115b9565b3480156104ff57600080fd5b5061021667ffffffffffffffff600435166115ee565b34801561052157600080fd5b506101e0600160a060020a0360043516611867565b34801561054257600080fd5b5061026d61186d565b34801561055757600080fd5b5061026d61189d565b34801561056c57600080fd5b50610216600160a060020a03600435166118c8565b34801561058d57600080fd5b5060408051602060046044358181013583810280860185019096528085526101e0958335600160a060020a0316956024803596369695606495939492019291829185019084908082843750949750611b579650505050505050565b3480156105f457600080fd5b506102fa611ca4565b34801561060957600080fd5b50610355611d59565b34801561061e57600080fd5b5061026d611d75565b34801561063357600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526101e0958335600160a060020a0316953695604494919390910191908190840183828082843750949750611d989650505050505050565b34801561069a57600080fd5b506101e0600435611dd6565b3480156106b257600080fd5b506101e0600435600160a060020a0360243516611e65565b3480156106d657600080fd5b506102fa611ef4565b3480156106eb57600080fd5b5061026d6024600480358281019290820135918135918201910135611f1f565b34801561071757600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526102169436949293602493928401919081908401838280828437509497506120439650505050505050565b34801561077057600080fd5b506103556120f4565b34801561078557600080fd5b506101e0612104565b34801561079a57600080fd5b5061026d612117565b3480156107af57600080fd5b506102166004356024351515604435151561211d565b3480156107d157600080fd5b5061026d6024600480358281019290820135918135918201910135604435151560643515156122eb565b34801561080757600080fd5b50610396600435612410565b34801561081f57600080fd5b506102166004356124a4565b34801561083757600080fd5b50610355612526565b34801561084c57600080fd5b506102fa61253d565b34801561086157600080fd5b5061035561254c565b34801561087657600080fd5b506101e0612558565b60008061088a61189d565b905080158015906108a257508061089f61255d565b10155b91505b5090565b604080517f554e534146454c595f4d4f444946595f564f54455f54494d455f524f4c4500008152815190819003601e018120600080835260208301909352916108f89133918491905b50611b57565b60408051808201909152600f8152600080516020613d3883398151915260208201529015156109a85760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561096d578181015183820152602001610955565b50505050905090810190601f16801561099a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060015460408051808201909152601781527f564f54494e475f4f424a5f54494d455f544f4f5f42494700000000000000000060208201529067ffffffffffffffff808516680100000000000000009092041611610a4b5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506004805467ffffffffffffffff841667ffffffffffffffff19909116811790915560408051918252517ff2eb32f215d9f6d0f4ace97038141d2574af9f8c3bb509239254ace3d9c270009181900360200190a15050565b610aab61189d565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a4544000000000000000060208201529015610b305760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b50610b39612561565b60408051808201909152601081527f564f54494e475f494e49545f5043545300000000000000000000000000000000602082015267ffffffffffffffff8086169085161115610bcd5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5060408051808201909152601b81527f564f54494e475f494e49545f535550504f52545f544f4f5f42494700000000006020820152670de0b6b3a764000067ffffffffffffffff861610610c665760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5060408051808201909152601c81527f564f54494e475f494e49545f4f424a5f54494d455f544f4f5f42494700000000602082015267ffffffffffffffff80831690841611610cfa5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0396909616959095177bffffffffffffffff0000000000000000000000000000000000000000191660a060020a67ffffffffffffffff95861602179094556001805467ffffffffffffffff19908116938516939093176fffffffffffffffff0000000000000000191668010000000000000000928516929092029190911790556004805490911692909116919091179055565b604080517f554e534146454c595f4d4f444946595f564f54455f54494d455f524f4c4500008152905190819003601e01902081565b604080517f554e534146454c595f4d4f444946595f564f54455f54494d455f524f4c4500008152815190819003601e01812060008083526020830190935291610e329133918491906108f2565b60408051808201909152600f8152600080516020613d388339815191526020820152901515610ea65760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5060045460408051808201909152601a81527f564f54494e475f564f54455f54494d455f544f4f5f534d414c4c00000000000060208201529067ffffffffffffffff90811690841611610f3e5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506001805467ffffffffffffffff84166801000000000000000081026fffffffffffffffff0000000000000000199092169190911790915560408051918252517f776dcd10c15e7a1bd4fbb6c824d2a80fa8a40a3a6b401fddc678696b7fb06abe9181900360200190a15050565b6000610fb6611ca4565b600160a060020a03166304bf2a7f836040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611011578181015183820152602001610ff9565b50505050905090810190601f16801561103e5780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b15801561105d57600080fd5b505af1158015611071573d6000803e3d6000fd5b505050506040513d602081101561108757600080fd5b505192915050565b6000611099611ef4565b600160a060020a03166332f0a3b56040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156110d357600080fd5b505af11580156110e7573d6000803e3d6000fd5b505050506040513d60208110156110fd57600080fd5b505190505b90565b604080517f4d4f444946595f51554f52554d5f524f4c4500000000000000000000000000008152905190819003601201902081565b60045467ffffffffffffffff1681565b60035460408051808201909152600e8152600080516020613d58833981519152602082015260009184919082106111c65760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506000848152600260209081526040808320600160a060020a038716845260060190915290205460ff1691505b5092915050565b600080600080600080600080600060606000808c60035481106040805190810160405280600e8152602001600080516020613d588339815191528152509015156112895760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5060008e815260026020526040902091506112a382612629565b9c508160000160009054906101000a900460ff169b508160000160019054906101000a900467ffffffffffffffff169a508160000160099054906101000a900467ffffffffffffffff1699508160000160119054906101000a900467ffffffffffffffff1698508160010160009054906101000a900467ffffffffffffffff169750816002015496508160030154955081600401549450816005018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156113d25780601f106113a7576101008083540402835291602001916113d2565b820191906000526020600020905b8154815290600101906020018083116113b557829003601f168201915b505050505093506113e282612690565b9250505091939597999b90929496989a50565b604080517f4d4f444946595f51554f52554d5f524f4c450000000000000000000000000000815290519081900360120190206001546114419067ffffffffffffffff808516911661274b565b61144c338383611b57565b60408051808201909152600f8152600080516020613d3883398151915260208201529015156114c05760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5060005460408051808201909152601981527f564f54494e475f4348414e47455f51554f52554d5f504354530000000000000060208201529067ffffffffffffffff60a060020a909104811690851611156115605760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506001805467ffffffffffffffff851667ffffffffffffffff19909116811790915560408051918252517f3172f2e9273c729c2a47cc8bf7e7f18506e3e3035126d562602bd2155bc78a509181900360200190a1505050565b604080517f4d4f444946595f535550504f52545f524f4c45000000000000000000000000008152905190819003601301902081565b604080517f4d4f444946595f535550504f52545f524f4c4500000000000000000000000000815290519081900360130190206000546116419067ffffffffffffffff8085169160a060020a90041661274b565b61164c338383611b57565b60408051808201909152600f8152600080516020613d3883398151915260208201529015156116c05760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5060015460408051808201909152601a81527f564f54494e475f4348414e47455f535550504f52545f5043545300000000000060208201529067ffffffffffffffff808616911611156117585760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5060408051808201909152601a81527f564f54494e475f4348414e47455f535550505f544f4f5f4249470000000000006020820152670de0b6b3a764000067ffffffffffffffff8516106117f15760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506000805467ffffffffffffffff851660a060020a81027bffffffffffffffff0000000000000000000000000000000000000000199092169190911790915560408051918252517f903b617f7f36eb047a29b89d1bf7885fdae31d250c3320fccf11d045c11b396e9181900360200190a1505050565b50600190565b60006118987fd625496217aa6a3453eecb9c3489dc5a53e6c67b444329ea2b2cbc9ff547639b6127a6565b905090565b60006118987febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e6127a6565b60008060006118d684611867565b60408051808201909152601281527f5245434f5645525f444953414c4c4f5745440000000000000000000000000000602082015290151561195c5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5061196561108f565b9250611970836127ae565b60408051808201909152601a81527f5245434f5645525f5641554c545f4e4f545f434f4e545241435400000000000060208201529015156119f65760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b50600160a060020a0384161515611a475760405130319250600160a060020a0384169083156108fc029084906000818181858888f19350505050158015611a41573d6000803e3d6000fd5b50611b06565b5082611a62600160a060020a0382163063ffffffff6127d416565b9150611a7e600160a060020a038216848463ffffffff6128d416565b60408051808201909152601d81527f5245434f5645525f544f4b454e5f5452414e534645525f4641494c45440000006020820152901515611b045760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b505b83600160a060020a031683600160a060020a03167f596caf56044b55fb8c4ca640089bbc2b63cae3e978b851f5745cbb7c5b288e02846040518082815260200191505060405180910390a350505050565b600080611b6261087f565b1515611b715760009150611c9c565b611b79611ef4565b9050600160a060020a0381161515611b945760009150611c9c565b80600160a060020a031663fdef9106863087611baf8861294a565b60405163ffffffff861660e01b8152600160a060020a03808616600483019081529085166024830152604482018490526080606483019081528351608484015283519192909160a490910190602085019080838360005b83811015611c1e578181015183820152602001611c06565b50505050905090810190601f168015611c4b5780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b158015611c6d57600080fd5b505af1158015611c81573d6000803e3d6000fd5b505050506040513d6020811015611c9757600080fd5b505191505b509392505050565b600080611caf611ef4565b604080517fbe00bbd80000000000000000000000000000000000000000000000000000000081527fd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb60048201527fddbcfd564f642ab5627cf68b9b7d374fb4f8a36e941a75d89c87998cef03bd6160248201529051600160a060020a03929092169163be00bbd8916044808201926020929091908290030181600087803b15801561105d57600080fd5b60015468010000000000000000900467ffffffffffffffff1681565b60408051600080516020613d788339815191528152905190819003601101902081565b6000611dcf836040518080600080516020613d7883398151915281525060110190506040518091039020611dca612954565b611b57565b9392505050565b60035460408051808201909152600e8152600080516020613d5883398151915260208201526000918391908210611e525760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b50611e5c83612966565b91505b50919050565b60035460408051808201909152600e8152600080516020613d5883398151915260208201526000918491908210611ee15760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b50611eec8484612a3b565b949350505050565b60006118987f4172f0f7d2289153072b0a6ca36959e0cbe2efc3afe50fc81636caa96338137b6127a6565b60408051600080516020613d788339815191528152815190819003601101812060008083526020830190935290611f5a9033908390856108f2565b60408051808201909152600f8152600080516020613d388339815191526020820152901515611fce5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5061203986868080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f8c018190048102820181019092528a815294508a935089925082915084018382808284375060019450612b159350505050565b9695505050505050565b61204d3382611d98565b60408051808201909152601681527f564f54494e475f43414e5f4e4f545f464f52574152440000000000000000000060208201529015156120d35760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506120f08160206040519081016040528060008152506001612b15565b5050565b60015467ffffffffffffffff1681565b600060001961211161189d565b14905090565b60035481565b60035460408051808201909152600e8152600080516020613d588339815191526020820152849182106121955760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506121a08433612a3b565b60408051808201909152601381527f564f54494e475f43414e5f4e4f545f564f54450000000000000000000000000060208201529015156122265760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b508215806122535750600084815260026020526040812061224690612690565b600281111561225157fe5b145b60408051808201909152601381527f564f54494e475f43414e5f4e4f545f564f54450000000000000000000000000060208201529015156122d95760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506122e5848433612e09565b50505050565b60408051600080516020613d7883398151915281528151908190036011018120600080835260208301909352906123269033908390856108f2565b60408051808201909152600f8152600080516020613d38833981519152602082015290151561239a5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5061240488888080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f8e018190048102820181019092528c815294508c93508b92508291508401838280828437508b9450612b159350505050565b98975050505050505050565b60035460408051808201909152600e8152600080516020613d588339815191526020820152600091839190821061248c5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506000838152600260205260409020611e5c90612690565b60035460408051808201909152600e8152600080516020613d5883398151915260208201528291821061251c5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506120f08261308a565b60005460a060020a900467ffffffffffffffff1681565b600054600160a060020a031681565b670de0b6b3a764000081565b600190565b4390565b61256961189d565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a45440000000000000000602082015290156125ee5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506126276125fa61255d565b7febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e9063ffffffff61312616565b565b600154815460009161265f91610100900467ffffffffffffffff908116916801000000000000000090041663ffffffff61312a16565b67ffffffffffffffff166126716131c5565b67ffffffffffffffff1610801561268a5750815460ff16155b92915050565b600080600061269d6131c5565b60015485549193506126d391610100900467ffffffffffffffff908116916801000000000000000090041663ffffffff61312a16565b6004549091506126f69067ffffffffffffffff808416911663ffffffff6131d716565b67ffffffffffffffff168267ffffffffffffffff16101561271a5760009250612744565b8067ffffffffffffffff168267ffffffffffffffff16101561273f5760019250612744565b600292505b5050919050565b60408051600280825260608083018452926020830190803883390190505090508281600081518110151561277b57fe5b60209081029091010152805182908290600190811061279657fe5b6020908102909101015292915050565b5490565b5490565b600080600160a060020a03831615156127ca5760009150611e5f565b50506000903b1190565b60408051600160a060020a038316602480830191909152825180830390910181526044909101909152602081018051600160e060020a03167f70a0823100000000000000000000000000000000000000000000000000000000179052600090818061283f8684613278565b60408051808201909152601c81527f534146455f4552435f32305f42414c414e43455f524556455254454400000000602082015291935091508215156128ca5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5095945050505050565b60408051600160a060020a03841660248201526044808201849052825180830390910181526064909101909152602081018051600160e060020a03167fa9059cbb0000000000000000000000000000000000000000000000000000000017905260009061294185826132a9565b95945050505050565b8051602002815290565b60408051600081526020810190915290565b600081815260026020526040812080548290819060ff161561298b5760009350612a33565b61299483612629565b156129a25760009350612a33565b826002015491506129c08360030154836132f790919063ffffffff16565b83549091506129f1908390839071010000000000000000000000000000000000900467ffffffffffffffff16613385565b1515612a005760009350612a33565b60048301546001840154612a1f91849167ffffffffffffffff16613385565b1515612a2e5760009350612a33565b600193505b505050919050565b6000828152600260205260408120612a5281612629565b8015611eec5750600080548254604080517f4ee2cd7e000000000000000000000000000000000000000000000000000000008152600160a060020a038881166004830152690100000000000000000090930467ffffffffffffffff16602482015290519190921691634ee2cd7e91604480830192602092919082900301818787803b158015612ae057600080fd5b505af1158015612af4573d6000803e3d6000fd5b505050506040513d6020811015612b0a57600080fd5b505111949350505050565b6000806000806001612b256133c7565b60008054604080517f981b24d00000000000000000000000000000000000000000000000000000000081529490930367ffffffffffffffff811660048601529251929650600160a060020a03169263981b24d09260248083019360209383900390910190829087803b158015612b9a57600080fd5b505af1158015612bae573d6000803e3d6000fd5b505050506040513d6020811015612bc457600080fd5b505160408051808201909152601681527f564f54494e475f4e4f5f564f54494e475f504f57455200000000000000000000602082015290925060008311612c505760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b505060038054600181019091556000818152600260205260409020909350612c766131c5565b815468ffffffffffffffff00191661010067ffffffffffffffff928316021770ffffffffffffffff00000000000000000019166901000000000000000000858316021780835560005478ffffffffffffffff00000000000000000000000000000000001990911660a060020a909104821671010000000000000000000000000000000000021782556001805490830180549190921667ffffffffffffffff19909116179055600481018290558651612d3790600583019060208a0190613ca9565b5033600160a060020a0316847f4d72fe0577a3a3f7da968d7b892779dde102519c25527b29cf7054f245c791b9886040518080602001828103825283818151815260200191508051906020019080838360005b83811015612da2578181015183820152602001612d8a565b50505050905090810190601f168015612dcf5780820380516001836020036101000a031916815260200191505b509250505060405180910390a3848015612dee5750612dee8433612a3b565b15612dff57612dff84600133612e09565b5050509392505050565b60008381526002602090815260408083208354815483517f4ee2cd7e000000000000000000000000000000000000000000000000000000008152600160a060020a038881166004830152690100000000000000000090920467ffffffffffffffff166024820152935192959485949190921692634ee2cd7e9260448084019391929182900301818787803b158015612ea057600080fd5b505af1158015612eb4573d6000803e3d6000fd5b505050506040513d6020811015612eca57600080fd5b5051600160a060020a038516600090815260068501602052604090205490925060ff1690506001816002811115612efd57fe5b1415612f22576002830154612f18908363ffffffff6133d416565b6002840155612f51565b6002816002811115612f3057fe5b1415612f51576003830154612f4b908363ffffffff6133d416565b60038401555b8415612f9b576002830154612f6c908363ffffffff6132f716565b6002840155600160a060020a03841660009081526006840160205260409020805460ff19166001179055612fdb565b6003830154612fb0908363ffffffff6132f716565b6003840155600160a060020a03841660009081526006840160205260409020805460ff191660021790555b604080518615158152602081018490528151600160a060020a0387169289927fb34ee265e3d4f5ec4e8b52d59b2a9be8fceca2f274ebc080d8fba797fea9391f929081900390910190a3600161303084612690565b600281111561303b57fe5b141561308257604080518381529051600160a060020a0386169188917ffa539989fcfb5d8fa8c97a1102d1777a34c3543f0725fb8ab66109619bb9de189181900360200190a35b505050505050565b61309381612966565b60408051808201909152601681527f564f54494e475f43414e5f4e4f545f455845435554450000000000000000000060208201529015156131195760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5061312381613460565b50565b9055565b60408051808201909152601381527f4d41544836345f4144445f4f564552464c4f570000000000000000000000000060208201526000908383019067ffffffffffffffff8086169083161015611c9c5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b60006118986131d261355c565b613560565b60408051808201909152601481527f4d41544836345f5355425f554e444552464c4f570000000000000000000000006020820152600090819067ffffffffffffffff80861690851611156132705760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b505050900390565b6000806000806040516020818751602089018a5afa9250600083111561329d57805191505b50909590945092505050565b6000806040516020818551602087016000895af160008111156132ed573d80156132da57602081146132e3576132eb565b600193506132eb565b600183511493505b505b5090949350505050565b60408051808201909152601181527f4d4154485f4144445f4f564552464c4f5700000000000000000000000000000060208201526000908383019084821015611c9c5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b6000808315156133985760009150611c9c565b836133b186670de0b6b3a764000063ffffffff6135f916565b8115156133ba57fe5b0492909211949350505050565b60006118986131d261255d565b60408051808201909152601281527f4d4154485f5355425f554e444552464c4f57000000000000000000000000000060208201526000908190848411156132705760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b6000818152600260208181526040808420805460ff191660019081178255825195865260058201805491821615610100026000190190911694909404601f8101849004840286018301835292850183815290949361352b93919290919085018282801561350e5780601f106134e35761010080835404028352916020019161350e565b820191906000526020600020905b8154815290600101906020018083116134f157829003601f168201915b505060408051600081526020810190915286935091506136a49050565b5060405183907fbf8e2b108bb7c980e08903a8a46527699d5e84905a082d56dacb4150725c8cab90600090a2505050565b4290565b60408051808201909152601581527f55494e5436345f4e554d4245525f544f4f5f4249470000000000000000000000602082015260009067ffffffffffffffff8311156135f25760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5090919050565b60008083151561360c57600091506111f3565b5082820282848281151561361c57fe5b60408051808201909152601181527f4d4154485f4d554c5f4f564552464c4f5700000000000000000000000000000060208201529291900414611c9c5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b60606000806060806136b461087f565b60408051808201909152601481527f494e49545f4e4f545f494e495449414c495a4544000000000000000000000000602082015290151561373a5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b50600080613746611ef4565b915061375061186d565b905061375b8a610fac565b60408051808201909152601b81527f45564d52554e5f4558454355544f525f554e415641494c41424c4500000000006020820152909650600160a060020a03871615156137ed5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506040516060602482019081528b5160848301528b517f279cea3500000000000000000000000000000000000000000000000000000000975087928d928d928d9282916044820191606481019160a490910190602089019080838360005b8381101561386357818101518382015260200161384b565b50505050905090810190601f1680156138905780820380516001836020036101000a031916815260200191505b50848103835286518152865160209182019188019080838360005b838110156138c35781810151838201526020016138ab565b50505050905090810190601f1680156138f05780820380516001836020036101000a031916815260200191505b508481038252855181528551602091820191808801910280838360005b8381101561392557818101518382015260200161390d565b50505050905001965050505050505060405160208183030381529060405290600160e060020a031916602082018051600160e060020a0383818316178352505050509350600080855160208701895af460405193508080156139e957603f3d11801561399e5760203d03806020883e86016040526139e3565b60e560020a62461bcd02865260206004870152601e60248701527f45564d52554e5f4558454355544f525f494e56414c49445f52455455524e00006044870152606486fd5b506139f2565b3d6000863e3d85fd5b505085600160a060020a03167f5229a5dba83a54ae8cb5b51bdd6de9474cacbe9dd332f5185f3a4f4f2e3f4ad98b8b8660405180806020018060200180602001848103845287818151815260200191508051906020019080838360005b83811015613a67578181015183820152602001613a4f565b50505050905090810190601f168015613a945780820380516001836020036101000a031916815260200191505b50848103835286518152865160209182019188019080838360005b83811015613ac7578181015183820152602001613aaf565b50505050905090810190601f168015613af45780820380516001836020036101000a031916815260200191505b50848103825285518152855160209182019187019080838360005b83811015613b27578181015183820152602001613b0f565b50505050905090810190601f168015613b545780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a282965081600160a060020a0316613b7a611ef4565b600160a060020a0316146040805190810160405280601f81526020017f45564d52554e5f50524f5445435445445f53544154455f4d4f44494649454400815250901515613c0c5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5080613c1661186d565b60408051808201909152601f81527f45564d52554e5f50524f5445435445445f53544154455f4d4f4449464945440060208201529114613c9b5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b505050505050509392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613cea57805160ff1916838001178555613d17565b82800160010185558215613d17579182015b82811115613d17578251825591602001919060010190613cfc565b506108a5926111029250905b808211156108a55760008155600101613d2356004150505f415554485f4641494c45440000000000000000000000000000000000564f54494e475f4e4f5f564f54450000000000000000000000000000000000004352454154455f564f5445535f524f4c45000000000000000000000000000000a165627a7a7230582082c999c0a0c062fce716c0e3a28af142d305631b2e1d68a13e85310971bf04290029ebb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e

Deployed ByteCode

0x6080604052600436106101c65760003560e01c63ffffffff1680630803fac0146101cb5780631351c2f5146101f457806313e094531461021857806321ab25ed1461025857806324b2c7c41461027f5780632914b9bd146102a157806332f0a3b5146103165780633c624c751461032b5780633fe1614e146103405780634b12311c146103725780635a55c1f0146103ba5780635eb24332146104bc57806362de7e5a146104de5780637c1d0b87146104f35780637e7db6e11461051557806380afdea8146105365780638b3dd7491461054b5780639d4941d814610560578063a1658fad14610581578063a479e508146105e8578063bcf93dd6146105fd578063be2c64d414610612578063c0774df314610627578063cc63604a1461068e578063cdb2867b146106a6578063d4aae0c4146106ca578063d5db2c80146106df578063d948d4681461070b578063dc474b1a14610764578063de4796ed14610779578063de4f63471461078e578063df133bca146107a3578063f4b00513146107c5578063f5edb03a146107fb578063f98a4eca14610813578063fad167ab1461082b578063fc0c546a14610840578063fc157cb414610855578063fd64eccb1461086a575b600080fd5b3480156101d757600080fd5b506101e061087f565b604080519115158252519081900360200190f35b34801561020057600080fd5b5061021667ffffffffffffffff600435166108a9565b005b34801561022457600080fd5b50610216600160a060020a036004351667ffffffffffffffff60243581169060443581169060643581169060843516610aa3565b34801561026457600080fd5b5061026d610db0565b60408051918252519081900360200190f35b34801561028b57600080fd5b5061021667ffffffffffffffff60043516610de5565b3480156102ad57600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526102fa943694929360249392840191908190840183828082843750949750610fac9650505050505050565b60408051600160a060020a039092168252519081900360200190f35b34801561032257600080fd5b506102fa61108f565b34801561033757600080fd5b5061026d611105565b34801561034c57600080fd5b5061035561113a565b6040805167ffffffffffffffff9092168252519081900360200190f35b34801561037e57600080fd5b50610396600435600160a060020a036024351661114a565b604051808260028111156103a657fe5b60ff16815260200191505060405180910390f35b3480156103c657600080fd5b506103d26004356111fa565b604080518c151581528b1515602082015267ffffffffffffffff808c16928201929092528982166060820152888216608082015290871660a082015260c0810186905260e0810185905261010081018490526101208101610140820183600281111561043a57fe5b60ff168152602001828103825284818151815260200191508051906020019080838360005b8381101561047757818101518382015260200161045f565b50505050905090810190601f1680156104a45780820380516001836020036101000a031916815260200191505b509c5050505050505050505050505060405180910390f35b3480156104c857600080fd5b5061021667ffffffffffffffff600435166113f5565b3480156104ea57600080fd5b5061026d6115b9565b3480156104ff57600080fd5b5061021667ffffffffffffffff600435166115ee565b34801561052157600080fd5b506101e0600160a060020a0360043516611867565b34801561054257600080fd5b5061026d61186d565b34801561055757600080fd5b5061026d61189d565b34801561056c57600080fd5b50610216600160a060020a03600435166118c8565b34801561058d57600080fd5b5060408051602060046044358181013583810280860185019096528085526101e0958335600160a060020a0316956024803596369695606495939492019291829185019084908082843750949750611b579650505050505050565b3480156105f457600080fd5b506102fa611ca4565b34801561060957600080fd5b50610355611d59565b34801561061e57600080fd5b5061026d611d75565b34801561063357600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526101e0958335600160a060020a0316953695604494919390910191908190840183828082843750949750611d989650505050505050565b34801561069a57600080fd5b506101e0600435611dd6565b3480156106b257600080fd5b506101e0600435600160a060020a0360243516611e65565b3480156106d657600080fd5b506102fa611ef4565b3480156106eb57600080fd5b5061026d6024600480358281019290820135918135918201910135611f1f565b34801561071757600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526102169436949293602493928401919081908401838280828437509497506120439650505050505050565b34801561077057600080fd5b506103556120f4565b34801561078557600080fd5b506101e0612104565b34801561079a57600080fd5b5061026d612117565b3480156107af57600080fd5b506102166004356024351515604435151561211d565b3480156107d157600080fd5b5061026d6024600480358281019290820135918135918201910135604435151560643515156122eb565b34801561080757600080fd5b50610396600435612410565b34801561081f57600080fd5b506102166004356124a4565b34801561083757600080fd5b50610355612526565b34801561084c57600080fd5b506102fa61253d565b34801561086157600080fd5b5061035561254c565b34801561087657600080fd5b506101e0612558565b60008061088a61189d565b905080158015906108a257508061089f61255d565b10155b91505b5090565b604080517f554e534146454c595f4d4f444946595f564f54455f54494d455f524f4c4500008152815190819003601e018120600080835260208301909352916108f89133918491905b50611b57565b60408051808201909152600f8152600080516020613d3883398151915260208201529015156109a85760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561096d578181015183820152602001610955565b50505050905090810190601f16801561099a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060015460408051808201909152601781527f564f54494e475f4f424a5f54494d455f544f4f5f42494700000000000000000060208201529067ffffffffffffffff808516680100000000000000009092041611610a4b5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506004805467ffffffffffffffff841667ffffffffffffffff19909116811790915560408051918252517ff2eb32f215d9f6d0f4ace97038141d2574af9f8c3bb509239254ace3d9c270009181900360200190a15050565b610aab61189d565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a4544000000000000000060208201529015610b305760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b50610b39612561565b60408051808201909152601081527f564f54494e475f494e49545f5043545300000000000000000000000000000000602082015267ffffffffffffffff8086169085161115610bcd5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5060408051808201909152601b81527f564f54494e475f494e49545f535550504f52545f544f4f5f42494700000000006020820152670de0b6b3a764000067ffffffffffffffff861610610c665760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5060408051808201909152601c81527f564f54494e475f494e49545f4f424a5f54494d455f544f4f5f42494700000000602082015267ffffffffffffffff80831690841611610cfa5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0396909616959095177bffffffffffffffff0000000000000000000000000000000000000000191660a060020a67ffffffffffffffff95861602179094556001805467ffffffffffffffff19908116938516939093176fffffffffffffffff0000000000000000191668010000000000000000928516929092029190911790556004805490911692909116919091179055565b604080517f554e534146454c595f4d4f444946595f564f54455f54494d455f524f4c4500008152905190819003601e01902081565b604080517f554e534146454c595f4d4f444946595f564f54455f54494d455f524f4c4500008152815190819003601e01812060008083526020830190935291610e329133918491906108f2565b60408051808201909152600f8152600080516020613d388339815191526020820152901515610ea65760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5060045460408051808201909152601a81527f564f54494e475f564f54455f54494d455f544f4f5f534d414c4c00000000000060208201529067ffffffffffffffff90811690841611610f3e5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506001805467ffffffffffffffff84166801000000000000000081026fffffffffffffffff0000000000000000199092169190911790915560408051918252517f776dcd10c15e7a1bd4fbb6c824d2a80fa8a40a3a6b401fddc678696b7fb06abe9181900360200190a15050565b6000610fb6611ca4565b600160a060020a03166304bf2a7f836040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611011578181015183820152602001610ff9565b50505050905090810190601f16801561103e5780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b15801561105d57600080fd5b505af1158015611071573d6000803e3d6000fd5b505050506040513d602081101561108757600080fd5b505192915050565b6000611099611ef4565b600160a060020a03166332f0a3b56040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156110d357600080fd5b505af11580156110e7573d6000803e3d6000fd5b505050506040513d60208110156110fd57600080fd5b505190505b90565b604080517f4d4f444946595f51554f52554d5f524f4c4500000000000000000000000000008152905190819003601201902081565b60045467ffffffffffffffff1681565b60035460408051808201909152600e8152600080516020613d58833981519152602082015260009184919082106111c65760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506000848152600260209081526040808320600160a060020a038716845260060190915290205460ff1691505b5092915050565b600080600080600080600080600060606000808c60035481106040805190810160405280600e8152602001600080516020613d588339815191528152509015156112895760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5060008e815260026020526040902091506112a382612629565b9c508160000160009054906101000a900460ff169b508160000160019054906101000a900467ffffffffffffffff169a508160000160099054906101000a900467ffffffffffffffff1699508160000160119054906101000a900467ffffffffffffffff1698508160010160009054906101000a900467ffffffffffffffff169750816002015496508160030154955081600401549450816005018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156113d25780601f106113a7576101008083540402835291602001916113d2565b820191906000526020600020905b8154815290600101906020018083116113b557829003601f168201915b505050505093506113e282612690565b9250505091939597999b90929496989a50565b604080517f4d4f444946595f51554f52554d5f524f4c450000000000000000000000000000815290519081900360120190206001546114419067ffffffffffffffff808516911661274b565b61144c338383611b57565b60408051808201909152600f8152600080516020613d3883398151915260208201529015156114c05760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5060005460408051808201909152601981527f564f54494e475f4348414e47455f51554f52554d5f504354530000000000000060208201529067ffffffffffffffff60a060020a909104811690851611156115605760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506001805467ffffffffffffffff851667ffffffffffffffff19909116811790915560408051918252517f3172f2e9273c729c2a47cc8bf7e7f18506e3e3035126d562602bd2155bc78a509181900360200190a1505050565b604080517f4d4f444946595f535550504f52545f524f4c45000000000000000000000000008152905190819003601301902081565b604080517f4d4f444946595f535550504f52545f524f4c4500000000000000000000000000815290519081900360130190206000546116419067ffffffffffffffff8085169160a060020a90041661274b565b61164c338383611b57565b60408051808201909152600f8152600080516020613d3883398151915260208201529015156116c05760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5060015460408051808201909152601a81527f564f54494e475f4348414e47455f535550504f52545f5043545300000000000060208201529067ffffffffffffffff808616911611156117585760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5060408051808201909152601a81527f564f54494e475f4348414e47455f535550505f544f4f5f4249470000000000006020820152670de0b6b3a764000067ffffffffffffffff8516106117f15760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506000805467ffffffffffffffff851660a060020a81027bffffffffffffffff0000000000000000000000000000000000000000199092169190911790915560408051918252517f903b617f7f36eb047a29b89d1bf7885fdae31d250c3320fccf11d045c11b396e9181900360200190a1505050565b50600190565b60006118987fd625496217aa6a3453eecb9c3489dc5a53e6c67b444329ea2b2cbc9ff547639b6127a6565b905090565b60006118987febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e6127a6565b60008060006118d684611867565b60408051808201909152601281527f5245434f5645525f444953414c4c4f5745440000000000000000000000000000602082015290151561195c5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5061196561108f565b9250611970836127ae565b60408051808201909152601a81527f5245434f5645525f5641554c545f4e4f545f434f4e545241435400000000000060208201529015156119f65760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b50600160a060020a0384161515611a475760405130319250600160a060020a0384169083156108fc029084906000818181858888f19350505050158015611a41573d6000803e3d6000fd5b50611b06565b5082611a62600160a060020a0382163063ffffffff6127d416565b9150611a7e600160a060020a038216848463ffffffff6128d416565b60408051808201909152601d81527f5245434f5645525f544f4b454e5f5452414e534645525f4641494c45440000006020820152901515611b045760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b505b83600160a060020a031683600160a060020a03167f596caf56044b55fb8c4ca640089bbc2b63cae3e978b851f5745cbb7c5b288e02846040518082815260200191505060405180910390a350505050565b600080611b6261087f565b1515611b715760009150611c9c565b611b79611ef4565b9050600160a060020a0381161515611b945760009150611c9c565b80600160a060020a031663fdef9106863087611baf8861294a565b60405163ffffffff861660e01b8152600160a060020a03808616600483019081529085166024830152604482018490526080606483019081528351608484015283519192909160a490910190602085019080838360005b83811015611c1e578181015183820152602001611c06565b50505050905090810190601f168015611c4b5780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b158015611c6d57600080fd5b505af1158015611c81573d6000803e3d6000fd5b505050506040513d6020811015611c9757600080fd5b505191505b509392505050565b600080611caf611ef4565b604080517fbe00bbd80000000000000000000000000000000000000000000000000000000081527fd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb60048201527fddbcfd564f642ab5627cf68b9b7d374fb4f8a36e941a75d89c87998cef03bd6160248201529051600160a060020a03929092169163be00bbd8916044808201926020929091908290030181600087803b15801561105d57600080fd5b60015468010000000000000000900467ffffffffffffffff1681565b60408051600080516020613d788339815191528152905190819003601101902081565b6000611dcf836040518080600080516020613d7883398151915281525060110190506040518091039020611dca612954565b611b57565b9392505050565b60035460408051808201909152600e8152600080516020613d5883398151915260208201526000918391908210611e525760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b50611e5c83612966565b91505b50919050565b60035460408051808201909152600e8152600080516020613d5883398151915260208201526000918491908210611ee15760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b50611eec8484612a3b565b949350505050565b60006118987f4172f0f7d2289153072b0a6ca36959e0cbe2efc3afe50fc81636caa96338137b6127a6565b60408051600080516020613d788339815191528152815190819003601101812060008083526020830190935290611f5a9033908390856108f2565b60408051808201909152600f8152600080516020613d388339815191526020820152901515611fce5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5061203986868080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f8c018190048102820181019092528a815294508a935089925082915084018382808284375060019450612b159350505050565b9695505050505050565b61204d3382611d98565b60408051808201909152601681527f564f54494e475f43414e5f4e4f545f464f52574152440000000000000000000060208201529015156120d35760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506120f08160206040519081016040528060008152506001612b15565b5050565b60015467ffffffffffffffff1681565b600060001961211161189d565b14905090565b60035481565b60035460408051808201909152600e8152600080516020613d588339815191526020820152849182106121955760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506121a08433612a3b565b60408051808201909152601381527f564f54494e475f43414e5f4e4f545f564f54450000000000000000000000000060208201529015156122265760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b508215806122535750600084815260026020526040812061224690612690565b600281111561225157fe5b145b60408051808201909152601381527f564f54494e475f43414e5f4e4f545f564f54450000000000000000000000000060208201529015156122d95760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506122e5848433612e09565b50505050565b60408051600080516020613d7883398151915281528151908190036011018120600080835260208301909352906123269033908390856108f2565b60408051808201909152600f8152600080516020613d38833981519152602082015290151561239a5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5061240488888080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f8e018190048102820181019092528c815294508c93508b92508291508401838280828437508b9450612b159350505050565b98975050505050505050565b60035460408051808201909152600e8152600080516020613d588339815191526020820152600091839190821061248c5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506000838152600260205260409020611e5c90612690565b60035460408051808201909152600e8152600080516020613d5883398151915260208201528291821061251c5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506120f08261308a565b60005460a060020a900467ffffffffffffffff1681565b600054600160a060020a031681565b670de0b6b3a764000081565b600190565b4390565b61256961189d565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a45440000000000000000602082015290156125ee5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506126276125fa61255d565b7febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e9063ffffffff61312616565b565b600154815460009161265f91610100900467ffffffffffffffff908116916801000000000000000090041663ffffffff61312a16565b67ffffffffffffffff166126716131c5565b67ffffffffffffffff1610801561268a5750815460ff16155b92915050565b600080600061269d6131c5565b60015485549193506126d391610100900467ffffffffffffffff908116916801000000000000000090041663ffffffff61312a16565b6004549091506126f69067ffffffffffffffff808416911663ffffffff6131d716565b67ffffffffffffffff168267ffffffffffffffff16101561271a5760009250612744565b8067ffffffffffffffff168267ffffffffffffffff16101561273f5760019250612744565b600292505b5050919050565b60408051600280825260608083018452926020830190803883390190505090508281600081518110151561277b57fe5b60209081029091010152805182908290600190811061279657fe5b6020908102909101015292915050565b5490565b5490565b600080600160a060020a03831615156127ca5760009150611e5f565b50506000903b1190565b60408051600160a060020a038316602480830191909152825180830390910181526044909101909152602081018051600160e060020a03167f70a0823100000000000000000000000000000000000000000000000000000000179052600090818061283f8684613278565b60408051808201909152601c81527f534146455f4552435f32305f42414c414e43455f524556455254454400000000602082015291935091508215156128ca5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5095945050505050565b60408051600160a060020a03841660248201526044808201849052825180830390910181526064909101909152602081018051600160e060020a03167fa9059cbb0000000000000000000000000000000000000000000000000000000017905260009061294185826132a9565b95945050505050565b8051602002815290565b60408051600081526020810190915290565b600081815260026020526040812080548290819060ff161561298b5760009350612a33565b61299483612629565b156129a25760009350612a33565b826002015491506129c08360030154836132f790919063ffffffff16565b83549091506129f1908390839071010000000000000000000000000000000000900467ffffffffffffffff16613385565b1515612a005760009350612a33565b60048301546001840154612a1f91849167ffffffffffffffff16613385565b1515612a2e5760009350612a33565b600193505b505050919050565b6000828152600260205260408120612a5281612629565b8015611eec5750600080548254604080517f4ee2cd7e000000000000000000000000000000000000000000000000000000008152600160a060020a038881166004830152690100000000000000000090930467ffffffffffffffff16602482015290519190921691634ee2cd7e91604480830192602092919082900301818787803b158015612ae057600080fd5b505af1158015612af4573d6000803e3d6000fd5b505050506040513d6020811015612b0a57600080fd5b505111949350505050565b6000806000806001612b256133c7565b60008054604080517f981b24d00000000000000000000000000000000000000000000000000000000081529490930367ffffffffffffffff811660048601529251929650600160a060020a03169263981b24d09260248083019360209383900390910190829087803b158015612b9a57600080fd5b505af1158015612bae573d6000803e3d6000fd5b505050506040513d6020811015612bc457600080fd5b505160408051808201909152601681527f564f54494e475f4e4f5f564f54494e475f504f57455200000000000000000000602082015290925060008311612c505760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b505060038054600181019091556000818152600260205260409020909350612c766131c5565b815468ffffffffffffffff00191661010067ffffffffffffffff928316021770ffffffffffffffff00000000000000000019166901000000000000000000858316021780835560005478ffffffffffffffff00000000000000000000000000000000001990911660a060020a909104821671010000000000000000000000000000000000021782556001805490830180549190921667ffffffffffffffff19909116179055600481018290558651612d3790600583019060208a0190613ca9565b5033600160a060020a0316847f4d72fe0577a3a3f7da968d7b892779dde102519c25527b29cf7054f245c791b9886040518080602001828103825283818151815260200191508051906020019080838360005b83811015612da2578181015183820152602001612d8a565b50505050905090810190601f168015612dcf5780820380516001836020036101000a031916815260200191505b509250505060405180910390a3848015612dee5750612dee8433612a3b565b15612dff57612dff84600133612e09565b5050509392505050565b60008381526002602090815260408083208354815483517f4ee2cd7e000000000000000000000000000000000000000000000000000000008152600160a060020a038881166004830152690100000000000000000090920467ffffffffffffffff166024820152935192959485949190921692634ee2cd7e9260448084019391929182900301818787803b158015612ea057600080fd5b505af1158015612eb4573d6000803e3d6000fd5b505050506040513d6020811015612eca57600080fd5b5051600160a060020a038516600090815260068501602052604090205490925060ff1690506001816002811115612efd57fe5b1415612f22576002830154612f18908363ffffffff6133d416565b6002840155612f51565b6002816002811115612f3057fe5b1415612f51576003830154612f4b908363ffffffff6133d416565b60038401555b8415612f9b576002830154612f6c908363ffffffff6132f716565b6002840155600160a060020a03841660009081526006840160205260409020805460ff19166001179055612fdb565b6003830154612fb0908363ffffffff6132f716565b6003840155600160a060020a03841660009081526006840160205260409020805460ff191660021790555b604080518615158152602081018490528151600160a060020a0387169289927fb34ee265e3d4f5ec4e8b52d59b2a9be8fceca2f274ebc080d8fba797fea9391f929081900390910190a3600161303084612690565b600281111561303b57fe5b141561308257604080518381529051600160a060020a0386169188917ffa539989fcfb5d8fa8c97a1102d1777a34c3543f0725fb8ab66109619bb9de189181900360200190a35b505050505050565b61309381612966565b60408051808201909152601681527f564f54494e475f43414e5f4e4f545f455845435554450000000000000000000060208201529015156131195760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5061312381613460565b50565b9055565b60408051808201909152601381527f4d41544836345f4144445f4f564552464c4f570000000000000000000000000060208201526000908383019067ffffffffffffffff8086169083161015611c9c5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b60006118986131d261355c565b613560565b60408051808201909152601481527f4d41544836345f5355425f554e444552464c4f570000000000000000000000006020820152600090819067ffffffffffffffff80861690851611156132705760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b505050900390565b6000806000806040516020818751602089018a5afa9250600083111561329d57805191505b50909590945092505050565b6000806040516020818551602087016000895af160008111156132ed573d80156132da57602081146132e3576132eb565b600193506132eb565b600183511493505b505b5090949350505050565b60408051808201909152601181527f4d4154485f4144445f4f564552464c4f5700000000000000000000000000000060208201526000908383019084821015611c9c5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b6000808315156133985760009150611c9c565b836133b186670de0b6b3a764000063ffffffff6135f916565b8115156133ba57fe5b0492909211949350505050565b60006118986131d261255d565b60408051808201909152601281527f4d4154485f5355425f554e444552464c4f57000000000000000000000000000060208201526000908190848411156132705760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b6000818152600260208181526040808420805460ff191660019081178255825195865260058201805491821615610100026000190190911694909404601f8101849004840286018301835292850183815290949361352b93919290919085018282801561350e5780601f106134e35761010080835404028352916020019161350e565b820191906000526020600020905b8154815290600101906020018083116134f157829003601f168201915b505060408051600081526020810190915286935091506136a49050565b5060405183907fbf8e2b108bb7c980e08903a8a46527699d5e84905a082d56dacb4150725c8cab90600090a2505050565b4290565b60408051808201909152601581527f55494e5436345f4e554d4245525f544f4f5f4249470000000000000000000000602082015260009067ffffffffffffffff8311156135f25760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5090919050565b60008083151561360c57600091506111f3565b5082820282848281151561361c57fe5b60408051808201909152601181527f4d4154485f4d554c5f4f564552464c4f5700000000000000000000000000000060208201529291900414611c9c5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b60606000806060806136b461087f565b60408051808201909152601481527f494e49545f4e4f545f494e495449414c495a4544000000000000000000000000602082015290151561373a5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b50600080613746611ef4565b915061375061186d565b905061375b8a610fac565b60408051808201909152601b81527f45564d52554e5f4558454355544f525f554e415641494c41424c4500000000006020820152909650600160a060020a03871615156137ed5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b506040516060602482019081528b5160848301528b517f279cea3500000000000000000000000000000000000000000000000000000000975087928d928d928d9282916044820191606481019160a490910190602089019080838360005b8381101561386357818101518382015260200161384b565b50505050905090810190601f1680156138905780820380516001836020036101000a031916815260200191505b50848103835286518152865160209182019188019080838360005b838110156138c35781810151838201526020016138ab565b50505050905090810190601f1680156138f05780820380516001836020036101000a031916815260200191505b508481038252855181528551602091820191808801910280838360005b8381101561392557818101518382015260200161390d565b50505050905001965050505050505060405160208183030381529060405290600160e060020a031916602082018051600160e060020a0383818316178352505050509350600080855160208701895af460405193508080156139e957603f3d11801561399e5760203d03806020883e86016040526139e3565b60e560020a62461bcd02865260206004870152601e60248701527f45564d52554e5f4558454355544f525f494e56414c49445f52455455524e00006044870152606486fd5b506139f2565b3d6000863e3d85fd5b505085600160a060020a03167f5229a5dba83a54ae8cb5b51bdd6de9474cacbe9dd332f5185f3a4f4f2e3f4ad98b8b8660405180806020018060200180602001848103845287818151815260200191508051906020019080838360005b83811015613a67578181015183820152602001613a4f565b50505050905090810190601f168015613a945780820380516001836020036101000a031916815260200191505b50848103835286518152865160209182019188019080838360005b83811015613ac7578181015183820152602001613aaf565b50505050905090810190601f168015613af45780820380516001836020036101000a031916815260200191505b50848103825285518152855160209182019187019080838360005b83811015613b27578181015183820152602001613b0f565b50505050905090810190601f168015613b545780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a282965081600160a060020a0316613b7a611ef4565b600160a060020a0316146040805190810160405280601f81526020017f45564d52554e5f50524f5445435445445f53544154455f4d4f44494649454400815250901515613c0c5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b5080613c1661186d565b60408051808201909152601f81527f45564d52554e5f50524f5445435445445f53544154455f4d4f4449464945440060208201529114613c9b5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561096d578181015183820152602001610955565b505050505050509392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613cea57805160ff1916838001178555613d17565b82800160010185558215613d17579182015b82811115613d17578251825591602001919060010190613cfc565b506108a5926111029250905b808211156108a55760008155600101613d2356004150505f415554485f4641494c45440000000000000000000000000000000000564f54494e475f4e4f5f564f54450000000000000000000000000000000000004352454154455f564f5445535f524f4c45000000000000000000000000000000a165627a7a7230582082c999c0a0c062fce716c0e3a28af142d305631b2e1d68a13e85310971bf04290029