{"file_path":"Voting.sol","creation_status":"success","source_code":"// Sources flattened with hardhat v2.6.8 https://hardhat.org\r\n\r\n// File @aragon/os/contracts/common/UnstructuredStorage.sol@v4.4.0\r\n\r\n/*\r\n * SPDX-License-Identifier:    MIT\r\n */\r\n\r\npragma solidity ^0.4.24;\r\n\r\n\r\nlibrary UnstructuredStorage {\r\n    function getStorageBool(bytes32 position) internal view returns (bool data) {\r\n        assembly { data := sload(position) }\r\n    }\r\n\r\n    function getStorageAddress(bytes32 position) internal view returns (address data) {\r\n        assembly { data := sload(position) }\r\n    }\r\n\r\n    function getStorageBytes32(bytes32 position) internal view returns (bytes32 data) {\r\n        assembly { data := sload(position) }\r\n    }\r\n\r\n    function getStorageUint256(bytes32 position) internal view returns (uint256 data) {\r\n        assembly { data := sload(position) }\r\n    }\r\n\r\n    function setStorageBool(bytes32 position, bool data) internal {\r\n        assembly { sstore(position, data) }\r\n    }\r\n\r\n    function setStorageAddress(bytes32 position, address data) internal {\r\n        assembly { sstore(position, data) }\r\n    }\r\n\r\n    function setStorageBytes32(bytes32 position, bytes32 data) internal {\r\n        assembly { sstore(position, data) }\r\n    }\r\n\r\n    function setStorageUint256(bytes32 position, uint256 data) internal {\r\n        assembly { sstore(position, data) }\r\n    }\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/acl/IACL.sol@v4.4.0\r\n\r\n/*\r\n * SPDX-License-Identifier:    MIT\r\n */\r\n\r\npragma solidity ^0.4.24;\r\n\r\n\r\ninterface IACL {\r\n    function initialize(address permissionsCreator) external;\r\n\r\n    // TODO: this should be external\r\n    // See https://github.com/ethereum/solidity/issues/4832\r\n    function hasPermission(address who, address where, bytes32 what, bytes how) public view returns (bool);\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/common/IVaultRecoverable.sol@v4.4.0\r\n\r\n/*\r\n * SPDX-License-Identifier:    MIT\r\n */\r\n\r\npragma solidity ^0.4.24;\r\n\r\n\r\ninterface IVaultRecoverable {\r\n    event RecoverToVault(address indexed vault, address indexed token, uint256 amount);\r\n\r\n    function transferToVault(address token) external;\r\n\r\n    function allowRecoverability(address token) external view returns (bool);\r\n    function getRecoveryVault() external view returns (address);\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/kernel/IKernel.sol@v4.4.0\r\n\r\n/*\r\n * SPDX-License-Identifier:    MIT\r\n */\r\n\r\npragma solidity ^0.4.24;\r\n\r\n\r\ninterface IKernelEvents {\r\n    event SetApp(bytes32 indexed namespace, bytes32 indexed appId, address app);\r\n}\r\n\r\n\r\n// This should be an interface, but interfaces can't inherit yet :(\r\ncontract IKernel is IKernelEvents, IVaultRecoverable {\r\n    function acl() public view returns (IACL);\r\n    function hasPermission(address who, address where, bytes32 what, bytes how) public view returns (bool);\r\n\r\n    function setApp(bytes32 namespace, bytes32 appId, address app) public;\r\n    function getApp(bytes32 namespace, bytes32 appId) public view returns (address);\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/apps/AppStorage.sol@v4.4.0\r\n\r\n/*\r\n * SPDX-License-Identifier:    MIT\r\n */\r\n\r\npragma solidity ^0.4.24;\r\n\r\n\r\ncontract AppStorage {\r\n    using UnstructuredStorage for bytes32;\r\n\r\n    /* Hardcoded constants to save gas\r\n    bytes32 internal constant KERNEL_POSITION = keccak256(\"aragonOS.appStorage.kernel\");\r\n    bytes32 internal constant APP_ID_POSITION = keccak256(\"aragonOS.appStorage.appId\");\r\n    */\r\n    bytes32 internal constant KERNEL_POSITION = 0x4172f0f7d2289153072b0a6ca36959e0cbe2efc3afe50fc81636caa96338137b;\r\n    bytes32 internal constant APP_ID_POSITION = 0xd625496217aa6a3453eecb9c3489dc5a53e6c67b444329ea2b2cbc9ff547639b;\r\n\r\n    function kernel() public view returns (IKernel) {\r\n        return IKernel(KERNEL_POSITION.getStorageAddress());\r\n    }\r\n\r\n    function appId() public view returns (bytes32) {\r\n        return APP_ID_POSITION.getStorageBytes32();\r\n    }\r\n\r\n    function setKernel(IKernel _kernel) internal {\r\n        KERNEL_POSITION.setStorageAddress(address(_kernel));\r\n    }\r\n\r\n    function setAppId(bytes32 _appId) internal {\r\n        APP_ID_POSITION.setStorageBytes32(_appId);\r\n    }\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/acl/ACLSyntaxSugar.sol@v4.4.0\r\n\r\n/*\r\n * SPDX-License-Identifier:    MIT\r\n */\r\n\r\npragma solidity ^0.4.24;\r\n\r\n\r\ncontract ACLSyntaxSugar {\r\n    function arr() internal pure returns (uint256[]) {\r\n        return new uint256[](0);\r\n    }\r\n\r\n    function arr(bytes32 _a) internal pure returns (uint256[] r) {\r\n        return arr(uint256(_a));\r\n    }\r\n\r\n    function arr(bytes32 _a, bytes32 _b) internal pure returns (uint256[] r) {\r\n        return arr(uint256(_a), uint256(_b));\r\n    }\r\n\r\n    function arr(address _a) internal pure returns (uint256[] r) {\r\n        return arr(uint256(_a));\r\n    }\r\n\r\n    function arr(address _a, address _b) internal pure returns (uint256[] r) {\r\n        return arr(uint256(_a), uint256(_b));\r\n    }\r\n\r\n    function arr(address _a, uint256 _b, uint256 _c) internal pure returns (uint256[] r) {\r\n        return arr(uint256(_a), _b, _c);\r\n    }\r\n\r\n    function arr(address _a, uint256 _b, uint256 _c, uint256 _d) internal pure returns (uint256[] r) {\r\n        return arr(uint256(_a), _b, _c, _d);\r\n    }\r\n\r\n    function arr(address _a, uint256 _b) internal pure returns (uint256[] r) {\r\n        return arr(uint256(_a), uint256(_b));\r\n    }\r\n\r\n    function arr(address _a, address _b, uint256 _c, uint256 _d, uint256 _e) internal pure returns (uint256[] r) {\r\n        return arr(uint256(_a), uint256(_b), _c, _d, _e);\r\n    }\r\n\r\n    function arr(address _a, address _b, address _c) internal pure returns (uint256[] r) {\r\n        return arr(uint256(_a), uint256(_b), uint256(_c));\r\n    }\r\n\r\n    function arr(address _a, address _b, uint256 _c) internal pure returns (uint256[] r) {\r\n        return arr(uint256(_a), uint256(_b), uint256(_c));\r\n    }\r\n\r\n    function arr(uint256 _a) internal pure returns (uint256[] r) {\r\n        r = new uint256[](1);\r\n        r[0] = _a;\r\n    }\r\n\r\n    function arr(uint256 _a, uint256 _b) internal pure returns (uint256[] r) {\r\n        r = new uint256[](2);\r\n        r[0] = _a;\r\n        r[1] = _b;\r\n    }\r\n\r\n    function arr(uint256 _a, uint256 _b, uint256 _c) internal pure returns (uint256[] r) {\r\n        r = new uint256[](3);\r\n        r[0] = _a;\r\n        r[1] = _b;\r\n        r[2] = _c;\r\n    }\r\n\r\n    function arr(uint256 _a, uint256 _b, uint256 _c, uint256 _d) internal pure returns (uint256[] r) {\r\n        r = new uint256[](4);\r\n        r[0] = _a;\r\n        r[1] = _b;\r\n        r[2] = _c;\r\n        r[3] = _d;\r\n    }\r\n\r\n    function arr(uint256 _a, uint256 _b, uint256 _c, uint256 _d, uint256 _e) internal pure returns (uint256[] r) {\r\n        r = new uint256[](5);\r\n        r[0] = _a;\r\n        r[1] = _b;\r\n        r[2] = _c;\r\n        r[3] = _d;\r\n        r[4] = _e;\r\n    }\r\n}\r\n\r\n\r\ncontract ACLHelpers {\r\n    function decodeParamOp(uint256 _x) internal pure returns (uint8 b) {\r\n        return uint8(_x >> (8 * 30));\r\n    }\r\n\r\n    function decodeParamId(uint256 _x) internal pure returns (uint8 b) {\r\n        return uint8(_x >> (8 * 31));\r\n    }\r\n\r\n    function decodeParamsList(uint256 _x) internal pure returns (uint32 a, uint32 b, uint32 c) {\r\n        a = uint32(_x);\r\n        b = uint32(_x >> (8 * 4));\r\n        c = uint32(_x >> (8 * 8));\r\n    }\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/common/Uint256Helpers.sol@v4.4.0\r\n\r\npragma solidity ^0.4.24;\r\n\r\n\r\nlibrary Uint256Helpers {\r\n    uint256 private constant MAX_UINT64 = uint64(-1);\r\n\r\n    string private constant ERROR_NUMBER_TOO_BIG = \"UINT64_NUMBER_TOO_BIG\";\r\n\r\n    function toUint64(uint256 a) internal pure returns (uint64) {\r\n        require(a <= MAX_UINT64, ERROR_NUMBER_TOO_BIG);\r\n        return uint64(a);\r\n    }\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/common/TimeHelpers.sol@v4.4.0\r\n\r\n/*\r\n * SPDX-License-Identifier:    MIT\r\n */\r\n\r\npragma solidity ^0.4.24;\r\n\r\ncontract TimeHelpers {\r\n    using Uint256Helpers for uint256;\r\n\r\n    /**\r\n    * @dev Returns the current block number.\r\n    *      Using a function rather than `block.number` allows us to easily mock the block number in\r\n    *      tests.\r\n    */\r\n    function getBlockNumber() internal view returns (uint256) {\r\n        return block.number;\r\n    }\r\n\r\n    /**\r\n    * @dev Returns the current block number, converted to uint64.\r\n    *      Using a function rather than `block.number` allows us to easily mock the block number in\r\n    *      tests.\r\n    */\r\n    function getBlockNumber64() internal view returns (uint64) {\r\n        return getBlockNumber().toUint64();\r\n    }\r\n\r\n    /**\r\n    * @dev Returns the current timestamp.\r\n    *      Using a function rather than `block.timestamp` allows us to easily mock it in\r\n    *      tests.\r\n    */\r\n    function getTimestamp() internal view returns (uint256) {\r\n        return block.timestamp; // solium-disable-line security/no-block-members\r\n    }\r\n\r\n    /**\r\n    * @dev Returns the current timestamp, converted to uint64.\r\n    *      Using a function rather than `block.timestamp` allows us to easily mock it in\r\n    *      tests.\r\n    */\r\n    function getTimestamp64() internal view returns (uint64) {\r\n        return getTimestamp().toUint64();\r\n    }\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/common/Initializable.sol@v4.4.0\r\n\r\n/*\r\n * SPDX-License-Identifier:    MIT\r\n */\r\n\r\npragma solidity ^0.4.24;\r\n\r\n\r\ncontract Initializable is TimeHelpers {\r\n    using UnstructuredStorage for bytes32;\r\n\r\n    // keccak256(\"aragonOS.initializable.initializationBlock\")\r\n    bytes32 internal constant INITIALIZATION_BLOCK_POSITION = 0xebb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e;\r\n\r\n    string private constant ERROR_ALREADY_INITIALIZED = \"INIT_ALREADY_INITIALIZED\";\r\n    string private constant ERROR_NOT_INITIALIZED = \"INIT_NOT_INITIALIZED\";\r\n\r\n    modifier onlyInit {\r\n        require(getInitializationBlock() == 0, ERROR_ALREADY_INITIALIZED);\r\n        _;\r\n    }\r\n\r\n    modifier isInitialized {\r\n        require(hasInitialized(), ERROR_NOT_INITIALIZED);\r\n        _;\r\n    }\r\n\r\n    /**\r\n    * @return Block number in which the contract was initialized\r\n    */\r\n    function getInitializationBlock() public view returns (uint256) {\r\n        return INITIALIZATION_BLOCK_POSITION.getStorageUint256();\r\n    }\r\n\r\n    /**\r\n    * @return Whether the contract has been initialized by the time of the current block\r\n    */\r\n    function hasInitialized() public view returns (bool) {\r\n        uint256 initializationBlock = getInitializationBlock();\r\n        return initializationBlock != 0 && getBlockNumber() >= initializationBlock;\r\n    }\r\n\r\n    /**\r\n    * @dev Function to be called by top level contract after initialization has finished.\r\n    */\r\n    function initialized() internal onlyInit {\r\n        INITIALIZATION_BLOCK_POSITION.setStorageUint256(getBlockNumber());\r\n    }\r\n\r\n    /**\r\n    * @dev Function to be called by top level contract after initialization to enable the contract\r\n    *      at a future block number rather than immediately.\r\n    */\r\n    function initializedAt(uint256 _blockNumber) internal onlyInit {\r\n        INITIALIZATION_BLOCK_POSITION.setStorageUint256(_blockNumber);\r\n    }\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/common/Petrifiable.sol@v4.4.0\r\n\r\n/*\r\n * SPDX-License-Identifier:    MIT\r\n */\r\n\r\npragma solidity ^0.4.24;\r\n\r\ncontract Petrifiable is Initializable {\r\n    // Use block UINT256_MAX (which should be never) as the initializable date\r\n    uint256 internal constant PETRIFIED_BLOCK = uint256(-1);\r\n\r\n    function isPetrified() public view returns (bool) {\r\n        return getInitializationBlock() == PETRIFIED_BLOCK;\r\n    }\r\n\r\n    /**\r\n    * @dev Function to be called by top level contract to prevent being initialized.\r\n    *      Useful for freezing base contracts when they're used behind proxies.\r\n    */\r\n    function petrify() internal onlyInit {\r\n        initializedAt(PETRIFIED_BLOCK);\r\n    }\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/common/Autopetrified.sol@v4.4.0\r\n\r\n/*\r\n * SPDX-License-Identifier:    MIT\r\n */\r\n\r\npragma solidity ^0.4.24;\r\n\r\ncontract Autopetrified is Petrifiable {\r\n    constructor() public {\r\n        // Immediately petrify base (non-proxy) instances of inherited contracts on deploy.\r\n        // This renders them uninitializable (and unusable without a proxy).\r\n        petrify();\r\n    }\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/common/ConversionHelpers.sol@v4.4.0\r\n\r\npragma solidity ^0.4.24;\r\n\r\n\r\nlibrary ConversionHelpers {\r\n    string private constant ERROR_IMPROPER_LENGTH = \"CONVERSION_IMPROPER_LENGTH\";\r\n\r\n    function dangerouslyCastUintArrayToBytes(uint256[] memory _input) internal pure returns (bytes memory output) {\r\n        // Force cast the uint256[] into a bytes array, by overwriting its length\r\n        // Note that the bytes array doesn't need to be initialized as we immediately overwrite it\r\n        // with the input and a new length. The input becomes invalid from this point forward.\r\n        uint256 byteLength = _input.length * 32;\r\n        assembly {\r\n            output := _input\r\n            mstore(output, byteLength)\r\n        }\r\n    }\r\n\r\n    function dangerouslyCastBytesToUintArray(bytes memory _input) internal pure returns (uint256[] memory output) {\r\n        // Force cast the bytes array into a uint256[], by overwriting its length\r\n        // Note that the uint256[] doesn't need to be initialized as we immediately overwrite it\r\n        // with the input and a new length. The input becomes invalid from this point forward.\r\n        uint256 intsLength = _input.length / 32;\r\n        require(_input.length == intsLength * 32, ERROR_IMPROPER_LENGTH);\r\n\r\n        assembly {\r\n            output := _input\r\n            mstore(output, intsLength)\r\n        }\r\n    }\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/common/ReentrancyGuard.sol@v4.4.0\r\n\r\n/*\r\n * SPDX-License-Identifier:    MIT\r\n */\r\n\r\npragma solidity ^0.4.24;\r\n\r\ncontract ReentrancyGuard {\r\n    using UnstructuredStorage for bytes32;\r\n\r\n    /* Hardcoded constants to save gas\r\n    bytes32 internal constant REENTRANCY_MUTEX_POSITION = keccak256(\"aragonOS.reentrancyGuard.mutex\");\r\n    */\r\n    bytes32 private constant REENTRANCY_MUTEX_POSITION = 0xe855346402235fdd185c890e68d2c4ecad599b88587635ee285bce2fda58dacb;\r\n\r\n    string private constant ERROR_REENTRANT = \"REENTRANCY_REENTRANT_CALL\";\r\n\r\n    modifier nonReentrant() {\r\n        // Ensure mutex is unlocked\r\n        require(!REENTRANCY_MUTEX_POSITION.getStorageBool(), ERROR_REENTRANT);\r\n\r\n        // Lock mutex before function call\r\n        REENTRANCY_MUTEX_POSITION.setStorageBool(true);\r\n\r\n        // Perform function call\r\n        _;\r\n\r\n        // Unlock mutex after function call\r\n        REENTRANCY_MUTEX_POSITION.setStorageBool(false);\r\n    }\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/lib/token/ERC20.sol@v4.4.0\r\n\r\n// See https://github.com/OpenZeppelin/openzeppelin-solidity/blob/a9f910d34f0ab33a1ae5e714f69f9596a02b4d91/contracts/token/ERC20/ERC20.sol\r\n\r\npragma solidity ^0.4.24;\r\n\r\n\r\n/**\r\n * @title ERC20 interface\r\n * @dev see https://github.com/ethereum/EIPs/issues/20\r\n */\r\ncontract ERC20 {\r\n    function totalSupply() public view returns (uint256);\r\n\r\n    function balanceOf(address _who) public view returns (uint256);\r\n\r\n    function allowance(address _owner, address _spender)\r\n        public view returns (uint256);\r\n\r\n    function transfer(address _to, uint256 _value) public returns (bool);\r\n\r\n    function approve(address _spender, uint256 _value)\r\n        public returns (bool);\r\n\r\n    function transferFrom(address _from, address _to, uint256 _value)\r\n        public returns (bool);\r\n\r\n    event Transfer(\r\n        address indexed from,\r\n        address indexed to,\r\n        uint256 value\r\n    );\r\n\r\n    event Approval(\r\n        address indexed owner,\r\n        address indexed spender,\r\n        uint256 value\r\n    );\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/common/EtherTokenConstant.sol@v4.4.0\r\n\r\n/*\r\n * SPDX-License-Identifier:    MIT\r\n */\r\n\r\npragma solidity ^0.4.24;\r\n\r\n\r\n// aragonOS and aragon-apps rely on address(0) to denote native ETH, in\r\n// contracts where both tokens and ETH are accepted\r\ncontract EtherTokenConstant {\r\n    address internal constant ETH = address(0);\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/common/IsContract.sol@v4.4.0\r\n\r\n/*\r\n * SPDX-License-Identifier:    MIT\r\n */\r\n\r\npragma solidity ^0.4.24;\r\n\r\n\r\ncontract IsContract {\r\n    /*\r\n    * NOTE: this should NEVER be used for authentication\r\n    * (see pitfalls: https://github.com/fergarrui/ethereum-security/tree/master/contracts/extcodesize).\r\n    *\r\n    * This is only intended to be used as a sanity check that an address is actually a contract,\r\n    * RATHER THAN an address not being a contract.\r\n    */\r\n    function isContract(address _target) internal view returns (bool) {\r\n        if (_target == address(0)) {\r\n            return false;\r\n        }\r\n\r\n        uint256 size;\r\n        assembly { size := extcodesize(_target) }\r\n        return size > 0;\r\n    }\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/common/SafeERC20.sol@v4.4.0\r\n\r\n// Inspired by AdEx (https://github.com/AdExNetwork/adex-protocol-eth/blob/b9df617829661a7518ee10f4cb6c4108659dd6d5/contracts/libs/SafeERC20.sol)\r\n// and 0x (https://github.com/0xProject/0x-monorepo/blob/737d1dc54d72872e24abce5a1dbe1b66d35fa21a/contracts/protocol/contracts/protocol/AssetProxy/ERC20Proxy.sol#L143)\r\n\r\npragma solidity ^0.4.24;\r\n\r\nlibrary SafeERC20 {\r\n    // Before 0.5, solidity has a mismatch between `address.transfer()` and `token.transfer()`:\r\n    // https://github.com/ethereum/solidity/issues/3544\r\n    bytes4 private constant TRANSFER_SELECTOR = 0xa9059cbb;\r\n\r\n    string private constant ERROR_TOKEN_BALANCE_REVERTED = \"SAFE_ERC_20_BALANCE_REVERTED\";\r\n    string private constant ERROR_TOKEN_ALLOWANCE_REVERTED = \"SAFE_ERC_20_ALLOWANCE_REVERTED\";\r\n\r\n    function invokeAndCheckSuccess(address _addr, bytes memory _calldata)\r\n        private\r\n        returns (bool)\r\n    {\r\n        bool ret;\r\n        assembly {\r\n            let ptr := mload(0x40)    // free memory pointer\r\n\r\n            let success := call(\r\n                gas,                  // forward all gas\r\n                _addr,                // address\r\n                0,                    // no value\r\n                add(_calldata, 0x20), // calldata start\r\n                mload(_calldata),     // calldata length\r\n                ptr,                  // write output over free memory\r\n                0x20                  // uint256 return\r\n            )\r\n\r\n            if gt(success, 0) {\r\n                // Check number of bytes returned from last function call\r\n                switch returndatasize\r\n\r\n                // No bytes returned: assume success\r\n                case 0 {\r\n                    ret := 1\r\n                }\r\n\r\n                // 32 bytes returned: check if non-zero\r\n                case 0x20 {\r\n                    // Only return success if returned data was true\r\n                    // Already have output in ptr\r\n                    ret := eq(mload(ptr), 1)\r\n                }\r\n\r\n                // Not sure what was returned: don't mark as success\r\n                default { }\r\n            }\r\n        }\r\n        return ret;\r\n    }\r\n\r\n    function staticInvoke(address _addr, bytes memory _calldata)\r\n        private\r\n        view\r\n        returns (bool, uint256)\r\n    {\r\n        bool success;\r\n        uint256 ret;\r\n        assembly {\r\n            let ptr := mload(0x40)    // free memory pointer\r\n\r\n            success := staticcall(\r\n                gas,                  // forward all gas\r\n                _addr,                // address\r\n                add(_calldata, 0x20), // calldata start\r\n                mload(_calldata),     // calldata length\r\n                ptr,                  // write output over free memory\r\n                0x20                  // uint256 return\r\n            )\r\n\r\n            if gt(success, 0) {\r\n                ret := mload(ptr)\r\n            }\r\n        }\r\n        return (success, ret);\r\n    }\r\n\r\n    /**\r\n    * @dev Same as a standards-compliant ERC20.transfer() that never reverts (returns false).\r\n    *      Note that this makes an external call to the token.\r\n    */\r\n    function safeTransfer(ERC20 _token, address _to, uint256 _amount) internal returns (bool) {\r\n        bytes memory transferCallData = abi.encodeWithSelector(\r\n            TRANSFER_SELECTOR,\r\n            _to,\r\n            _amount\r\n        );\r\n        return invokeAndCheckSuccess(_token, transferCallData);\r\n    }\r\n\r\n    /**\r\n    * @dev Same as a standards-compliant ERC20.transferFrom() that never reverts (returns false).\r\n    *      Note that this makes an external call to the token.\r\n    */\r\n    function safeTransferFrom(ERC20 _token, address _from, address _to, uint256 _amount) internal returns (bool) {\r\n        bytes memory transferFromCallData = abi.encodeWithSelector(\r\n            _token.transferFrom.selector,\r\n            _from,\r\n            _to,\r\n            _amount\r\n        );\r\n        return invokeAndCheckSuccess(_token, transferFromCallData);\r\n    }\r\n\r\n    /**\r\n    * @dev Same as a standards-compliant ERC20.approve() that never reverts (returns false).\r\n    *      Note that this makes an external call to the token.\r\n    */\r\n    function safeApprove(ERC20 _token, address _spender, uint256 _amount) internal returns (bool) {\r\n        bytes memory approveCallData = abi.encodeWithSelector(\r\n            _token.approve.selector,\r\n            _spender,\r\n            _amount\r\n        );\r\n        return invokeAndCheckSuccess(_token, approveCallData);\r\n    }\r\n\r\n    /**\r\n    * @dev Static call into ERC20.balanceOf().\r\n    * Reverts if the call fails for some reason (should never fail).\r\n    */\r\n    function staticBalanceOf(ERC20 _token, address _owner) internal view returns (uint256) {\r\n        bytes memory balanceOfCallData = abi.encodeWithSelector(\r\n            _token.balanceOf.selector,\r\n            _owner\r\n        );\r\n\r\n        (bool success, uint256 tokenBalance) = staticInvoke(_token, balanceOfCallData);\r\n        require(success, ERROR_TOKEN_BALANCE_REVERTED);\r\n\r\n        return tokenBalance;\r\n    }\r\n\r\n    /**\r\n    * @dev Static call into ERC20.allowance().\r\n    * Reverts if the call fails for some reason (should never fail).\r\n    */\r\n    function staticAllowance(ERC20 _token, address _owner, address _spender) internal view returns (uint256) {\r\n        bytes memory allowanceCallData = abi.encodeWithSelector(\r\n            _token.allowance.selector,\r\n            _owner,\r\n            _spender\r\n        );\r\n\r\n        (bool success, uint256 allowance) = staticInvoke(_token, allowanceCallData);\r\n        require(success, ERROR_TOKEN_ALLOWANCE_REVERTED);\r\n\r\n        return allowance;\r\n    }\r\n\r\n    /**\r\n    * @dev Static call into ERC20.totalSupply().\r\n    * Reverts if the call fails for some reason (should never fail).\r\n    */\r\n    function staticTotalSupply(ERC20 _token) internal view returns (uint256) {\r\n        bytes memory totalSupplyCallData = abi.encodeWithSelector(_token.totalSupply.selector);\r\n\r\n        (bool success, uint256 totalSupply) = staticInvoke(_token, totalSupplyCallData);\r\n        require(success, ERROR_TOKEN_ALLOWANCE_REVERTED);\r\n\r\n        return totalSupply;\r\n    }\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/common/VaultRecoverable.sol@v4.4.0\r\n\r\n/*\r\n * SPDX-License-Identifier:    MIT\r\n */\r\n\r\npragma solidity ^0.4.24;\r\n\r\n\r\n\r\n\r\n\r\ncontract VaultRecoverable is IVaultRecoverable, EtherTokenConstant, IsContract {\r\n    using SafeERC20 for ERC20;\r\n\r\n    string private constant ERROR_DISALLOWED = \"RECOVER_DISALLOWED\";\r\n    string private constant ERROR_VAULT_NOT_CONTRACT = \"RECOVER_VAULT_NOT_CONTRACT\";\r\n    string private constant ERROR_TOKEN_TRANSFER_FAILED = \"RECOVER_TOKEN_TRANSFER_FAILED\";\r\n\r\n    /**\r\n     * @notice Send funds to recovery Vault. This contract should never receive funds,\r\n     *         but in case it does, this function allows one to recover them.\r\n     * @param _token Token balance to be sent to recovery vault.\r\n     */\r\n    function transferToVault(address _token) external {\r\n        require(allowRecoverability(_token), ERROR_DISALLOWED);\r\n        address vault = getRecoveryVault();\r\n        require(isContract(vault), ERROR_VAULT_NOT_CONTRACT);\r\n\r\n        uint256 balance;\r\n        if (_token == ETH) {\r\n            balance = address(this).balance;\r\n            vault.transfer(balance);\r\n        } else {\r\n            ERC20 token = ERC20(_token);\r\n            balance = token.staticBalanceOf(this);\r\n            require(token.safeTransfer(vault, balance), ERROR_TOKEN_TRANSFER_FAILED);\r\n        }\r\n\r\n        emit RecoverToVault(vault, _token, balance);\r\n    }\r\n\r\n    /**\r\n    * @dev By default deriving from AragonApp makes it recoverable\r\n    * @param token Token address that would be recovered\r\n    * @return bool whether the app allows the recovery\r\n    */\r\n    function allowRecoverability(address token) public view returns (bool) {\r\n        return true;\r\n    }\r\n\r\n    // Cast non-implemented interface to be public so we can use it internally\r\n    function getRecoveryVault() public view returns (address);\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/evmscript/IEVMScriptExecutor.sol@v4.4.0\r\n\r\n/*\r\n * SPDX-License-Identifier:    MIT\r\n */\r\n\r\npragma solidity ^0.4.24;\r\n\r\n\r\ninterface IEVMScriptExecutor {\r\n    function execScript(bytes script, bytes input, address[] blacklist) external returns (bytes);\r\n    function executorType() external pure returns (bytes32);\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/evmscript/IEVMScriptRegistry.sol@v4.4.0\r\n\r\n/*\r\n * SPDX-License-Identifier:    MIT\r\n */\r\n\r\npragma solidity ^0.4.24;\r\n\r\ncontract EVMScriptRegistryConstants {\r\n    /* Hardcoded constants to save gas\r\n    bytes32 internal constant EVMSCRIPT_REGISTRY_APP_ID = apmNamehash(\"evmreg\");\r\n    */\r\n    bytes32 internal constant EVMSCRIPT_REGISTRY_APP_ID = 0xddbcfd564f642ab5627cf68b9b7d374fb4f8a36e941a75d89c87998cef03bd61;\r\n}\r\n\r\n\r\ninterface IEVMScriptRegistry {\r\n    function addScriptExecutor(IEVMScriptExecutor executor) external returns (uint id);\r\n    function disableScriptExecutor(uint256 executorId) external;\r\n\r\n    // TODO: this should be external\r\n    // See https://github.com/ethereum/solidity/issues/4832\r\n    function getScriptExecutor(bytes script) public view returns (IEVMScriptExecutor);\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/kernel/KernelConstants.sol@v4.4.0\r\n\r\n/*\r\n * SPDX-License-Identifier:    MIT\r\n */\r\n\r\npragma solidity ^0.4.24;\r\n\r\n\r\ncontract KernelAppIds {\r\n    /* Hardcoded constants to save gas\r\n    bytes32 internal constant KERNEL_CORE_APP_ID = apmNamehash(\"kernel\");\r\n    bytes32 internal constant KERNEL_DEFAULT_ACL_APP_ID = apmNamehash(\"acl\");\r\n    bytes32 internal constant KERNEL_DEFAULT_VAULT_APP_ID = apmNamehash(\"vault\");\r\n    */\r\n    bytes32 internal constant KERNEL_CORE_APP_ID = 0x3b4bf6bf3ad5000ecf0f989d5befde585c6860fea3e574a4fab4c49d1c177d9c;\r\n    bytes32 internal constant KERNEL_DEFAULT_ACL_APP_ID = 0xe3262375f45a6e2026b7e7b18c2b807434f2508fe1a2a3dfb493c7df8f4aad6a;\r\n    bytes32 internal constant KERNEL_DEFAULT_VAULT_APP_ID = 0x7e852e0fcfce6551c13800f1e7476f982525c2b5277ba14b24339c68416336d1;\r\n}\r\n\r\n\r\ncontract KernelNamespaceConstants {\r\n    /* Hardcoded constants to save gas\r\n    bytes32 internal constant KERNEL_CORE_NAMESPACE = keccak256(\"core\");\r\n    bytes32 internal constant KERNEL_APP_BASES_NAMESPACE = keccak256(\"base\");\r\n    bytes32 internal constant KERNEL_APP_ADDR_NAMESPACE = keccak256(\"app\");\r\n    */\r\n    bytes32 internal constant KERNEL_CORE_NAMESPACE = 0xc681a85306374a5ab27f0bbc385296a54bcd314a1948b6cf61c4ea1bc44bb9f8;\r\n    bytes32 internal constant KERNEL_APP_BASES_NAMESPACE = 0xf1f3eb40f5bc1ad1344716ced8b8a0431d840b5783aea1fd01786bc26f35ac0f;\r\n    bytes32 internal constant KERNEL_APP_ADDR_NAMESPACE = 0xd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb;\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/evmscript/EVMScriptRunner.sol@v4.4.0\r\n\r\n/*\r\n * SPDX-License-Identifier:    MIT\r\n */\r\n\r\npragma solidity ^0.4.24;\r\n\r\n\r\n\r\n\r\ncontract EVMScriptRunner is AppStorage, Initializable, EVMScriptRegistryConstants, KernelNamespaceConstants {\r\n    string private constant ERROR_EXECUTOR_UNAVAILABLE = \"EVMRUN_EXECUTOR_UNAVAILABLE\";\r\n    string private constant ERROR_PROTECTED_STATE_MODIFIED = \"EVMRUN_PROTECTED_STATE_MODIFIED\";\r\n\r\n    /* This is manually crafted in assembly\r\n    string private constant ERROR_EXECUTOR_INVALID_RETURN = \"EVMRUN_EXECUTOR_INVALID_RETURN\";\r\n    */\r\n\r\n    event ScriptResult(address indexed executor, bytes script, bytes input, bytes returnData);\r\n\r\n    function getEVMScriptExecutor(bytes _script) public view returns (IEVMScriptExecutor) {\r\n        return IEVMScriptExecutor(getEVMScriptRegistry().getScriptExecutor(_script));\r\n    }\r\n\r\n    function getEVMScriptRegistry() public view returns (IEVMScriptRegistry) {\r\n        address registryAddr = kernel().getApp(KERNEL_APP_ADDR_NAMESPACE, EVMSCRIPT_REGISTRY_APP_ID);\r\n        return IEVMScriptRegistry(registryAddr);\r\n    }\r\n\r\n    function runScript(bytes _script, bytes _input, address[] _blacklist)\r\n        internal\r\n        isInitialized\r\n        protectState\r\n        returns (bytes)\r\n    {\r\n        IEVMScriptExecutor executor = getEVMScriptExecutor(_script);\r\n        require(address(executor) != address(0), ERROR_EXECUTOR_UNAVAILABLE);\r\n\r\n        bytes4 sig = executor.execScript.selector;\r\n        bytes memory data = abi.encodeWithSelector(sig, _script, _input, _blacklist);\r\n\r\n        bytes memory output;\r\n        assembly {\r\n            let success := delegatecall(\r\n                gas,                // forward all gas\r\n                executor,           // address\r\n                add(data, 0x20),    // calldata start\r\n                mload(data),        // calldata length\r\n                0,                  // don't write output (we'll handle this ourselves)\r\n                0                   // don't write output\r\n            )\r\n\r\n            output := mload(0x40) // free mem ptr get\r\n\r\n            switch success\r\n            case 0 {\r\n                // If the call errored, forward its full error data\r\n                returndatacopy(output, 0, returndatasize)\r\n                revert(output, returndatasize)\r\n            }\r\n            default {\r\n                switch gt(returndatasize, 0x3f)\r\n                case 0 {\r\n                    // Need at least 0x40 bytes returned for properly ABI-encoded bytes values,\r\n                    // revert with \"EVMRUN_EXECUTOR_INVALID_RETURN\"\r\n                    // See remix: doing a `revert(\"EVMRUN_EXECUTOR_INVALID_RETURN\")` always results in\r\n                    // this memory layout\r\n                    mstore(output, 0x08c379a000000000000000000000000000000000000000000000000000000000)         // error identifier\r\n                    mstore(add(output, 0x04), 0x0000000000000000000000000000000000000000000000000000000000000020) // starting offset\r\n                    mstore(add(output, 0x24), 0x000000000000000000000000000000000000000000000000000000000000001e) // reason length\r\n                    mstore(add(output, 0x44), 0x45564d52554e5f4558454355544f525f494e56414c49445f52455455524e0000) // reason\r\n\r\n                    revert(output, 100) // 100 = 4 + 3 * 32 (error identifier + 3 words for the ABI encoded error)\r\n                }\r\n                default {\r\n                    // Copy result\r\n                    //\r\n                    // Needs to perform an ABI decode for the expected `bytes` return type of\r\n                    // `executor.execScript()` as solidity will automatically ABI encode the returned bytes as:\r\n                    //    [ position of the first dynamic length return value = 0x20 (32 bytes) ]\r\n                    //    [ output length (32 bytes) ]\r\n                    //    [ output content (N bytes) ]\r\n                    //\r\n                    // Perform the ABI decode by ignoring the first 32 bytes of the return data\r\n                    let copysize := sub(returndatasize, 0x20)\r\n                    returndatacopy(output, 0x20, copysize)\r\n\r\n                    mstore(0x40, add(output, copysize)) // free mem ptr set\r\n                }\r\n            }\r\n        }\r\n\r\n        emit ScriptResult(address(executor), _script, _input, output);\r\n\r\n        return output;\r\n    }\r\n\r\n    modifier protectState {\r\n        address preKernel = address(kernel());\r\n        bytes32 preAppId = appId();\r\n        _; // exec\r\n        require(address(kernel()) == preKernel, ERROR_PROTECTED_STATE_MODIFIED);\r\n        require(appId() == preAppId, ERROR_PROTECTED_STATE_MODIFIED);\r\n    }\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/apps/AragonApp.sol@v4.4.0\r\n\r\n/*\r\n * SPDX-License-Identifier:    MIT\r\n */\r\n\r\npragma solidity ^0.4.24;\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n// Contracts inheriting from AragonApp are, by default, immediately petrified upon deployment so\r\n// that they can never be initialized.\r\n// Unless overriden, this behaviour enforces those contracts to be usable only behind an AppProxy.\r\n// ReentrancyGuard, EVMScriptRunner, and ACLSyntaxSugar are not directly used by this contract, but\r\n// are included so that they are automatically usable by subclassing contracts\r\ncontract AragonApp is AppStorage, Autopetrified, VaultRecoverable, ReentrancyGuard, EVMScriptRunner, ACLSyntaxSugar {\r\n    string private constant ERROR_AUTH_FAILED = \"APP_AUTH_FAILED\";\r\n\r\n    modifier auth(bytes32 _role) {\r\n        require(canPerform(msg.sender, _role, new uint256[](0)), ERROR_AUTH_FAILED);\r\n        _;\r\n    }\r\n\r\n    modifier authP(bytes32 _role, uint256[] _params) {\r\n        require(canPerform(msg.sender, _role, _params), ERROR_AUTH_FAILED);\r\n        _;\r\n    }\r\n\r\n    /**\r\n    * @dev Check whether an action can be performed by a sender for a particular role on this app\r\n    * @param _sender Sender of the call\r\n    * @param _role Role on this app\r\n    * @param _params Permission params for the role\r\n    * @return Boolean indicating whether the sender has the permissions to perform the action.\r\n    *         Always returns false if the app hasn't been initialized yet.\r\n    */\r\n    function canPerform(address _sender, bytes32 _role, uint256[] _params) public view returns (bool) {\r\n        if (!hasInitialized()) {\r\n            return false;\r\n        }\r\n\r\n        IKernel linkedKernel = kernel();\r\n        if (address(linkedKernel) == address(0)) {\r\n            return false;\r\n        }\r\n\r\n        return linkedKernel.hasPermission(\r\n            _sender,\r\n            address(this),\r\n            _role,\r\n            ConversionHelpers.dangerouslyCastUintArrayToBytes(_params)\r\n        );\r\n    }\r\n\r\n    /**\r\n    * @dev Get the recovery vault for the app\r\n    * @return Recovery vault address for the app\r\n    */\r\n    function getRecoveryVault() public view returns (address) {\r\n        // Funds recovery via a vault is only available when used with a kernel\r\n        return kernel().getRecoveryVault(); // if kernel is not set, it will revert\r\n    }\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/common/IForwarder.sol@v4.4.0\r\n\r\n/*\r\n * SPDX-License-Identifier:    MIT\r\n */\r\n\r\npragma solidity ^0.4.24;\r\n\r\n\r\ninterface IForwarder {\r\n    function isForwarder() external pure returns (bool);\r\n\r\n    // TODO: this should be external\r\n    // See https://github.com/ethereum/solidity/issues/4832\r\n    function canForward(address sender, bytes evmCallScript) public view returns (bool);\r\n\r\n    // TODO: this should be external\r\n    // See https://github.com/ethereum/solidity/issues/4832\r\n    function forward(bytes evmCallScript) public;\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/lib/math/SafeMath.sol@v4.4.0\r\n\r\n// See https://github.com/OpenZeppelin/openzeppelin-solidity/blob/d51e38758e1d985661534534d5c61e27bece5042/contracts/math/SafeMath.sol\r\n// Adapted to use pragma ^0.4.24 and satisfy our linter rules\r\n\r\npragma solidity ^0.4.24;\r\n\r\n\r\n/**\r\n * @title SafeMath\r\n * @dev Math operations with safety checks that revert on error\r\n */\r\nlibrary SafeMath {\r\n    string private constant ERROR_ADD_OVERFLOW = \"MATH_ADD_OVERFLOW\";\r\n    string private constant ERROR_SUB_UNDERFLOW = \"MATH_SUB_UNDERFLOW\";\r\n    string private constant ERROR_MUL_OVERFLOW = \"MATH_MUL_OVERFLOW\";\r\n    string private constant ERROR_DIV_ZERO = \"MATH_DIV_ZERO\";\r\n\r\n    /**\r\n    * @dev Multiplies two numbers, reverts on overflow.\r\n    */\r\n    function mul(uint256 _a, uint256 _b) internal pure returns (uint256) {\r\n        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\r\n        // benefit is lost if 'b' is also tested.\r\n        // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\r\n        if (_a == 0) {\r\n            return 0;\r\n        }\r\n\r\n        uint256 c = _a * _b;\r\n        require(c / _a == _b, ERROR_MUL_OVERFLOW);\r\n\r\n        return c;\r\n    }\r\n\r\n    /**\r\n    * @dev Integer division of two numbers truncating the quotient, reverts on division by zero.\r\n    */\r\n    function div(uint256 _a, uint256 _b) internal pure returns (uint256) {\r\n        require(_b > 0, ERROR_DIV_ZERO); // Solidity only automatically asserts when dividing by 0\r\n        uint256 c = _a / _b;\r\n        // assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold\r\n\r\n        return c;\r\n    }\r\n\r\n    /**\r\n    * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).\r\n    */\r\n    function sub(uint256 _a, uint256 _b) internal pure returns (uint256) {\r\n        require(_b <= _a, ERROR_SUB_UNDERFLOW);\r\n        uint256 c = _a - _b;\r\n\r\n        return c;\r\n    }\r\n\r\n    /**\r\n    * @dev Adds two numbers, reverts on overflow.\r\n    */\r\n    function add(uint256 _a, uint256 _b) internal pure returns (uint256) {\r\n        uint256 c = _a + _b;\r\n        require(c >= _a, ERROR_ADD_OVERFLOW);\r\n\r\n        return c;\r\n    }\r\n\r\n    /**\r\n    * @dev Divides two numbers and returns the remainder (unsigned integer modulo),\r\n    * reverts when dividing by zero.\r\n    */\r\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\r\n        require(b != 0, ERROR_DIV_ZERO);\r\n        return a % b;\r\n    }\r\n}\r\n\r\n\r\n// File @aragon/os/contracts/lib/math/SafeMath64.sol@v4.4.0\r\n\r\n// See https://github.com/OpenZeppelin/openzeppelin-solidity/blob/d51e38758e1d985661534534d5c61e27bece5042/contracts/math/SafeMath.sol\r\n// Adapted for uint64, pragma ^0.4.24, and satisfying our linter rules\r\n// Also optimized the mul() implementation, see https://github.com/aragon/aragonOS/pull/417\r\n\r\npragma solidity ^0.4.24;\r\n\r\n\r\n/**\r\n * @title SafeMath64\r\n * @dev Math operations for uint64 with safety checks that revert on error\r\n */\r\nlibrary SafeMath64 {\r\n    string private constant ERROR_ADD_OVERFLOW = \"MATH64_ADD_OVERFLOW\";\r\n    string private constant ERROR_SUB_UNDERFLOW = \"MATH64_SUB_UNDERFLOW\";\r\n    string private constant ERROR_MUL_OVERFLOW = \"MATH64_MUL_OVERFLOW\";\r\n    string private constant ERROR_DIV_ZERO = \"MATH64_DIV_ZERO\";\r\n\r\n    /**\r\n    * @dev Multiplies two numbers, reverts on overflow.\r\n    */\r\n    function mul(uint64 _a, uint64 _b) internal pure returns (uint64) {\r\n        uint256 c = uint256(_a) * uint256(_b);\r\n        require(c < 0x010000000000000000, ERROR_MUL_OVERFLOW); // 2**64 (less gas this way)\r\n\r\n        return uint64(c);\r\n    }\r\n\r\n    /**\r\n    * @dev Integer division of two numbers truncating the quotient, reverts on division by zero.\r\n    */\r\n    function div(uint64 _a, uint64 _b) internal pure returns (uint64) {\r\n        require(_b > 0, ERROR_DIV_ZERO); // Solidity only automatically asserts when dividing by 0\r\n        uint64 c = _a / _b;\r\n        // assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold\r\n\r\n        return c;\r\n    }\r\n\r\n    /**\r\n    * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).\r\n    */\r\n    function sub(uint64 _a, uint64 _b) internal pure returns (uint64) {\r\n        require(_b <= _a, ERROR_SUB_UNDERFLOW);\r\n        uint64 c = _a - _b;\r\n\r\n        return c;\r\n    }\r\n\r\n    /**\r\n    * @dev Adds two numbers, reverts on overflow.\r\n    */\r\n    function add(uint64 _a, uint64 _b) internal pure returns (uint64) {\r\n        uint64 c = _a + _b;\r\n        require(c >= _a, ERROR_ADD_OVERFLOW);\r\n\r\n        return c;\r\n    }\r\n\r\n    /**\r\n    * @dev Divides two numbers and returns the remainder (unsigned integer modulo),\r\n    * reverts when dividing by zero.\r\n    */\r\n    function mod(uint64 a, uint64 b) internal pure returns (uint64) {\r\n        require(b != 0, ERROR_DIV_ZERO);\r\n        return a % b;\r\n    }\r\n}\r\n\r\n\r\n// File @aragon/apps-shared-minime/contracts/ITokenController.sol@v1.0.2\r\n\r\npragma solidity ^0.4.24;\r\n\r\n/// @dev The token controller contract must implement these functions\r\n\r\n\r\ninterface ITokenController {\r\n    /// @notice Called when `_owner` sends ether to the MiniMe Token contract\r\n    /// @param _owner The address that sent the ether to create tokens\r\n    /// @return True if the ether is accepted, false if it throws\r\n    function proxyPayment(address _owner) external payable returns(bool);\r\n\r\n    /// @notice Notifies the controller about a token transfer allowing the\r\n    ///  controller to react if desired\r\n    /// @param _from The origin of the transfer\r\n    /// @param _to The destination of the transfer\r\n    /// @param _amount The amount of the transfer\r\n    /// @return False if the controller does not authorize the transfer\r\n    function onTransfer(address _from, address _to, uint _amount) external returns(bool);\r\n\r\n    /// @notice Notifies the controller about an approval allowing the\r\n    ///  controller to react if desired\r\n    /// @param _owner The address that calls `approve()`\r\n    /// @param _spender The spender in the `approve()` call\r\n    /// @param _amount The amount in the `approve()` call\r\n    /// @return False if the controller does not authorize the approval\r\n    function onApprove(address _owner, address _spender, uint _amount) external returns(bool);\r\n}\r\n\r\n\r\n// File @aragon/apps-shared-minime/contracts/MiniMeToken.sol@v1.0.2\r\n\r\npragma solidity ^0.4.24;\r\n\r\n/*\r\n    Copyright 2016, Jordi Baylina\r\n    This program is free software: you can redistribute it and/or modify\r\n    it under the terms of the GNU General Public License as published by\r\n    the Free Software Foundation, either version 3 of the License, or\r\n    (at your option) any later version.\r\n    This program is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU General Public License for more details.\r\n    You should have received a copy of the GNU General Public License\r\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\r\n */\r\n\r\n/// @title MiniMeToken Contract\r\n/// @author Jordi Baylina\r\n/// @dev This token contract's goal is to make it easy for anyone to clone this\r\n///  token using the token distribution at a given block, this will allow DAO's\r\n///  and DApps to upgrade their features in a decentralized manner without\r\n///  affecting the original token\r\n/// @dev It is ERC20 compliant, but still needs to under go further testing.\r\n\r\ncontract Controlled {\r\n    /// @notice The address of the controller is the only address that can call\r\n    ///  a function with this modifier\r\n    modifier onlyController {\r\n        require(msg.sender == controller);\r\n        _;\r\n    }\r\n\r\n    address public controller;\r\n\r\n    function Controlled()  public { controller = msg.sender;}\r\n\r\n    /// @notice Changes the controller of the contract\r\n    /// @param _newController The new controller of the contract\r\n    function changeController(address _newController) onlyController  public {\r\n        controller = _newController;\r\n    }\r\n}\r\n\r\ncontract ApproveAndCallFallBack {\r\n    function receiveApproval(\r\n        address from,\r\n        uint256 _amount,\r\n        address _token,\r\n        bytes _data\r\n    ) public;\r\n}\r\n\r\n/// @dev The actual token contract, the default controller is the msg.sender\r\n///  that deploys the contract, so usually this token will be deployed by a\r\n///  token controller contract, which Giveth will call a \"Campaign\"\r\ncontract MiniMeToken is Controlled {\r\n\r\n    string public name;                //The Token's name: e.g. DigixDAO Tokens\r\n    uint8 public decimals;             //Number of decimals of the smallest unit\r\n    string public symbol;              //An identifier: e.g. REP\r\n    string public version = \"MMT_0.1\"; //An arbitrary versioning scheme\r\n\r\n\r\n    /// @dev `Checkpoint` is the structure that attaches a block number to a\r\n    ///  given value, the block number attached is the one that last changed the\r\n    ///  value\r\n    struct Checkpoint {\r\n\r\n        // `fromBlock` is the block number that the value was generated from\r\n        uint128 fromBlock;\r\n\r\n        // `value` is the amount of tokens at a specific block number\r\n        uint128 value;\r\n    }\r\n\r\n    // `parentToken` is the Token address that was cloned to produce this token;\r\n    //  it will be 0x0 for a token that was not cloned\r\n    MiniMeToken public parentToken;\r\n\r\n    // `parentSnapShotBlock` is the block number from the Parent Token that was\r\n    //  used to determine the initial distribution of the Clone Token\r\n    uint public parentSnapShotBlock;\r\n\r\n    // `creationBlock` is the block number that the Clone Token was created\r\n    uint public creationBlock;\r\n\r\n    // `balances` is the map that tracks the balance of each address, in this\r\n    //  contract when the balance changes the block number that the change\r\n    //  occurred is also included in the map\r\n    mapping (address => Checkpoint[]) balances;\r\n\r\n    // `allowed` tracks any extra transfer rights as in all ERC20 tokens\r\n    mapping (address => mapping (address => uint256)) allowed;\r\n\r\n    // Tracks the history of the `totalSupply` of the token\r\n    Checkpoint[] totalSupplyHistory;\r\n\r\n    // Flag that determines if the token is transferable or not.\r\n    bool public transfersEnabled;\r\n\r\n    // The factory used to create new clone tokens\r\n    MiniMeTokenFactory public tokenFactory;\r\n\r\n////////////////\r\n// Constructor\r\n////////////////\r\n\r\n    /// @notice Constructor to create a MiniMeToken\r\n    /// @param _tokenFactory The address of the MiniMeTokenFactory contract that\r\n    ///  will create the Clone token contracts, the token factory needs to be\r\n    ///  deployed first\r\n    /// @param _parentToken Address of the parent token, set to 0x0 if it is a\r\n    ///  new token\r\n    /// @param _parentSnapShotBlock Block of the parent token that will\r\n    ///  determine the initial distribution of the clone token, set to 0 if it\r\n    ///  is a new token\r\n    /// @param _tokenName Name of the new token\r\n    /// @param _decimalUnits Number of decimals of the new token\r\n    /// @param _tokenSymbol Token Symbol for the new token\r\n    /// @param _transfersEnabled If true, tokens will be able to be transferred\r\n    function MiniMeToken(\r\n        MiniMeTokenFactory _tokenFactory,\r\n        MiniMeToken _parentToken,\r\n        uint _parentSnapShotBlock,\r\n        string _tokenName,\r\n        uint8 _decimalUnits,\r\n        string _tokenSymbol,\r\n        bool _transfersEnabled\r\n    )  public\r\n    {\r\n        tokenFactory = _tokenFactory;\r\n        name = _tokenName;                                 // Set the name\r\n        decimals = _decimalUnits;                          // Set the decimals\r\n        symbol = _tokenSymbol;                             // Set the symbol\r\n        parentToken = _parentToken;\r\n        parentSnapShotBlock = _parentSnapShotBlock;\r\n        transfersEnabled = _transfersEnabled;\r\n        creationBlock = block.number;\r\n    }\r\n\r\n\r\n///////////////////\r\n// ERC20 Methods\r\n///////////////////\r\n\r\n    /// @notice Send `_amount` tokens to `_to` from `msg.sender`\r\n    /// @param _to The address of the recipient\r\n    /// @param _amount The amount of tokens to be transferred\r\n    /// @return Whether the transfer was successful or not\r\n    function transfer(address _to, uint256 _amount) public returns (bool success) {\r\n        require(transfersEnabled);\r\n        return doTransfer(msg.sender, _to, _amount);\r\n    }\r\n\r\n    /// @notice Send `_amount` tokens to `_to` from `_from` on the condition it\r\n    ///  is approved by `_from`\r\n    /// @param _from The address holding the tokens being transferred\r\n    /// @param _to The address of the recipient\r\n    /// @param _amount The amount of tokens to be transferred\r\n    /// @return True if the transfer was successful\r\n    function transferFrom(address _from, address _to, uint256 _amount) public returns (bool success) {\r\n\r\n        // The controller of this contract can move tokens around at will,\r\n        //  this is important to recognize! Confirm that you trust the\r\n        //  controller of this contract, which in most situations should be\r\n        //  another open source smart contract or 0x0\r\n        if (msg.sender != controller) {\r\n            require(transfersEnabled);\r\n\r\n            // The standard ERC 20 transferFrom functionality\r\n            if (allowed[_from][msg.sender] < _amount)\r\n                return false;\r\n            allowed[_from][msg.sender] -= _amount;\r\n        }\r\n        return doTransfer(_from, _to, _amount);\r\n    }\r\n\r\n    /// @dev This is the actual transfer function in the token contract, it can\r\n    ///  only be called by other functions in this contract.\r\n    /// @param _from The address holding the tokens being transferred\r\n    /// @param _to The address of the recipient\r\n    /// @param _amount The amount of tokens to be transferred\r\n    /// @return True if the transfer was successful\r\n    function doTransfer(address _from, address _to, uint _amount) internal returns(bool) {\r\n        if (_amount == 0) {\r\n            return true;\r\n        }\r\n        require(parentSnapShotBlock < block.number);\r\n        // Do not allow transfer to 0x0 or the token contract itself\r\n        require((_to != 0) && (_to != address(this)));\r\n        // If the amount being transfered is more than the balance of the\r\n        //  account the transfer returns false\r\n        var previousBalanceFrom = balanceOfAt(_from, block.number);\r\n        if (previousBalanceFrom < _amount) {\r\n            return false;\r\n        }\r\n        // Alerts the token controller of the transfer\r\n        if (isContract(controller)) {\r\n            // Adding the ` == true` makes the linter shut up so...\r\n            require(ITokenController(controller).onTransfer(_from, _to, _amount) == true);\r\n        }\r\n        // First update the balance array with the new value for the address\r\n        //  sending the tokens\r\n        updateValueAtNow(balances[_from], previousBalanceFrom - _amount);\r\n        // Then update the balance array with the new value for the address\r\n        //  receiving the tokens\r\n        var previousBalanceTo = balanceOfAt(_to, block.number);\r\n        require(previousBalanceTo + _amount >= previousBalanceTo); // Check for overflow\r\n        updateValueAtNow(balances[_to], previousBalanceTo + _amount);\r\n        // An event to make the transfer easy to find on the blockchain\r\n        Transfer(_from, _to, _amount);\r\n        return true;\r\n    }\r\n\r\n    /// @param _owner The address that's balance is being requested\r\n    /// @return The balance of `_owner` at the current block\r\n    function balanceOf(address _owner) public constant returns (uint256 balance) {\r\n        return balanceOfAt(_owner, block.number);\r\n    }\r\n\r\n    /// @notice `msg.sender` approves `_spender` to spend `_amount` tokens on\r\n    ///  its behalf. This is a modified version of the ERC20 approve function\r\n    ///  to be a little bit safer\r\n    /// @param _spender The address of the account able to transfer the tokens\r\n    /// @param _amount The amount of tokens to be approved for transfer\r\n    /// @return True if the approval was successful\r\n    function approve(address _spender, uint256 _amount) public returns (bool success) {\r\n        require(transfersEnabled);\r\n\r\n        // To change the approve amount you first have to reduce the addresses`\r\n        //  allowance to zero by calling `approve(_spender,0)` if it is not\r\n        //  already 0 to mitigate the race condition described here:\r\n        //  https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\r\n        require((_amount == 0) || (allowed[msg.sender][_spender] == 0));\r\n\r\n        // Alerts the token controller of the approve function call\r\n        if (isContract(controller)) {\r\n            // Adding the ` == true` makes the linter shut up so...\r\n            require(ITokenController(controller).onApprove(msg.sender, _spender, _amount) == true);\r\n        }\r\n\r\n        allowed[msg.sender][_spender] = _amount;\r\n        Approval(msg.sender, _spender, _amount);\r\n        return true;\r\n    }\r\n\r\n    /// @dev This function makes it easy to read the `allowed[]` map\r\n    /// @param _owner The address of the account that owns the token\r\n    /// @param _spender The address of the account able to transfer the tokens\r\n    /// @return Amount of remaining tokens of _owner that _spender is allowed\r\n    ///  to spend\r\n    function allowance(address _owner, address _spender) public constant returns (uint256 remaining) {\r\n        return allowed[_owner][_spender];\r\n    }\r\n\r\n    /// @notice `msg.sender` approves `_spender` to send `_amount` tokens on\r\n    ///  its behalf, and then a function is triggered in the contract that is\r\n    ///  being approved, `_spender`. This allows users to use their tokens to\r\n    ///  interact with contracts in one function call instead of two\r\n    /// @param _spender The address of the contract able to transfer the tokens\r\n    /// @param _amount The amount of tokens to be approved for transfer\r\n    /// @return True if the function call was successful\r\n    function approveAndCall(ApproveAndCallFallBack _spender, uint256 _amount, bytes _extraData) public returns (bool success) {\r\n        require(approve(_spender, _amount));\r\n\r\n        _spender.receiveApproval(\r\n            msg.sender,\r\n            _amount,\r\n            this,\r\n            _extraData\r\n        );\r\n\r\n        return true;\r\n    }\r\n\r\n    /// @dev This function makes it easy to get the total number of tokens\r\n    /// @return The total number of tokens\r\n    function totalSupply() public constant returns (uint) {\r\n        return totalSupplyAt(block.number);\r\n    }\r\n\r\n\r\n////////////////\r\n// Query balance and totalSupply in History\r\n////////////////\r\n\r\n    /// @dev Queries the balance of `_owner` at a specific `_blockNumber`\r\n    /// @param _owner The address from which the balance will be retrieved\r\n    /// @param _blockNumber The block number when the balance is queried\r\n    /// @return The balance at `_blockNumber`\r\n    function balanceOfAt(address _owner, uint _blockNumber) public constant returns (uint) {\r\n\r\n        // These next few lines are used when the balance of the token is\r\n        //  requested before a check point was ever created for this token, it\r\n        //  requires that the `parentToken.balanceOfAt` be queried at the\r\n        //  genesis block for that token as this contains initial balance of\r\n        //  this token\r\n        if ((balances[_owner].length == 0) || (balances[_owner][0].fromBlock > _blockNumber)) {\r\n            if (address(parentToken) != 0) {\r\n                return parentToken.balanceOfAt(_owner, min(_blockNumber, parentSnapShotBlock));\r\n            } else {\r\n                // Has no parent\r\n                return 0;\r\n            }\r\n\r\n        // This will return the expected balance during normal situations\r\n        } else {\r\n            return getValueAt(balances[_owner], _blockNumber);\r\n        }\r\n    }\r\n\r\n    /// @notice Total amount of tokens at a specific `_blockNumber`.\r\n    /// @param _blockNumber The block number when the totalSupply is queried\r\n    /// @return The total amount of tokens at `_blockNumber`\r\n    function totalSupplyAt(uint _blockNumber) public constant returns(uint) {\r\n\r\n        // These next few lines are used when the totalSupply of the token is\r\n        //  requested before a check point was ever created for this token, it\r\n        //  requires that the `parentToken.totalSupplyAt` be queried at the\r\n        //  genesis block for this token as that contains totalSupply of this\r\n        //  token at this block number.\r\n        if ((totalSupplyHistory.length == 0) || (totalSupplyHistory[0].fromBlock > _blockNumber)) {\r\n            if (address(parentToken) != 0) {\r\n                return parentToken.totalSupplyAt(min(_blockNumber, parentSnapShotBlock));\r\n            } else {\r\n                return 0;\r\n            }\r\n\r\n        // This will return the expected totalSupply during normal situations\r\n        } else {\r\n            return getValueAt(totalSupplyHistory, _blockNumber);\r\n        }\r\n    }\r\n\r\n////////////////\r\n// Clone Token Method\r\n////////////////\r\n\r\n    /// @notice Creates a new clone token with the initial distribution being\r\n    ///  this token at `_snapshotBlock`\r\n    /// @param _cloneTokenName Name of the clone token\r\n    /// @param _cloneDecimalUnits Number of decimals of the smallest unit\r\n    /// @param _cloneTokenSymbol Symbol of the clone token\r\n    /// @param _snapshotBlock Block when the distribution of the parent token is\r\n    ///  copied to set the initial distribution of the new clone token;\r\n    ///  if the block is zero than the actual block, the current block is used\r\n    /// @param _transfersEnabled True if transfers are allowed in the clone\r\n    /// @return The address of the new MiniMeToken Contract\r\n    function createCloneToken(\r\n        string _cloneTokenName,\r\n        uint8 _cloneDecimalUnits,\r\n        string _cloneTokenSymbol,\r\n        uint _snapshotBlock,\r\n        bool _transfersEnabled\r\n    ) public returns(MiniMeToken)\r\n    {\r\n        uint256 snapshot = _snapshotBlock == 0 ? block.number - 1 : _snapshotBlock;\r\n\r\n        MiniMeToken cloneToken = tokenFactory.createCloneToken(\r\n            this,\r\n            snapshot,\r\n            _cloneTokenName,\r\n            _cloneDecimalUnits,\r\n            _cloneTokenSymbol,\r\n            _transfersEnabled\r\n        );\r\n\r\n        cloneToken.changeController(msg.sender);\r\n\r\n        // An event to make the token easy to find on the blockchain\r\n        NewCloneToken(address(cloneToken), snapshot);\r\n        return cloneToken;\r\n    }\r\n\r\n////////////////\r\n// Generate and destroy tokens\r\n////////////////\r\n\r\n    /// @notice Generates `_amount` tokens that are assigned to `_owner`\r\n    /// @param _owner The address that will be assigned the new tokens\r\n    /// @param _amount The quantity of tokens generated\r\n    /// @return True if the tokens are generated correctly\r\n    function generateTokens(address _owner, uint _amount) onlyController public returns (bool) {\r\n        uint curTotalSupply = totalSupply();\r\n        require(curTotalSupply + _amount >= curTotalSupply); // Check for overflow\r\n        uint previousBalanceTo = balanceOf(_owner);\r\n        require(previousBalanceTo + _amount >= previousBalanceTo); // Check for overflow\r\n        updateValueAtNow(totalSupplyHistory, curTotalSupply + _amount);\r\n        updateValueAtNow(balances[_owner], previousBalanceTo + _amount);\r\n        Transfer(0, _owner, _amount);\r\n        return true;\r\n    }\r\n\r\n\r\n    /// @notice Burns `_amount` tokens from `_owner`\r\n    /// @param _owner The address that will lose the tokens\r\n    /// @param _amount The quantity of tokens to burn\r\n    /// @return True if the tokens are burned correctly\r\n    function destroyTokens(address _owner, uint _amount) onlyController public returns (bool) {\r\n        uint curTotalSupply = totalSupply();\r\n        require(curTotalSupply >= _amount);\r\n        uint previousBalanceFrom = balanceOf(_owner);\r\n        require(previousBalanceFrom >= _amount);\r\n        updateValueAtNow(totalSupplyHistory, curTotalSupply - _amount);\r\n        updateValueAtNow(balances[_owner], previousBalanceFrom - _amount);\r\n        Transfer(_owner, 0, _amount);\r\n        return true;\r\n    }\r\n\r\n////////////////\r\n// Enable tokens transfers\r\n////////////////\r\n\r\n\r\n    /// @notice Enables token holders to transfer their tokens freely if true\r\n    /// @param _transfersEnabled True if transfers are allowed in the clone\r\n    function enableTransfers(bool _transfersEnabled) onlyController public {\r\n        transfersEnabled = _transfersEnabled;\r\n    }\r\n\r\n////////////////\r\n// Internal helper functions to query and set a value in a snapshot array\r\n////////////////\r\n\r\n    /// @dev `getValueAt` retrieves the number of tokens at a given block number\r\n    /// @param checkpoints The history of values being queried\r\n    /// @param _block The block number to retrieve the value at\r\n    /// @return The number of tokens being queried\r\n    function getValueAt(Checkpoint[] storage checkpoints, uint _block) constant internal returns (uint) {\r\n        if (checkpoints.length == 0)\r\n            return 0;\r\n\r\n        // Shortcut for the actual value\r\n        if (_block >= checkpoints[checkpoints.length-1].fromBlock)\r\n            return checkpoints[checkpoints.length-1].value;\r\n        if (_block < checkpoints[0].fromBlock)\r\n            return 0;\r\n\r\n        // Binary search of the value in the array\r\n        uint min = 0;\r\n        uint max = checkpoints.length-1;\r\n        while (max > min) {\r\n            uint mid = (max + min + 1) / 2;\r\n            if (checkpoints[mid].fromBlock<=_block) {\r\n                min = mid;\r\n            } else {\r\n                max = mid-1;\r\n            }\r\n        }\r\n        return checkpoints[min].value;\r\n    }\r\n\r\n    /// @dev `updateValueAtNow` used to update the `balances` map and the\r\n    ///  `totalSupplyHistory`\r\n    /// @param checkpoints The history of data being updated\r\n    /// @param _value The new number of tokens\r\n    function updateValueAtNow(Checkpoint[] storage checkpoints, uint _value) internal {\r\n        if ((checkpoints.length == 0) || (checkpoints[checkpoints.length - 1].fromBlock < block.number)) {\r\n            Checkpoint storage newCheckPoint = checkpoints[checkpoints.length++];\r\n            newCheckPoint.fromBlock = uint128(block.number);\r\n            newCheckPoint.value = uint128(_value);\r\n        } else {\r\n            Checkpoint storage oldCheckPoint = checkpoints[checkpoints.length - 1];\r\n            oldCheckPoint.value = uint128(_value);\r\n        }\r\n    }\r\n\r\n    /// @dev Internal function to determine if an address is a contract\r\n    /// @param _addr The address being queried\r\n    /// @return True if `_addr` is a contract\r\n    function isContract(address _addr) constant internal returns(bool) {\r\n        uint size;\r\n        if (_addr == 0)\r\n            return false;\r\n\r\n        assembly {\r\n            size := extcodesize(_addr)\r\n        }\r\n\r\n        return size>0;\r\n    }\r\n\r\n    /// @dev Helper function to return a min betwen the two uints\r\n    function min(uint a, uint b) pure internal returns (uint) {\r\n        return a < b ? a : b;\r\n    }\r\n\r\n    /// @notice The fallback function: If the contract's controller has not been\r\n    ///  set to 0, then the `proxyPayment` method is called which relays the\r\n    ///  ether and creates tokens as described in the token controller contract\r\n    function () external payable {\r\n        require(isContract(controller));\r\n        // Adding the ` == true` makes the linter shut up so...\r\n        require(ITokenController(controller).proxyPayment.value(msg.value)(msg.sender) == true);\r\n    }\r\n\r\n//////////\r\n// Safety Methods\r\n//////////\r\n\r\n    /// @notice This method can be used by the controller to extract mistakenly\r\n    ///  sent tokens to this contract.\r\n    /// @param _token The address of the token contract that you want to recover\r\n    ///  set to 0 in case you want to extract ether.\r\n    function claimTokens(address _token) onlyController public {\r\n        if (_token == 0x0) {\r\n            controller.transfer(this.balance);\r\n            return;\r\n        }\r\n\r\n        MiniMeToken token = MiniMeToken(_token);\r\n        uint balance = token.balanceOf(this);\r\n        token.transfer(controller, balance);\r\n        ClaimedTokens(_token, controller, balance);\r\n    }\r\n\r\n////////////////\r\n// Events\r\n////////////////\r\n    event ClaimedTokens(address indexed _token, address indexed _controller, uint _amount);\r\n    event Transfer(address indexed _from, address indexed _to, uint256 _amount);\r\n    event NewCloneToken(address indexed _cloneToken, uint _snapshotBlock);\r\n    event Approval(\r\n        address indexed _owner,\r\n        address indexed _spender,\r\n        uint256 _amount\r\n        );\r\n\r\n}\r\n\r\n\r\n////////////////\r\n// MiniMeTokenFactory\r\n////////////////\r\n\r\n/// @dev This contract is used to generate clone contracts from a contract.\r\n///  In solidity this is the way to create a contract from a contract of the\r\n///  same class\r\ncontract MiniMeTokenFactory {\r\n\r\n    /// @notice Update the DApp by creating a new token with new functionalities\r\n    ///  the msg.sender becomes the controller of this clone token\r\n    /// @param _parentToken Address of the token being cloned\r\n    /// @param _snapshotBlock Block of the parent token that will\r\n    ///  determine the initial distribution of the clone token\r\n    /// @param _tokenName Name of the new token\r\n    /// @param _decimalUnits Number of decimals of the new token\r\n    /// @param _tokenSymbol Token Symbol for the new token\r\n    /// @param _transfersEnabled If true, tokens will be able to be transferred\r\n    /// @return The address of the new token contract\r\n    function createCloneToken(\r\n        MiniMeToken _parentToken,\r\n        uint _snapshotBlock,\r\n        string _tokenName,\r\n        uint8 _decimalUnits,\r\n        string _tokenSymbol,\r\n        bool _transfersEnabled\r\n    ) public returns (MiniMeToken)\r\n    {\r\n        MiniMeToken newToken = new MiniMeToken(\r\n            this,\r\n            _parentToken,\r\n            _snapshotBlock,\r\n            _tokenName,\r\n            _decimalUnits,\r\n            _tokenSymbol,\r\n            _transfersEnabled\r\n        );\r\n\r\n        newToken.changeController(msg.sender);\r\n        return newToken;\r\n    }\r\n}\r\n\r\n\r\n// File contracts/Voting.sol\r\n\r\n/*\r\n * SPDX-License-Identitifer:    GPL-3.0-or-later\r\n */\r\n\r\npragma solidity 0.4.24;\r\n\r\n\r\n\r\ncontract Voting is IForwarder, AragonApp {\r\n    using SafeMath for uint256;\r\n    using SafeMath64 for uint64;\r\n\r\n    uint128 private constant MAX_UINT_128 = 2 ** 128 - 1;\r\n    uint128 private constant MAX_UINT_64 = 2 ** 64 - 1;\r\n\r\n    bytes32 public constant CREATE_VOTES_ROLE = 0xe7dcd7275292e064d090fbc5f3bd7995be23b502c1fed5cd94cfddbbdcd32bbc; //keccak256(\"CREATE_VOTES_ROLE\");\r\n    bytes32 public constant MODIFY_SUPPORT_ROLE = 0xda3972983e62bdf826c4b807c4c9c2b8a941e1f83dfa76d53d6aeac11e1be650; //keccak256(\"MODIFY_SUPPORT_ROLE\");\r\n    bytes32 public constant MODIFY_QUORUM_ROLE = 0xad15e7261800b4bb73f1b69d3864565ffb1fd00cb93cf14fe48da8f1f2149f39; //keccak256(\"MODIFY_QUORUM_ROLE\");\r\n\r\n    bytes32 public constant SET_MIN_BALANCE_ROLE = 0xb1f3f26f63ad27cd630737a426f990492f5c674208299d6fb23bb2b0733d3d66; //keccak256(\"SET_MIN_BALANCE_ROLE\")\r\n    bytes32 public constant SET_MIN_TIME_ROLE = 0xe7ab0252519cd959720b328191bed7fe61b8e25f77613877be7070646d12daf0; //keccak256(\"SET_MIN_TIME_ROLE\")\r\n\r\n    bytes32 public constant ENABLE_VOTE_CREATION = 0xecb50dc3e77ba8a59697a3cc090a29b4cbd3c1f2b6b3aea524e0d166969592b9; //keccak256(\"ENABLE_VOTE_CREATION\")\r\n\r\n    bytes32 public constant DISABLE_VOTE_CREATION = 0x40b01f8b31b51596de2eeab8c325ff77cc3695c1c1875d66ff31176e7148d2a1; //keccack256(\"DISABLE_VOTE_CREATION\")\r\n\r\n    uint64 public constant PCT_BASE = 10 ** 18; // 0% = 0; 1% = 10^16; 100% = 10^18\r\n\r\n    string private constant ERROR_NO_VOTE = \"VOTING_NO_VOTE\";\r\n    string private constant ERROR_INIT_PCTS = \"VOTING_INIT_PCTS\";\r\n    string private constant ERROR_CHANGE_SUPPORT_PCTS = \"VOTING_CHANGE_SUPPORT_PCTS\";\r\n    string private constant ERROR_CHANGE_QUORUM_PCTS = \"VOTING_CHANGE_QUORUM_PCTS\";\r\n    string private constant ERROR_INIT_SUPPORT_TOO_BIG = \"VOTING_INIT_SUPPORT_TOO_BIG\";\r\n    string private constant ERROR_CHANGE_SUPPORT_TOO_BIG = \"VOTING_CHANGE_SUPP_TOO_BIG\";\r\n    string private constant ERROR_CAN_NOT_VOTE = \"VOTING_CAN_NOT_VOTE\";\r\n    string private constant ERROR_MALFORMED_CONTINUOUS_VOTE = \"MALFORMED_CONTINUOUS_VOTE\";\r\n    string private constant ERROR_CAN_NOT_EXECUTE = \"VOTING_CAN_NOT_EXECUTE\";\r\n    string private constant ERROR_CAN_NOT_FORWARD = \"VOTING_CAN_NOT_FORWARD\";\r\n    string private constant ERROR_NO_VOTING_POWER = \"VOTING_NO_VOTING_POWER\";\r\n\r\n    enum VoterState { Absent, Yea, Nay, Even }\r\n\r\n    struct Vote {\r\n        bool executed;\r\n        uint64 startDate;\r\n        uint64 snapshotBlock;\r\n        uint64 supportRequiredPct;\r\n        uint64 minAcceptQuorumPct;\r\n        uint256 yea;\r\n        uint256 nay;\r\n        uint256 votingPower;\r\n        bytes executionScript;\r\n        mapping (address => VoterState) voters;\r\n    }\r\n\r\n    MiniMeToken public token;\r\n    uint64 public supportRequiredPct;\r\n    uint64 public minAcceptQuorumPct;\r\n    uint64 public voteTime;\r\n\r\n    //2500000000000000000000\r\n    uint256 public minBalanceLowerLimit;\r\n    uint256 public minBalanceUpperLimit;\r\n    //43200\r\n    uint256 public minTimeLowerLimit;\r\n    //1209600\r\n    uint256 public minTimeUpperLimit;\r\n\r\n    uint256 public minBalance;\r\n    uint256 public minTime;\r\n\r\n    bool public enableVoteCreation;\r\n\r\n    // We are mimicing an array, we use a mapping instead to make app upgrade more graceful\r\n    mapping (uint256 => Vote) internal votes;\r\n    uint256 public votesLength;\r\n\r\n    mapping(address => uint256) public lastCreateVoteTimes;\r\n\r\n    event StartVote(uint256 indexed voteId, address indexed creator, string metadata, uint256 minBalance, uint256 minTime, uint256 totalSupply, uint256 creatorVotingPower);\r\n    event CastVote(uint256 indexed voteId, address indexed voter, bool supports, uint256 stake);\r\n    event ExecuteVote(uint256 indexed voteId);\r\n    event ChangeSupportRequired(uint64 supportRequiredPct);\r\n    event ChangeMinQuorum(uint64 minAcceptQuorumPct);\r\n\r\n    event MinimumBalanceSet(uint256 minBalance);\r\n    event MinimumTimeSet(uint256 minTime);\r\n\r\n    modifier voteExists(uint256 _voteId) {\r\n        require(_voteId < votesLength, ERROR_NO_VOTE);\r\n        _;\r\n    }\r\n\r\n    modifier minBalanceCheck(uint256 _minBalance) {\r\n        //_minBalance to be at least the equivalent of 10k locked for a year (1e18 precision)\r\n        require(_minBalance >= minBalanceLowerLimit && _minBalance <= minBalanceUpperLimit, \"Min balance should be within initialization hardcoded limits\");\r\n        _;\r\n    }\r\n\r\n    modifier minTimeCheck(uint256 _minTime) {\r\n        require(_minTime >= minTimeLowerLimit && _minTime <= minTimeUpperLimit, \"Min time should be within initialization hardcoded limits\");\r\n        _;\r\n    }\r\n\r\n    /**\r\n    * @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)`\r\n    * @param _token MiniMeToken Address that will be used as governance token\r\n    * @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%)\r\n    * @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%)\r\n    * @param _voteTime Seconds that a vote will be open for token holders to vote (unless enough yeas or nays have been cast to make an early decision)\r\n    * @param _minBalance Minumum balance that a token holder should have to create a new vote\r\n    * @param _minTime Minimum time between a user's previous vote and creating a new vote\r\n    * @param _minBalanceLowerLimit Hardcoded lower limit for _minBalance on initialization\r\n    * @param _minTimeLowerLimit Hardcoded lower limit for _minTime on initialization\r\n    * @param _minTimeUpperLimit Hardcoded upper limit for _minTime on initialization\r\n    */\r\n    function initialize(MiniMeToken _token, \r\n        uint64 _supportRequiredPct, \r\n        uint64 _minAcceptQuorumPct, \r\n        uint64 _voteTime,\r\n        uint256 _minBalance,\r\n        uint256 _minTime,\r\n        uint256 _minBalanceLowerLimit,\r\n        uint256 _minBalanceUpperLimit,\r\n        uint256 _minTimeLowerLimit,\r\n        uint256 _minTimeUpperLimit\r\n    ) external onlyInit {\r\n        assert(CREATE_VOTES_ROLE == keccak256(\"CREATE_VOTES_ROLE\"));\r\n        assert(MODIFY_SUPPORT_ROLE == keccak256(\"MODIFY_SUPPORT_ROLE\"));\r\n        assert(MODIFY_QUORUM_ROLE == keccak256(\"MODIFY_QUORUM_ROLE\"));\r\n        assert(SET_MIN_BALANCE_ROLE == keccak256(\"SET_MIN_BALANCE_ROLE\"));\r\n        assert(SET_MIN_TIME_ROLE == keccak256(\"SET_MIN_TIME_ROLE\"));\r\n        assert(DISABLE_VOTE_CREATION == keccak256(\"DISABLE_VOTE_CREATION\"));\r\n        assert(ENABLE_VOTE_CREATION == keccak256(\"ENABLE_VOTE_CREATION\"));\r\n\r\n        initialized();\r\n\r\n        require(_minAcceptQuorumPct <= _supportRequiredPct, ERROR_INIT_PCTS);\r\n        require(_supportRequiredPct < PCT_BASE, ERROR_INIT_SUPPORT_TOO_BIG);\r\n\r\n        require(_minBalance >= _minBalanceLowerLimit && _minBalance <= _minBalanceUpperLimit);\r\n        require(_minTime >= _minTimeLowerLimit && _minTime <= _minTimeUpperLimit);\r\n\r\n        token = _token;\r\n        supportRequiredPct = _supportRequiredPct;\r\n        minAcceptQuorumPct = _minAcceptQuorumPct;\r\n        voteTime = _voteTime;\r\n\r\n        uint256 decimalsMul = uint256(10) ** token.decimals();\r\n\r\n        minBalance = _minBalance.mul(decimalsMul);\r\n        minTime = _minTime;\r\n\r\n        minBalanceLowerLimit = _minBalanceLowerLimit.mul(decimalsMul);\r\n        minBalanceUpperLimit = _minBalanceUpperLimit.mul(decimalsMul);\r\n        minTimeLowerLimit = _minTimeLowerLimit;\r\n        minTimeUpperLimit = _minTimeUpperLimit;\r\n\r\n        emit MinimumBalanceSet(minBalance);\r\n        emit MinimumTimeSet(minTime);\r\n\r\n        enableVoteCreation = true;\r\n    }\r\n\r\n    /**\r\n    * @notice Change required support to `@formatPct(_supportRequiredPct)`%\r\n    * @param _supportRequiredPct New required support\r\n    */\r\n    function changeSupportRequiredPct(uint64 _supportRequiredPct)\r\n        external\r\n        authP(MODIFY_SUPPORT_ROLE, arr(uint256(_supportRequiredPct), uint256(supportRequiredPct)))\r\n    {\r\n        require(minAcceptQuorumPct <= _supportRequiredPct, ERROR_CHANGE_SUPPORT_PCTS);\r\n        require(_supportRequiredPct < PCT_BASE, ERROR_CHANGE_SUPPORT_TOO_BIG);\r\n        supportRequiredPct = _supportRequiredPct;\r\n\r\n        emit ChangeSupportRequired(_supportRequiredPct);\r\n    }\r\n\r\n    /**\r\n    * @notice Change minimum acceptance quorum to `@formatPct(_minAcceptQuorumPct)`%\r\n    * @param _minAcceptQuorumPct New acceptance quorum\r\n    */\r\n    function changeMinAcceptQuorumPct(uint64 _minAcceptQuorumPct)\r\n        external\r\n        authP(MODIFY_QUORUM_ROLE, arr(uint256(_minAcceptQuorumPct), uint256(minAcceptQuorumPct)))\r\n    {\r\n        require(_minAcceptQuorumPct <= supportRequiredPct, ERROR_CHANGE_QUORUM_PCTS);\r\n        minAcceptQuorumPct = _minAcceptQuorumPct;\r\n\r\n        emit ChangeMinQuorum(_minAcceptQuorumPct);\r\n    }\r\n\r\n    /**\r\n    * @notice Change minimum balance needed to create a vote to `_minBalance`\r\n    * @param _minBalance New minimum balance\r\n    */\r\n\r\n    function setMinBalance(uint256 _minBalance) external auth(SET_MIN_BALANCE_ROLE) minBalanceCheck(_minBalance) {\r\n        //min balance can't be set to lower than 10k * 1 year\r\n        minBalance = _minBalance;\r\n\r\n        emit MinimumBalanceSet(_minBalance);\r\n    }\r\n\r\n    /**\r\n    * @notice Change minimum time needed to pass between user's previous vote and a user creating a new vote\r\n    * @param _minTime New minumum time\r\n    */\r\n\r\n    function setMinTime(uint256 _minTime) external auth(SET_MIN_TIME_ROLE) minTimeCheck(_minTime) {\r\n        //min time should be within initialized hardcoded limits\r\n        minTime = _minTime;\r\n\r\n        emit MinimumTimeSet(_minTime);\r\n    }\r\n\r\n    //later role will be set to 0x0 - noone\r\n    function disableVoteCreationOnce() external auth(DISABLE_VOTE_CREATION) {\r\n        enableVoteCreation = false;\r\n    }\r\n\r\n    function enableVoteCreationOnce() external auth(ENABLE_VOTE_CREATION) {\r\n        enableVoteCreation = true;\r\n    }\r\n\r\n    /**\r\n    * @notice Create a new vote about \"`_metadata`\"\r\n    * @param _executionScript EVM script to be executed on approval\r\n    * @param _metadata Vote metadata\r\n    * @return voteId Id for newly created vote\r\n    */\r\n    function newVote(bytes _executionScript, string _metadata) external auth(CREATE_VOTES_ROLE) returns (uint256 voteId) {\r\n        return _newVote(_executionScript, _metadata, true, true);\r\n    }\r\n\r\n    /**\r\n    * @notice Create a new vote about \"`_metadata`\"\r\n    * @param _executionScript EVM script to be executed on approval\r\n    * @param _metadata Vote metadata\r\n    * @param _castVote Whether to also cast newly created vote\r\n    * @param _executesIfDecided Whether to also immediately execute newly created vote if decided\r\n    * @return voteId id for newly created vote\r\n    */\r\n    function newVote(bytes _executionScript, string _metadata, bool _castVote, bool _executesIfDecided)\r\n        external\r\n        auth(CREATE_VOTES_ROLE)\r\n        returns (uint256 voteId)\r\n    {\r\n        return _newVote(_executionScript, _metadata, _castVote, _executesIfDecided);\r\n    }\r\n\r\n    /**\r\n    * @notice Vote a percentage value in favor of a vote\r\n    * @dev Initialization check is implicitly provided by `voteExists()` as new votes can only be\r\n    *      created via `newVote(),` which requires initialization\r\n    * @param _voteData Packed vote data containing both voteId and the vote in favor percentage (where 0 is no, and 1e18 is yes)\r\n    *          Vote data packing\r\n    * |  yeaPct  |  nayPct  |   voteId  |\r\n    * |  64b     |  64b     |   128b    |\r\n    * @param _supports Whether voter supports the vote (preserved for backward compatibility purposes)\r\n    * @param _executesIfDecided Whether the vote should execute its action if it becomes decided\r\n    */\r\n    function vote(uint256 _voteData, bool _supports, bool _executesIfDecided) external voteExists(_decodeData(_voteData, 0, MAX_UINT_128)) {\r\n        uint256 voteId = _decodeData(_voteData, 0, MAX_UINT_128);\r\n        uint256 nayPct = _decodeData(_voteData, 128, MAX_UINT_64);\r\n        uint256 yeaPct = _decodeData(_voteData, 192, MAX_UINT_64);\r\n\r\n        require(_canVote(voteId, msg.sender), ERROR_CAN_NOT_VOTE);\r\n\r\n        if (yeaPct == 0 && nayPct == 0) {\r\n            // Keep backwards compatibility\r\n            if (_supports) {\r\n                yeaPct = PCT_BASE;\r\n            } else {\r\n                nayPct = PCT_BASE;\r\n            }\r\n        } else {\r\n            require(!_supports && yeaPct.add(nayPct) <= PCT_BASE, ERROR_MALFORMED_CONTINUOUS_VOTE);\r\n        }\r\n        _vote(voteId, yeaPct, nayPct, msg.sender, _executesIfDecided);\r\n    }\r\n\r\n    /**\r\n    * @notice Vote `@formatPct(_yeaPct)`% in favor and `@formatPct(_nayPct)`% against of vote #`_voteId`\r\n    * @dev Initialization check is implicitly provided by `voteExists()` as new votes can only be\r\n    *      created via `newVote(),` which requires initialization\r\n    * @param _voteId Id for vote\r\n    * @param _yeaPct Percentage of support, where 0 is no support, and 1e18 is total support\r\n    * @param _nayPct Percentage of opposition, where 0 is no oposition, and 1e18 is total oposition\r\n    * @param _executesIfDecided Whether the vote should execute its action if it becomes decided\r\n    */\r\n    function votePct(uint256 _voteId, uint256 _yeaPct, uint256 _nayPct, bool _executesIfDecided) external voteExists(_voteId) {\r\n        require(_canVote(_voteId, msg.sender), ERROR_CAN_NOT_VOTE);\r\n        require(_yeaPct.add(_nayPct) <= PCT_BASE, ERROR_MALFORMED_CONTINUOUS_VOTE);\r\n        _vote(_voteId, _yeaPct, _nayPct, msg.sender, _executesIfDecided);\r\n    }\r\n\r\n    /**\r\n    * @notice Execute vote #`_voteId`\r\n    * @dev Initialization check is implicitly provided by `voteExists()` as new votes can only be\r\n    *      created via `newVote(),` which requires initialization\r\n    * @param _voteId Id for vote\r\n    */\r\n    function executeVote(uint256 _voteId) external voteExists(_voteId) {\r\n        _executeVote(_voteId);\r\n    }\r\n\r\n    // Forwarding fns\r\n\r\n    /**\r\n    * @notice Tells whether the Voting app is a forwarder or not\r\n    * @dev IForwarder interface conformance\r\n    * @return Always true\r\n    */\r\n    function isForwarder() external pure returns (bool) {\r\n        return true;\r\n    }\r\n\r\n    /**\r\n    * @notice Creates a vote to execute the desired action, and casts a support vote if possible\r\n    * @dev IForwarder interface conformance\r\n    * @param _evmScript Start vote with script\r\n    */\r\n    function forward(bytes _evmScript) public {\r\n        require(canForward(msg.sender, _evmScript), ERROR_CAN_NOT_FORWARD);\r\n        _newVote(_evmScript, \"\", true, true);\r\n    }\r\n\r\n    /**\r\n    * @notice Tells whether `_sender` can forward actions or not\r\n    * @dev IForwarder interface conformance\r\n    * @param _sender Address of the account intending to forward an action\r\n    * @return True if the given address can create votes, false otherwise\r\n    */\r\n    function canForward(address _sender, bytes) public view returns (bool) {\r\n        // Note that `canPerform()` implicitly does an initialization check itself\r\n        return canPerform(_sender, CREATE_VOTES_ROLE, arr()) && canCreateNewVote(_sender);\r\n    }\r\n\r\n    // Getter fns\r\n\r\n    /**\r\n    * @notice Tells whether a vote #`_voteId` can be executed or not\r\n    * @dev Initialization check is implicitly provided by `voteExists()` as new votes can only be\r\n    *      created via `newVote(),` which requires initialization\r\n    * @return True if the given vote can be executed, false otherwise\r\n    */\r\n    function canExecute(uint256 _voteId) public view voteExists(_voteId) returns (bool) {\r\n        return _canExecute(_voteId);\r\n    }\r\n\r\n    /**\r\n    * @notice Tells whether `_sender` can participate in the vote #`_voteId` or not\r\n    * @dev Initialization check is implicitly provided by `voteExists()` as new votes can only be\r\n    *      created via `newVote(),` which requires initialization\r\n    * @return True if the given voter can participate a certain vote, false otherwise\r\n    */\r\n    function canVote(uint256 _voteId, address _voter) public view voteExists(_voteId) returns (bool) {\r\n        return _canVote(_voteId, _voter);\r\n    }\r\n\r\n    function canCreateNewVote(address _sender) public view returns(bool) {\r\n        return enableVoteCreation && token.balanceOf(_sender) >= minBalance &&  block.timestamp.sub(minTime) >= lastCreateVoteTimes[_sender];\r\n    }\r\n\r\n    /**\r\n    * @dev Return all information for a vote by its ID\r\n    * @param _voteId Vote identifier\r\n    * @return Vote open status\r\n    * @return Vote executed status\r\n    * @return Vote start date\r\n    * @return Vote snapshot block\r\n    * @return Vote support required\r\n    * @return Vote minimum acceptance quorum\r\n    * @return Vote yeas amount\r\n    * @return Vote nays amount\r\n    * @return Vote power\r\n    * @return Vote script\r\n    */\r\n    function getVote(uint256 _voteId)\r\n        public\r\n        view\r\n        voteExists(_voteId)\r\n        returns (\r\n            bool open,\r\n            bool executed,\r\n            uint64 startDate,\r\n            uint64 snapshotBlock,\r\n            uint64 supportRequired,\r\n            uint64 minAcceptQuorum,\r\n            uint256 yea,\r\n            uint256 nay,\r\n            uint256 votingPower,\r\n            bytes script\r\n        )\r\n    {\r\n        Vote storage vote_ = votes[_voteId];\r\n\r\n        open = _isVoteOpen(vote_);\r\n        executed = vote_.executed;\r\n        startDate = vote_.startDate;\r\n        snapshotBlock = vote_.snapshotBlock;\r\n        supportRequired = vote_.supportRequiredPct;\r\n        minAcceptQuorum = vote_.minAcceptQuorumPct;\r\n        yea = vote_.yea;\r\n        nay = vote_.nay;\r\n        votingPower = vote_.votingPower;\r\n        script = vote_.executionScript;\r\n    }\r\n\r\n    /**\r\n    * @dev Return the state of a voter for a given vote by its ID\r\n    * @param _voteId Vote identifier\r\n    * @return VoterState of the requested voter for a certain vote\r\n    */\r\n    function getVoterState(uint256 _voteId, address _voter) public view voteExists(_voteId) returns (VoterState) {\r\n        return votes[_voteId].voters[_voter];\r\n    }\r\n\r\n    // Internal fns\r\n\r\n    /**\r\n    * @dev Internal function to create a new vote\r\n    * @return voteId id for newly created vote\r\n    */\r\n    function _newVote(bytes _executionScript, string _metadata, bool _castVote, bool _executesIfDecided) internal returns (uint256 voteId) {\r\n        require(canCreateNewVote(msg.sender));\r\n        uint64 snapshotBlock = getBlockNumber64() - 1; // avoid double voting in this very block\r\n        uint256 votingPower = token.totalSupplyAt(snapshotBlock);\r\n        require(votingPower > 0, ERROR_NO_VOTING_POWER);\r\n\r\n        voteId = votesLength++;\r\n\r\n        Vote storage vote_ = votes[voteId];\r\n        vote_.startDate = getTimestamp64();\r\n        vote_.snapshotBlock = snapshotBlock;\r\n        vote_.supportRequiredPct = supportRequiredPct;\r\n        vote_.minAcceptQuorumPct = minAcceptQuorumPct;\r\n        vote_.votingPower = votingPower;\r\n        vote_.executionScript = _executionScript;\r\n\r\n        emit StartVote(voteId, msg.sender, _metadata, minBalance, minTime, token.totalSupply(), token.balanceOfAt(msg.sender, snapshotBlock));\r\n\r\n        lastCreateVoteTimes[msg.sender] = getTimestamp64();\r\n\r\n        if (_castVote && _canVote(voteId, msg.sender)) {\r\n            _vote(voteId, PCT_BASE, 0, msg.sender, _executesIfDecided);\r\n        }\r\n    }\r\n\r\n    /**\r\n    * @dev Internal function to cast a vote. It assumes the queried vote exists.\r\n    */\r\n    function _vote(uint256 _voteId, uint256 _yeaPct, uint256 _nayPct, address _voter, bool _executesIfDecided) internal {\r\n        Vote storage vote_ = votes[_voteId];\r\n\r\n        VoterState state = vote_.voters[_voter];\r\n        require(state == VoterState.Absent, \"Can't change votes\");\r\n        // This could re-enter, though we can assume the governance token is not malicious\r\n        uint256 balance = token.balanceOfAt(_voter, vote_.snapshotBlock);\r\n        uint256 voterStake = uint256(2).mul(balance).mul(vote_.startDate.add(voteTime).sub(getTimestamp64())).div(voteTime);\r\n        if(voterStake > balance) {\r\n            voterStake = balance;\r\n        }\r\n\r\n        uint256 yea = voterStake.mul(_yeaPct).div(PCT_BASE);\r\n        uint256 nay = voterStake.mul(_nayPct).div(PCT_BASE);\r\n\r\n        if (yea > 0) {\r\n            vote_.yea = vote_.yea.add(yea);\r\n        }\r\n        if (nay > 0) {\r\n            vote_.nay = vote_.nay.add(nay);\r\n        }\r\n\r\n        vote_.voters[_voter] = yea == nay ? VoterState.Even : yea > nay ? VoterState.Yea : VoterState.Nay;\r\n\r\n        if (yea > 0) {\r\n          emit CastVote(_voteId, _voter, true, yea);\r\n        }\r\n        if (nay > 0) {\r\n          emit CastVote(_voteId, _voter, false, nay);\r\n        }\r\n\r\n        if (_executesIfDecided && _canExecute(_voteId)) {\r\n            // We've already checked if the vote can be executed with `_canExecute()`\r\n            _unsafeExecuteVote(_voteId);\r\n        }\r\n    }\r\n\r\n    /**\r\n    * @dev Internal function to execute a vote. It assumes the queried vote exists.\r\n    */\r\n    function _executeVote(uint256 _voteId) internal {\r\n        require(_canExecute(_voteId), ERROR_CAN_NOT_EXECUTE);\r\n        _unsafeExecuteVote(_voteId);\r\n    }\r\n\r\n    /**\r\n    * @dev Unsafe version of _executeVote that assumes you have already checked if the vote can be executed and exists\r\n    */\r\n    function _unsafeExecuteVote(uint256 _voteId) internal {\r\n        Vote storage vote_ = votes[_voteId];\r\n\r\n        vote_.executed = true;\r\n\r\n        bytes memory input = new bytes(0); // TODO: Consider input for voting scripts\r\n        runScript(vote_.executionScript, input, new address[](0));\r\n\r\n        emit ExecuteVote(_voteId);\r\n    }\r\n\r\n    /**\r\n    * @dev Internal function to check if a vote can be executed. It assumes the queried vote exists.\r\n    * @return True if the given vote can be executed, false otherwise\r\n    */\r\n    function _canExecute(uint256 _voteId) internal view returns (bool) {\r\n        Vote storage vote_ = votes[_voteId];\r\n\r\n        if(_isVoteOpen(vote_)) {\r\n            return false;\r\n        }\r\n\r\n        if (vote_.executed) {\r\n            return false;\r\n        }\r\n\r\n        // Voting is already decided\r\n        if (_isValuePct(vote_.yea, vote_.votingPower, vote_.supportRequiredPct)) {\r\n            return true;\r\n        }\r\n\r\n        // Vote ended?\r\n        if (_isVoteOpen(vote_)) {\r\n            return false;\r\n        }\r\n        // Has enough support?\r\n        uint256 totalVotes = vote_.yea.add(vote_.nay);\r\n        if (!_isValuePct(vote_.yea, totalVotes, vote_.supportRequiredPct)) {\r\n            return false;\r\n        }\r\n        // Has min quorum?\r\n        if (!_isValuePct(vote_.yea, vote_.votingPower, vote_.minAcceptQuorumPct)) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    /**\r\n    * @dev Internal function to check if a voter can participate on a vote. It assumes the queried vote exists.\r\n    * @return True if the given voter can participate a certain vote, false otherwise\r\n    */\r\n    function _canVote(uint256 _voteId, address _voter) internal view returns (bool) {\r\n        Vote storage vote_ = votes[_voteId];\r\n        return _isVoteOpen(vote_) && token.balanceOfAt(_voter, vote_.snapshotBlock) > 0;\r\n    }\r\n\r\n    /**\r\n    * @dev Internal function to check if a vote is still open\r\n    * @return True if the given vote is open, false otherwise\r\n    */\r\n    function _isVoteOpen(Vote storage vote_) internal view returns (bool) {\r\n        return getTimestamp64() < vote_.startDate.add(voteTime) && !vote_.executed;\r\n    }\r\n\r\n    /**\r\n    * @dev Calculates whether `_value` is more than a percentage `_pct` of `_total`\r\n    */\r\n    function _isValuePct(uint256 _value, uint256 _total, uint256 _pct) internal pure returns (bool) {\r\n        if (_total == 0) {\r\n            return false;\r\n        }\r\n\r\n        uint256 computedPct = _value.mul(PCT_BASE) / _total;\r\n        return computedPct > _pct;\r\n    }\r\n\r\n    /**\r\n    * @dev Decodes data by performing bitwise operations.\r\n    * @param _value Value containing the data\r\n    * @param _shiftValue Number of bits to shift to the right\r\n    * @param _maskValue Number of bits to apply as a mask to the value\r\n     */\r\n    function _decodeData(uint256 _value, uint256 _shiftValue, uint256 _maskValue) internal pure returns(uint256) {\r\n        return uint256((_value >> _shiftValue) & _maskValue);\r\n    }\r\n}","deployed_bytecode":"0x6080604052600436106102715763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630803fac081146102765780631aa430781461029f5780631e526610146102c65780632914b9bd146102eb5780632d5735011461036d57806332f0a3b51461039b5780633c624c75146103b05780634b12311c146103c55780635a55c1f01461041a5780635eb243321461054157806362de7e5a146105635780637bbddcfc146105785780637c1d0b87146105a65780637e7db6e1146105c857806380afdea8146105f6578063868ce31a1461060b5780638b3dd749146106205780638b5683271461063557806393f89a801461064a5780639d4941d814610662578063a1658fad14610690578063a479e50814610704578063a87f862414610719578063b6f6825414610774578063b879572514610789578063bcf93dd61461079e578063be2c64d4146107d0578063c0774df3146107e5578063c54c24b514610859578063c5bb87581461086e578063c91d956c14610883578063cc63604a1461089b578063cdb2867b146108b3578063d4aae0c4146108e4578063d5db2c80146108f9578063d948d46814610925578063dc177eec1461097e578063dc474b1a14610993578063de4796ed146109a8578063de4f6347146109bd578063df133bca146109d2578063df136602146109f4578063df35219714610a09578063eb1e3b7714610a1e578063ee0f160e14610a33578063f4b0051314610a48578063f98a4eca14610a7e578063fad167ab14610a96578063fc0c546a14610aab578063fc157cb414610ac0578063fd64eccb14610ad5578063ff31183814610aea575b600080fd5b34801561028257600080fd5b5061028b610aff565b604080519115158252519081900360200190f35b3480156102ab57600080fd5b506102b4610b29565b60408051918252519081900360200190f35b3480156102d257600080fd5b506102e96004356024356044356064351515610b2f565b005b3480156102f757600080fd5b506040805160206004803580820135601f8101849004840285018401909552848452610344943694929360249392840191908190840183828082843750949750610d809650505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561037957600080fd5b5061028b73ffffffffffffffffffffffffffffffffffffffff60043516610e8c565b3480156103a757600080fd5b50610344610f90565b3480156103bc57600080fd5b506102b461102f565b3480156103d157600080fd5b506103f660043573ffffffffffffffffffffffffffffffffffffffff60243516611053565b6040518082600381111561040657fe5b60ff16815260200191505060405180910390f35b34801561042657600080fd5b50610432600435611139565b604051808b1515151581526020018a1515151581526020018967ffffffffffffffff1667ffffffffffffffff1681526020018867ffffffffffffffff1667ffffffffffffffff1681526020018767ffffffffffffffff1667ffffffffffffffff1681526020018667ffffffffffffffff1667ffffffffffffffff16815260200185815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156104fd5781810151838201526020016104e5565b50505050905090810190601f16801561052a5780820380516001836020036101000a031916815260200191505b509b50505050505050505050505060405180910390f35b34801561054d57600080fd5b506102e967ffffffffffffffff6004351661134f565b34801561056f57600080fd5b506102b461156b565b34801561058457600080fd5b506102b473ffffffffffffffffffffffffffffffffffffffff6004351661158f565b3480156105b257600080fd5b506102e967ffffffffffffffff600435166115a1565b3480156105d457600080fd5b5061028b73ffffffffffffffffffffffffffffffffffffffff60043516611886565b34801561060257600080fd5b506102b461188c565b34801561061757600080fd5b506102b46118bc565b34801561062c57600080fd5b506102b46118e0565b34801561064157600080fd5b506102b461190b565b34801561065657600080fd5b506102e9600435611911565b34801561066e57600080fd5b506102e973ffffffffffffffffffffffffffffffffffffffff60043516611ad6565b34801561069c57600080fd5b50604080516020600460443581810135838102808601850190965280855261028b95833573ffffffffffffffffffffffffffffffffffffffff16956024803596369695606495939492019291829185019084908082843750949750611df89650505050505050565b34801561071057600080fd5b50610344611f88565b34801561072557600080fd5b506102e973ffffffffffffffffffffffffffffffffffffffff6004351667ffffffffffffffff6024358116906044358116906064351660843560a43560c43560e435610104356101243561204a565b34801561078057600080fd5b506102b461275f565b34801561079557600080fd5b506102b4612783565b3480156107aa57600080fd5b506107b3612789565b6040805167ffffffffffffffff9092168252519081900360200190f35b3480156107dc57600080fd5b506102b46127a5565b3480156107f157600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261028b95833573ffffffffffffffffffffffffffffffffffffffff169536956044949193909101919081908401838280828437509497506127c99650505050505050565b34801561086557600080fd5b506102b4612814565b34801561087a57600080fd5b506102b4612838565b34801561088f57600080fd5b506102e960043561283e565b3480156108a757600080fd5b5061028b600435612a01565b3480156108bf57600080fd5b5061028b60043573ffffffffffffffffffffffffffffffffffffffff60243516612ab9565b3480156108f057600080fd5b50610344612b71565b34801561090557600080fd5b506102b46024600480358281019290820135918135918201910135612b9c565b34801561093157600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526102e9943694929360249392840191908190840183828082843750949750612cf09650505050505050565b34801561098a57600080fd5b506102e9612db9565b34801561099f57600080fd5b506107b3612ec2565b3480156109b457600080fd5b5061028b612ed2565b3480156109c957600080fd5b506102b4612f03565b3480156109de57600080fd5b506102e960043560243515156044351515612f09565b348015610a0057600080fd5b506102e96131cd565b348015610a1557600080fd5b506102b46132d9565b348015610a2a57600080fd5b506102b46132df565b348015610a3f57600080fd5b5061028b6132e5565b348015610a5457600080fd5b506102b46024600480358281019290820135918135918201910135604435151560643515156132ee565b348015610a8a57600080fd5b506102e9600435613443565b348015610aa257600080fd5b506107b36134ee565b348015610ab757600080fd5b50610344613516565b348015610acc57600080fd5b506107b3613532565b348015610ae157600080fd5b5061028b61353e565b348015610af657600080fd5b506102b4613543565b600080610b0a6118e0565b90508015801590610b22575080610b1f613567565b10155b91505b5090565b60075481565b600a5460408051808201909152600e81527f564f54494e475f4e4f5f564f5445000000000000000000000000000000000000602082015285918210610c0c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610bd1578181015183820152602001610bb9565b50505050905090810190601f168015610bfe5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50610c17853361356b565b60408051808201909152601381527f564f54494e475f43414e5f4e4f545f564f5445000000000000000000000000006020820152901515610cb4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50670de0b6b3a7640000610cce858563ffffffff61365216565b60408051808201909152601981527f4d414c464f524d45445f434f4e54494e554f55535f564f5445000000000000006020820152911015610d6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50610d7985858533866136f7565b5050505050565b6000610d8a611f88565b73ffffffffffffffffffffffffffffffffffffffff166304bf2a7f836040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610e0e578181015183820152602001610df6565b50505050905090810190601f168015610e3b5780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b158015610e5a57600080fd5b505af1158015610e6e573d6000803e3d6000fd5b505050506040513d6020811015610e8457600080fd5b505192915050565b60085460009060ff168015610f46575060065460008054604080517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152915191909216926370a0823192602480820193602093909283900390910190829087803b158015610f1757600080fd5b505af1158015610f2b573d6000803e3d6000fd5b505050506040513d6020811015610f4157600080fd5b505110155b8015610f8a575073ffffffffffffffffffffffffffffffffffffffff82166000908152600b6020526040902054600754610f8790429063ffffffff613b1916565b10155b92915050565b6000610f9a612b71565b73ffffffffffffffffffffffffffffffffffffffff166332f0a3b56040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015610ffd57600080fd5b505af1158015611011573d6000803e3d6000fd5b505050506040513d602081101561102757600080fd5b505190505b90565b7fad15e7261800b4bb73f1b69d3864565ffb1fd00cb93cf14fe48da8f1f2149f3981565b600a5460408051808201909152600e81527f564f54494e475f4e4f5f564f5445000000000000000000000000000000000000602082015260009184919082106110f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50600084815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845260060190915290205460ff1691505b5092915050565b6000806000806000806000806000606060008b600a5481106040805190810160405280600e81526020017f564f54494e475f4e4f5f564f54450000000000000000000000000000000000008152509015156111f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5060008d8152600960205260409020915061120a82613bc4565b9b508160000160009054906101000a900460ff169a508160000160019054906101000a900467ffffffffffffffff1699508160000160099054906101000a900467ffffffffffffffff1698508160000160119054906101000a900467ffffffffffffffff1697508160010160009054906101000a900467ffffffffffffffff169650816002015495508160030154945081600401549350816005018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156113395780601f1061130e57610100808354040283529160200191611339565b820191906000526020600020905b81548152906001019060200180831161131c57829003601f168201915b5050505050925050509193959799509193959799565b6001547fad15e7261800b4bb73f1b69d3864565ffb1fd00cb93cf14fe48da8f1f2149f399061138b9067ffffffffffffffff8085169116613c27565b611396338383611df8565b60408051808201909152600f81527f4150505f415554485f4641494c454400000000000000000000000000000000006020820152901515611433576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5060005460408051808201909152601981527f564f54494e475f4348414e47455f51554f52554d5f504354530000000000000060208201529067ffffffffffffffff74010000000000000000000000000000000000000000909104811690851611156114fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b506001805467ffffffffffffffff85167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909116811790915560408051918252517f3172f2e9273c729c2a47cc8bf7e7f18506e3e3035126d562602bd2155bc78a509181900360200190a1505050565b7fda3972983e62bdf826c4b807c4c9c2b8a941e1f83dfa76d53d6aeac11e1be65081565b600b6020526000908152604090205481565b6000547fda3972983e62bdf826c4b807c4c9c2b8a941e1f83dfa76d53d6aeac11e1be650906115f59067ffffffffffffffff8085169174010000000000000000000000000000000000000000900416613c27565b611600338383611df8565b60408051808201909152600f81527f4150505f415554485f4641494c45440000000000000000000000000000000000602082015290151561169d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5060015460408051808201909152601a81527f564f54494e475f4348414e47455f535550504f52545f5043545300000000000060208201529067ffffffffffffffff8086169116111561174c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5060408051808201909152601a81527f564f54494e475f4348414e47455f535550505f544f4f5f4249470000000000006020820152670de0b6b3a764000067ffffffffffffffff8516106117fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b506000805467ffffffffffffffff85167401000000000000000000000000000000000000000081027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff9092169190911790915560408051918252517f903b617f7f36eb047a29b89d1bf7885fdae31d250c3320fccf11d045c11b396e9181900360200190a1505050565b50600190565b60006118b77fd625496217aa6a3453eecb9c3489dc5a53e6c67b444329ea2b2cbc9ff547639b613c82565b905090565b7fecb50dc3e77ba8a59697a3cc090a29b4cbd3c1f2b6b3aea524e0d166969592b981565b60006118b77febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e613c82565b60035481565b604080516000808252602082019092527fe7ab0252519cd959720b328191bed7fe61b8e25f77613877be7070646d12daf0916119539133918491905b50611df8565b60408051808201909152600f81527f4150505f415554485f4641494c4544000000000000000000000000000000000060208201529015156119f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50816004548110158015611a0657506005548111155b1515611a9957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d696e2074696d652073686f756c642062652077697468696e20696e6974696160448201527f6c697a6174696f6e2068617264636f646564206c696d69747300000000000000606482015290519081900360840190fd5b60078390556040805184815290517fcb34d0577abe5b2f96b65ea1bb5de2209ba6309c6909438c6d50dd277ca3b5809181900360200190a1505050565b6000806000611ae484611886565b60408051808201909152601281527f5245434f5645525f444953414c4c4f57454400000000000000000000000000006020820152901515611b81576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50611b8a610f90565b9250611b9583613c8a565b60408051808201909152601a81527f5245434f5645525f5641554c545f4e4f545f434f4e54524143540000000000006020820152901515611c32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5073ffffffffffffffffffffffffffffffffffffffff84161515611c9d576040513031925073ffffffffffffffffffffffffffffffffffffffff84169083156108fc029084906000818181858888f19350505050158015611c97573d6000803e3d6000fd5b50611d8d565b5082611cc573ffffffffffffffffffffffffffffffffffffffff82163063ffffffff613cbd16565b9150611cee73ffffffffffffffffffffffffffffffffffffffff8216848463ffffffff613df616565b60408051808201909152601d81527f5245434f5645525f544f4b454e5f5452414e534645525f4641494c45440000006020820152901515611d8b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b505b8373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f596caf56044b55fb8c4ca640089bbc2b63cae3e978b851f5745cbb7c5b288e02846040518082815260200191505060405180910390a350505050565b600080611e03610aff565b1515611e125760009150611f80565b611e1a612b71565b905073ffffffffffffffffffffffffffffffffffffffff81161515611e425760009150611f80565b8073ffffffffffffffffffffffffffffffffffffffff1663fdef9106863087611e6a88613e8e565b6040517c010000000000000000000000000000000000000000000000000000000063ffffffff871602815273ffffffffffffffffffffffffffffffffffffffff808616600483019081529085166024830152604482018490526080606483019081528351608484015283519192909160a490910190602085019080838360005b83811015611f02578181015183820152602001611eea565b50505050905090810190601f168015611f2f5780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b158015611f5157600080fd5b505af1158015611f65573d6000803e3d6000fd5b505050506040513d6020811015611f7b57600080fd5b505191505b509392505050565b600080611f93612b71565b604080517fbe00bbd80000000000000000000000000000000000000000000000000000000081527fd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb60048201527fddbcfd564f642ab5627cf68b9b7d374fb4f8a36e941a75d89c87998cef03bd616024820152905173ffffffffffffffffffffffffffffffffffffffff929092169163be00bbd8916044808201926020929091908290030181600087803b158015610e5a57600080fd5b60006120546118e0565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a45440000000000000000602082015290156120f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50604080517f4352454154455f564f5445535f524f4c45000000000000000000000000000000815290519081900360110190207fe7dcd7275292e064d090fbc5f3bd7995be23b502c1fed5cd94cfddbbdcd32bbc1461214b57fe5b604080517f4d4f444946595f535550504f52545f524f4c4500000000000000000000000000815290519081900360130190207fda3972983e62bdf826c4b807c4c9c2b8a941e1f83dfa76d53d6aeac11e1be650146121a557fe5b604080517f4d4f444946595f51554f52554d5f524f4c450000000000000000000000000000815290519081900360120190207fad15e7261800b4bb73f1b69d3864565ffb1fd00cb93cf14fe48da8f1f2149f39146121ff57fe5b604080517f5345545f4d494e5f42414c414e43455f524f4c45000000000000000000000000815290519081900360140190207fb1f3f26f63ad27cd630737a426f990492f5c674208299d6fb23bb2b0733d3d661461225957fe5b604080517f5345545f4d494e5f54494d455f524f4c45000000000000000000000000000000815290519081900360110190207fe7ab0252519cd959720b328191bed7fe61b8e25f77613877be7070646d12daf0146122b357fe5b604080517f44495341424c455f564f54455f4352454154494f4e0000000000000000000000815290519081900360150190207f40b01f8b31b51596de2eeab8c325ff77cc3695c1c1875d66ff31176e7148d2a11461230d57fe5b604080517f454e41424c455f564f54455f4352454154494f4e000000000000000000000000815290519081900360140190207fecb50dc3e77ba8a59697a3cc090a29b4cbd3c1f2b6b3aea524e0d166969592b91461236757fe5b61236f613e98565b60408051808201909152601081527f564f54494e475f494e49545f5043545300000000000000000000000000000000602082015267ffffffffffffffff808c16908b16111561241a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5060408051808201909152601b81527f564f54494e475f494e49545f535550504f52545f544f4f5f42494700000000006020820152670de0b6b3a764000067ffffffffffffffff8c16106124ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b508487101580156124db5750838711155b15156124e657600080fd5b8286101580156124f65750818611155b151561250157600080fd5b8a6000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555089600060146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555088600160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555087600160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561264157600080fd5b505af1158015612655573d6000803e3d6000fd5b505050506040513d602081101561266b57600080fd5b505160ff16600a0a9050612685878263ffffffff613f7716565b600655600786905561269d858263ffffffff613f7716565b6002556126b0848263ffffffff613f7716565b6003556004839055600582905560065460408051918252517fbd5318adc778260bd213cc16f3ef06cfb4f729adb9309495fed0e10abc61c3759181900360200190a160075460408051918252517fcb34d0577abe5b2f96b65ea1bb5de2209ba6309c6909438c6d50dd277ca3b5809181900360200190a15050600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505050505050565b7fb1f3f26f63ad27cd630737a426f990492f5c674208299d6fb23bb2b0733d3d6681565b60045481565b60015468010000000000000000900467ffffffffffffffff1681565b7fe7dcd7275292e064d090fbc5f3bd7995be23b502c1fed5cd94cfddbbdcd32bbc81565b60006127fd837fe7dcd7275292e064d090fbc5f3bd7995be23b502c1fed5cd94cfddbbdcd32bbc6127f8614039565b611df8565b801561280d575061280d83610e8c565b9392505050565b7fe7ab0252519cd959720b328191bed7fe61b8e25f77613877be7070646d12daf081565b60065481565b604080516000808252602082019092527fb1f3f26f63ad27cd630737a426f990492f5c674208299d6fb23bb2b0733d3d669161287e91339184919061194d565b60408051808201909152600f81527f4150505f415554485f4641494c45440000000000000000000000000000000000602082015290151561291b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5081600254811015801561293157506003548111155b15156129c457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f4d696e2062616c616e63652073686f756c642062652077697468696e20696e6960448201527f7469616c697a6174696f6e2068617264636f646564206c696d69747300000000606482015290519081900360840190fd5b60068390556040805184815290517fbd5318adc778260bd213cc16f3ef06cfb4f729adb9309495fed0e10abc61c3759181900360200190a1505050565b600a5460408051808201909152600e81527f564f54494e475f4e4f5f564f544500000000000000000000000000000000000060208201526000918391908210612aa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50612ab08361404b565b91505b50919050565b600a5460408051808201909152600e81527f564f54494e475f4e4f5f564f544500000000000000000000000000000000000060208201526000918491908210612b5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50612b69848461356b565b949350505050565b60006118b77f4172f0f7d2289153072b0a6ca36959e0cbe2efc3afe50fc81636caa96338137b613c82565b604080516000808252602082019092527fe7dcd7275292e064d090fbc5f3bd7995be23b502c1fed5cd94cfddbbdcd32bbc90612bdc90339083908561194d565b60408051808201909152600f81527f4150505f415554485f4641494c454400000000000000000000000000000000006020820152901515612c79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50612ce686868080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f8c018190048102820181019092528a815294508a9350899250829150840183828082843782019150505050505060018061417a565b9695505050505050565b612cfa33826127c9565b60408051808201909152601681527f564f54494e475f43414e5f4e4f545f464f5257415244000000000000000000006020820152901515612d97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50612db581602060405190810160405280600081525060018061417a565b5050565b604080516000808252602082019092527f40b01f8b31b51596de2eeab8c325ff77cc3695c1c1875d66ff31176e7148d2a191612df991339184919061194d565b60408051808201909152600f81527f4150505f415554485f4641494c454400000000000000000000000000000000006020820152901515612e96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5050600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60015467ffffffffffffffff1681565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612efd6118e0565b14905090565b600a5481565b60008080612f2886826fffffffffffffffffffffffffffffffff6146bb565b600a5460408051808201909152600e81527f564f54494e475f4e4f5f564f54450000000000000000000000000000000000006020820152908210612fc8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50612fe58760006fffffffffffffffffffffffffffffffff6146bb565b9350612ffb87608067ffffffffffffffff6146bb565b92506130118760c067ffffffffffffffff6146bb565b915061301d843361356b565b60408051808201909152601381527f564f54494e475f43414e5f4e4f545f564f54450000000000000000000000000060208201529015156130ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50811580156130c7575082155b156130f35785156130e257670de0b6b3a764000091506130ee565b670de0b6b3a764000092505b6131b7565b851580156131185750670de0b6b3a7640000613115838563ffffffff61365216565b11155b60408051808201909152601981527f4d414c464f524d45445f434f4e54494e554f55535f564f54450000000000000060208201529015156131b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b505b6131c484838533896136f7565b50505050505050565b604080516000808252602082019092527fecb50dc3e77ba8a59697a3cc090a29b4cbd3c1f2b6b3aea524e0d166969592b99161320d91339184919061194d565b60408051808201909152600f81527f4150505f415554485f4641494c4544000000000000000000000000000000000060208201529015156132aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5050600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60055481565b60025481565b60085460ff1681565b604080516000808252602082019092527fe7dcd7275292e064d090fbc5f3bd7995be23b502c1fed5cd94cfddbbdcd32bbc9061332e90339083908561194d565b60408051808201909152600f81527f4150505f415554485f4641494c4544000000000000000000000000000000000060208201529015156133cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5061343788888080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f8e018190048102820181019092528c815294508c93508b92508291508401838280828437820191505050505050868661417a565b98975050505050505050565b600a5460408051808201909152600e81527f564f54494e475f4e4f5f564f54450000000000000000000000000000000000006020820152829182106134e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50612db5826146c8565b60005474010000000000000000000000000000000000000000900467ffffffffffffffff1681565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b670de0b6b3a764000081565b600190565b7f40b01f8b31b51596de2eeab8c325ff77cc3695c1c1875d66ff31176e7148d2a181565b4390565b600082815260096020526040812061358281613bc4565b8015612b695750600080548254604080517f4ee2cd7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152690100000000000000000090930467ffffffffffffffff16602482015290519190921691634ee2cd7e91604480830192602092919082900301818787803b15801561361d57600080fd5b505af1158015613631573d6000803e3d6000fd5b505050506040513d602081101561364757600080fd5b505111949350505050565b60408051808201909152601181527f4d4154485f4144445f4f564552464c4f5700000000000000000000000000000060208201526000908383019084821015611f80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b600085815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845260068101909252822054909160ff909116908080808085600381111561374357fe5b146137af57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f43616e2774206368616e676520766f7465730000000000000000000000000000604482015290519081900360640190fd5b600080548754604080517f4ee2cd7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d81166004830152690100000000000000000090930467ffffffffffffffff16602482015290519190921692634ee2cd7e92604480820193602093909283900390910190829087803b15801561384657600080fd5b505af115801561385a573d6000803e3d6000fd5b505050506040513d602081101561387057600080fd5b505160015490945061391d9068010000000000000000900467ffffffffffffffff166139116138ea6138a061477b565b6001548b546138d49161010090910467ffffffffffffffff908116916801000000000000000090041663ffffffff61478d16565b67ffffffffffffffff169063ffffffff61483f16565b67ffffffffffffffff1661390560028963ffffffff613f7716565b9063ffffffff613f7716565b9063ffffffff6148ef16565b92508383111561392b578392505b613947670de0b6b3a7640000613911858d63ffffffff613f7716565b9150613965670de0b6b3a7640000613911858c63ffffffff613f7716565b9050600082111561398b576002860154613985908363ffffffff61365216565b60028701555b60008111156139af5760038601546139a9908263ffffffff61365216565b60038701555b8082146139cc578082116139c45760026139c7565b60015b6139cf565b60035b73ffffffffffffffffffffffffffffffffffffffff89166000908152600688016020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001836003811115613a2857fe5b02179055506000821115613a8d57604080516001815260208101849052815173ffffffffffffffffffffffffffffffffffffffff8b16928e927fb34ee265e3d4f5ec4e8b52d59b2a9be8fceca2f274ebc080d8fba797fea9391f929081900390910190a35b6000811115613aed57604080516000815260208101839052815173ffffffffffffffffffffffffffffffffffffffff8b16928e927fb34ee265e3d4f5ec4e8b52d59b2a9be8fceca2f274ebc080d8fba797fea9391f929081900390910190a35b868015613afe5750613afe8b61404b565b15613b0c57613b0c8b6149a6565b5050505050505050505050565b60408051808201909152601281527f4d4154485f5355425f554e444552464c4f5700000000000000000000000000006020820152600090819084841115613bbc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b505050900390565b6001548154600091613bfa91610100900467ffffffffffffffff908116916801000000000000000090041663ffffffff61478d16565b67ffffffffffffffff16613c0c61477b565b67ffffffffffffffff16108015610f8a5750505460ff161590565b604080516002808252606080830184529260208301908038833901905050905082816000815181101515613c5757fe5b602090810290910101528051829082906001908110613c7257fe5b6020908102909101015292915050565b5490565b5490565b60008073ffffffffffffffffffffffffffffffffffffffff83161515613cb35760009150612ab3565b50506000903b1190565b6040805173ffffffffffffffffffffffffffffffffffffffff83166024808301919091528251808303909101815260449091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a08231000000000000000000000000000000000000000000000000000000001790526000908180613d4a8684614ad9565b60408051808201909152601c81527f534146455f4552435f32305f42414c414e43455f52455645525445440000000060208201529193509150821515613dec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5095945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052600090613e858582614b0a565b95945050505050565b8051602002815290565b613ea06118e0565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a4544000000000000000060208201529015613f3c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50613f75613f48613567565b7febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e9063ffffffff614b5816565b565b600080831515613f8a5760009150611132565b50828202828482811515613f9a57fe5b60408051808201909152601181527f4d4154485f4d554c5f4f564552464c4f5700000000000000000000000000000060208201529291900414611f80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b60408051600081526020810190915290565b60008181526009602052604081208161406382613bc4565b156140715760009250614173565b815460ff16156140845760009250614173565b6002820154600483015483546140ba92919071010000000000000000000000000000000000900467ffffffffffffffff16614b5c565b156140c85760019250614173565b6140d182613bc4565b156140df5760009250614173565b600382015460028301546140f89163ffffffff61365216565b6002830154835491925061412c91839071010000000000000000000000000000000000900467ffffffffffffffff16614b5c565b151561413b5760009250614173565b60028201546004830154600184015461415f92919067ffffffffffffffff16614b5c565b151561416e5760009250614173565b600192505b5050919050565b60008060008061418933610e8c565b151561419457600080fd5b600161419e614b9e565b60008054604080517f981b24d00000000000000000000000000000000000000000000000000000000081529490930367ffffffffffffffff81166004860152925192965073ffffffffffffffffffffffffffffffffffffffff169263981b24d09260248083019360209383900390910190829087803b15801561422057600080fd5b505af1158015614234573d6000803e3d6000fd5b505050506040513d602081101561424a57600080fd5b505160408051808201909152601681527f564f54494e475f4e4f5f564f54494e475f504f574552000000000000000000006020820152909250600083116142ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5050600a805460018101909155600081815260096020526040902090935061431361477b565b81547fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff1661010067ffffffffffffffff92831602177fffffffffffffffffffffffffffffff0000000000000000ffffffffffffffffff16690100000000000000000085831602178083556000547fffffffffffffff0000000000000000ffffffffffffffffffffffffffffffffff9091167401000000000000000000000000000000000000000090910482167101000000000000000000000000000000000002178255600180549083018054919092167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090911617905560048101829055875161442690600583019060208b0190615335565b503373ffffffffffffffffffffffffffffffffffffffff16847f0730610a5322c6584fb6f5bb760719e650c888cfd965a2beb2d598bcd425e394896006546007546000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156144ec57600080fd5b505af1158015614500573d6000803e3d6000fd5b505050506040513d602081101561451657600080fd5b505160008054604080517f4ee2cd7e00000000000000000000000000000000000000000000000000000000815233600482015267ffffffffffffffff8e166024820152905173ffffffffffffffffffffffffffffffffffffffff90921692634ee2cd7e926044808401936020939083900390910190829087803b15801561459c57600080fd5b505af11580156145b0573d6000803e3d6000fd5b505050506040513d60208110156145c657600080fd5b5051604080516020818101879052918101859052606081018490526080810183905260a080825287519082015286519091829160c083019189019080838360005b8381101561461f578181015183820152602001614607565b50505050905090810190601f16801561464c5780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a361466561477b565b336000908152600b6020526040902067ffffffffffffffff9190911690558580156146955750614695843361356b565b156146b0576146b084670de0b6b3a7640000600033896136f7565b505050949350505050565b60029190910a9091041690565b6146d18161404b565b60408051808201909152601681527f564f54494e475f43414e5f4e4f545f4558454355544500000000000000000000602082015290151561476e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50614778816149a6565b50565b60006118b7614788614bab565b614baf565b60408051808201909152601381527f4d41544836345f4144445f4f564552464c4f570000000000000000000000000060208201526000908383019067ffffffffffffffff8086169083161015611f80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b60408051808201909152601481527f4d41544836345f5355425f554e444552464c4f570000000000000000000000006020820152600090819067ffffffffffffffff8086169085161115613bbc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b60408051808201909152600d81527f4d4154485f4449565f5a45524f0000000000000000000000000000000000000060208201526000908190818411614991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50828481151561499d57fe5b04949350505050565b600081815260096020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811782558251948552600582018054600292811615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff011691909104601f81018590048502860184018452938501848152919493614aa893850182828015614a8b5780601f10614a6057610100808354040283529160200191614a8b565b820191906000526020600020905b815481529060010190602001808311614a6e57829003601f168201915b50506040805160008152602081019091528693509150614c5f9050565b5060405183907fbf8e2b108bb7c980e08903a8a46527699d5e84905a082d56dacb4150725c8cab90600090a2505050565b6000806000806040516020818751602089018a5afa92506000831115614afe57805191505b50909590945092505050565b6000806040516020818551602087016000895af16000811115614b4e573d8015614b3b5760208114614b4457614b4c565b60019350614b4c565b600183511493505b505b5090949350505050565b9055565b600080831515614b6f5760009150611f80565b83614b8886670de0b6b3a764000063ffffffff613f7716565b811515614b9157fe5b0492909211949350505050565b60006118b7614788613567565b4290565b60408051808201909152601581527f55494e5436345f4e554d4245525f544f4f5f4249470000000000000000000000602082015260009067ffffffffffffffff831115614c58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5090919050565b6060600080606080614c6f610aff565b60408051808201909152601481527f494e49545f4e4f545f494e495449414c495a45440000000000000000000000006020820152901515614d0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50600080614d18612b71565b9150614d2261188c565b9050614d2d8a610d80565b60408051808201909152601b81527f45564d52554e5f4558454355544f525f554e415641494c41424c450000000000602082015290965073ffffffffffffffffffffffffffffffffffffffff87161515614de3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b506040516060602482019081528b5160848301528b517f279cea3500000000000000000000000000000000000000000000000000000000975087928d928d928d9282916044820191606481019160a490910190602089019080838360005b83811015614e59578181015183820152602001614e41565b50505050905090810190601f168015614e865780820380516001836020036101000a031916815260200191505b50848103835286518152865160209182019188019080838360005b83811015614eb9578181015183820152602001614ea1565b50505050905090810190601f168015614ee65780820380516001836020036101000a031916815260200191505b508481038252855181528551602091820191808801910280838360005b83811015614f1b578181015183820152602001614f03565b505050509050019650505050505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509350600080855160208701895af4604051935080801561502057603f3d118015614fbe5760203d03806020883e860160405261501a565b7f08c379a000000000000000000000000000000000000000000000000000000000865260206004870152601e60248701527f45564d52554e5f4558454355544f525f494e56414c49445f52455455524e00006044870152606486fd5b50615029565b3d6000863e3d85fd5b50508573ffffffffffffffffffffffffffffffffffffffff167f5229a5dba83a54ae8cb5b51bdd6de9474cacbe9dd332f5185f3a4f4f2e3f4ad98b8b8660405180806020018060200180602001848103845287818151815260200191508051906020019080838360005b838110156150ab578181015183820152602001615093565b50505050905090810190601f1680156150d85780820380516001836020036101000a031916815260200191505b50848103835286518152865160209182019188019080838360005b8381101561510b5781810151838201526020016150f3565b50505050905090810190601f1680156151385780820380516001836020036101000a031916815260200191505b50848103825285518152855160209182019187019080838360005b8381101561516b578181015183820152602001615153565b50505050905090810190601f1680156151985780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a28296508173ffffffffffffffffffffffffffffffffffffffff166151cb612b71565b73ffffffffffffffffffffffffffffffffffffffff16146040805190810160405280601f81526020017f45564d52554e5f50524f5445435445445f53544154455f4d4f44494649454400815250901515615281576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b508061528b61188c565b60408051808201909152601f81527f45564d52554e5f50524f5445435445445f53544154455f4d4f4449464945440060208201529114615327576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b505050505050509392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061537657805160ff19168380011785556153a3565b828001600101855582156153a3579182015b828111156153a3578251825591602001919060010190615388565b50610b259261102c9250905b80821115610b2557600081556001016153af5600a165627a7a72305820a65003a6c94965a7db45161c90b46146f2a025baf582adae16ed92d3028eccf90029","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"byzantium","libraries":{},"optimizer":{"enabled":true,"runs":10000},"remappings":[]},"optimization_runs":10000,"sourcify_repo_url":"https://repo.sourcify.dev/contracts/partial_match/1/0xa4D1a2693589840BABb7f3A44D14Fdf41b3bF1Fe/","decoded_constructor_args":null,"compiler_version":"0.4.24+commit.e67f0147","is_verified_via_verifier_alliance":false,"verified_at":"2024-08-14T01:54:37.241217Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x6080604052620000176401000000006200001d810204565b6200023b565b6200003064010000000062000125810204565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a45440000000000000000602082015290156200010c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015620000d0578181015183820152602001620000b6565b50505050905090810190601f168015620000fe5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506200012360001964010000000062000154810204565b565b60006200014f6000805160206200563a83398151915264010000000062003c826200023382021704565b905090565b6200016764010000000062000125810204565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a454400000000000000006020820152901562000206576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015620000d0578181015183820152602001620000b6565b50620002306000805160206200563a8339815191528264010000000062004b586200023782021704565b50565b5490565b9055565b6153ef806200024b6000396000f3006080604052600436106102715763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630803fac081146102765780631aa430781461029f5780631e526610146102c65780632914b9bd146102eb5780632d5735011461036d57806332f0a3b51461039b5780633c624c75146103b05780634b12311c146103c55780635a55c1f01461041a5780635eb243321461054157806362de7e5a146105635780637bbddcfc146105785780637c1d0b87146105a65780637e7db6e1146105c857806380afdea8146105f6578063868ce31a1461060b5780638b3dd749146106205780638b5683271461063557806393f89a801461064a5780639d4941d814610662578063a1658fad14610690578063a479e50814610704578063a87f862414610719578063b6f6825414610774578063b879572514610789578063bcf93dd61461079e578063be2c64d4146107d0578063c0774df3146107e5578063c54c24b514610859578063c5bb87581461086e578063c91d956c14610883578063cc63604a1461089b578063cdb2867b146108b3578063d4aae0c4146108e4578063d5db2c80146108f9578063d948d46814610925578063dc177eec1461097e578063dc474b1a14610993578063de4796ed146109a8578063de4f6347146109bd578063df133bca146109d2578063df136602146109f4578063df35219714610a09578063eb1e3b7714610a1e578063ee0f160e14610a33578063f4b0051314610a48578063f98a4eca14610a7e578063fad167ab14610a96578063fc0c546a14610aab578063fc157cb414610ac0578063fd64eccb14610ad5578063ff31183814610aea575b600080fd5b34801561028257600080fd5b5061028b610aff565b604080519115158252519081900360200190f35b3480156102ab57600080fd5b506102b4610b29565b60408051918252519081900360200190f35b3480156102d257600080fd5b506102e96004356024356044356064351515610b2f565b005b3480156102f757600080fd5b506040805160206004803580820135601f8101849004840285018401909552848452610344943694929360249392840191908190840183828082843750949750610d809650505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561037957600080fd5b5061028b73ffffffffffffffffffffffffffffffffffffffff60043516610e8c565b3480156103a757600080fd5b50610344610f90565b3480156103bc57600080fd5b506102b461102f565b3480156103d157600080fd5b506103f660043573ffffffffffffffffffffffffffffffffffffffff60243516611053565b6040518082600381111561040657fe5b60ff16815260200191505060405180910390f35b34801561042657600080fd5b50610432600435611139565b604051808b1515151581526020018a1515151581526020018967ffffffffffffffff1667ffffffffffffffff1681526020018867ffffffffffffffff1667ffffffffffffffff1681526020018767ffffffffffffffff1667ffffffffffffffff1681526020018667ffffffffffffffff1667ffffffffffffffff16815260200185815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156104fd5781810151838201526020016104e5565b50505050905090810190601f16801561052a5780820380516001836020036101000a031916815260200191505b509b50505050505050505050505060405180910390f35b34801561054d57600080fd5b506102e967ffffffffffffffff6004351661134f565b34801561056f57600080fd5b506102b461156b565b34801561058457600080fd5b506102b473ffffffffffffffffffffffffffffffffffffffff6004351661158f565b3480156105b257600080fd5b506102e967ffffffffffffffff600435166115a1565b3480156105d457600080fd5b5061028b73ffffffffffffffffffffffffffffffffffffffff60043516611886565b34801561060257600080fd5b506102b461188c565b34801561061757600080fd5b506102b46118bc565b34801561062c57600080fd5b506102b46118e0565b34801561064157600080fd5b506102b461190b565b34801561065657600080fd5b506102e9600435611911565b34801561066e57600080fd5b506102e973ffffffffffffffffffffffffffffffffffffffff60043516611ad6565b34801561069c57600080fd5b50604080516020600460443581810135838102808601850190965280855261028b95833573ffffffffffffffffffffffffffffffffffffffff16956024803596369695606495939492019291829185019084908082843750949750611df89650505050505050565b34801561071057600080fd5b50610344611f88565b34801561072557600080fd5b506102e973ffffffffffffffffffffffffffffffffffffffff6004351667ffffffffffffffff6024358116906044358116906064351660843560a43560c43560e435610104356101243561204a565b34801561078057600080fd5b506102b461275f565b34801561079557600080fd5b506102b4612783565b3480156107aa57600080fd5b506107b3612789565b6040805167ffffffffffffffff9092168252519081900360200190f35b3480156107dc57600080fd5b506102b46127a5565b3480156107f157600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261028b95833573ffffffffffffffffffffffffffffffffffffffff169536956044949193909101919081908401838280828437509497506127c99650505050505050565b34801561086557600080fd5b506102b4612814565b34801561087a57600080fd5b506102b4612838565b34801561088f57600080fd5b506102e960043561283e565b3480156108a757600080fd5b5061028b600435612a01565b3480156108bf57600080fd5b5061028b60043573ffffffffffffffffffffffffffffffffffffffff60243516612ab9565b3480156108f057600080fd5b50610344612b71565b34801561090557600080fd5b506102b46024600480358281019290820135918135918201910135612b9c565b34801561093157600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526102e9943694929360249392840191908190840183828082843750949750612cf09650505050505050565b34801561098a57600080fd5b506102e9612db9565b34801561099f57600080fd5b506107b3612ec2565b3480156109b457600080fd5b5061028b612ed2565b3480156109c957600080fd5b506102b4612f03565b3480156109de57600080fd5b506102e960043560243515156044351515612f09565b348015610a0057600080fd5b506102e96131cd565b348015610a1557600080fd5b506102b46132d9565b348015610a2a57600080fd5b506102b46132df565b348015610a3f57600080fd5b5061028b6132e5565b348015610a5457600080fd5b506102b46024600480358281019290820135918135918201910135604435151560643515156132ee565b348015610a8a57600080fd5b506102e9600435613443565b348015610aa257600080fd5b506107b36134ee565b348015610ab757600080fd5b50610344613516565b348015610acc57600080fd5b506107b3613532565b348015610ae157600080fd5b5061028b61353e565b348015610af657600080fd5b506102b4613543565b600080610b0a6118e0565b90508015801590610b22575080610b1f613567565b10155b91505b5090565b60075481565b600a5460408051808201909152600e81527f564f54494e475f4e4f5f564f5445000000000000000000000000000000000000602082015285918210610c0c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610bd1578181015183820152602001610bb9565b50505050905090810190601f168015610bfe5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50610c17853361356b565b60408051808201909152601381527f564f54494e475f43414e5f4e4f545f564f5445000000000000000000000000006020820152901515610cb4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50670de0b6b3a7640000610cce858563ffffffff61365216565b60408051808201909152601981527f4d414c464f524d45445f434f4e54494e554f55535f564f5445000000000000006020820152911015610d6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50610d7985858533866136f7565b5050505050565b6000610d8a611f88565b73ffffffffffffffffffffffffffffffffffffffff166304bf2a7f836040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610e0e578181015183820152602001610df6565b50505050905090810190601f168015610e3b5780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b158015610e5a57600080fd5b505af1158015610e6e573d6000803e3d6000fd5b505050506040513d6020811015610e8457600080fd5b505192915050565b60085460009060ff168015610f46575060065460008054604080517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152915191909216926370a0823192602480820193602093909283900390910190829087803b158015610f1757600080fd5b505af1158015610f2b573d6000803e3d6000fd5b505050506040513d6020811015610f4157600080fd5b505110155b8015610f8a575073ffffffffffffffffffffffffffffffffffffffff82166000908152600b6020526040902054600754610f8790429063ffffffff613b1916565b10155b92915050565b6000610f9a612b71565b73ffffffffffffffffffffffffffffffffffffffff166332f0a3b56040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015610ffd57600080fd5b505af1158015611011573d6000803e3d6000fd5b505050506040513d602081101561102757600080fd5b505190505b90565b7fad15e7261800b4bb73f1b69d3864565ffb1fd00cb93cf14fe48da8f1f2149f3981565b600a5460408051808201909152600e81527f564f54494e475f4e4f5f564f5445000000000000000000000000000000000000602082015260009184919082106110f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50600084815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845260060190915290205460ff1691505b5092915050565b6000806000806000806000806000606060008b600a5481106040805190810160405280600e81526020017f564f54494e475f4e4f5f564f54450000000000000000000000000000000000008152509015156111f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5060008d8152600960205260409020915061120a82613bc4565b9b508160000160009054906101000a900460ff169a508160000160019054906101000a900467ffffffffffffffff1699508160000160099054906101000a900467ffffffffffffffff1698508160000160119054906101000a900467ffffffffffffffff1697508160010160009054906101000a900467ffffffffffffffff169650816002015495508160030154945081600401549350816005018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156113395780601f1061130e57610100808354040283529160200191611339565b820191906000526020600020905b81548152906001019060200180831161131c57829003601f168201915b5050505050925050509193959799509193959799565b6001547fad15e7261800b4bb73f1b69d3864565ffb1fd00cb93cf14fe48da8f1f2149f399061138b9067ffffffffffffffff8085169116613c27565b611396338383611df8565b60408051808201909152600f81527f4150505f415554485f4641494c454400000000000000000000000000000000006020820152901515611433576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5060005460408051808201909152601981527f564f54494e475f4348414e47455f51554f52554d5f504354530000000000000060208201529067ffffffffffffffff74010000000000000000000000000000000000000000909104811690851611156114fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b506001805467ffffffffffffffff85167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909116811790915560408051918252517f3172f2e9273c729c2a47cc8bf7e7f18506e3e3035126d562602bd2155bc78a509181900360200190a1505050565b7fda3972983e62bdf826c4b807c4c9c2b8a941e1f83dfa76d53d6aeac11e1be65081565b600b6020526000908152604090205481565b6000547fda3972983e62bdf826c4b807c4c9c2b8a941e1f83dfa76d53d6aeac11e1be650906115f59067ffffffffffffffff8085169174010000000000000000000000000000000000000000900416613c27565b611600338383611df8565b60408051808201909152600f81527f4150505f415554485f4641494c45440000000000000000000000000000000000602082015290151561169d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5060015460408051808201909152601a81527f564f54494e475f4348414e47455f535550504f52545f5043545300000000000060208201529067ffffffffffffffff8086169116111561174c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5060408051808201909152601a81527f564f54494e475f4348414e47455f535550505f544f4f5f4249470000000000006020820152670de0b6b3a764000067ffffffffffffffff8516106117fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b506000805467ffffffffffffffff85167401000000000000000000000000000000000000000081027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff9092169190911790915560408051918252517f903b617f7f36eb047a29b89d1bf7885fdae31d250c3320fccf11d045c11b396e9181900360200190a1505050565b50600190565b60006118b77fd625496217aa6a3453eecb9c3489dc5a53e6c67b444329ea2b2cbc9ff547639b613c82565b905090565b7fecb50dc3e77ba8a59697a3cc090a29b4cbd3c1f2b6b3aea524e0d166969592b981565b60006118b77febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e613c82565b60035481565b604080516000808252602082019092527fe7ab0252519cd959720b328191bed7fe61b8e25f77613877be7070646d12daf0916119539133918491905b50611df8565b60408051808201909152600f81527f4150505f415554485f4641494c4544000000000000000000000000000000000060208201529015156119f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50816004548110158015611a0657506005548111155b1515611a9957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d696e2074696d652073686f756c642062652077697468696e20696e6974696160448201527f6c697a6174696f6e2068617264636f646564206c696d69747300000000000000606482015290519081900360840190fd5b60078390556040805184815290517fcb34d0577abe5b2f96b65ea1bb5de2209ba6309c6909438c6d50dd277ca3b5809181900360200190a1505050565b6000806000611ae484611886565b60408051808201909152601281527f5245434f5645525f444953414c4c4f57454400000000000000000000000000006020820152901515611b81576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50611b8a610f90565b9250611b9583613c8a565b60408051808201909152601a81527f5245434f5645525f5641554c545f4e4f545f434f4e54524143540000000000006020820152901515611c32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5073ffffffffffffffffffffffffffffffffffffffff84161515611c9d576040513031925073ffffffffffffffffffffffffffffffffffffffff84169083156108fc029084906000818181858888f19350505050158015611c97573d6000803e3d6000fd5b50611d8d565b5082611cc573ffffffffffffffffffffffffffffffffffffffff82163063ffffffff613cbd16565b9150611cee73ffffffffffffffffffffffffffffffffffffffff8216848463ffffffff613df616565b60408051808201909152601d81527f5245434f5645525f544f4b454e5f5452414e534645525f4641494c45440000006020820152901515611d8b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b505b8373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f596caf56044b55fb8c4ca640089bbc2b63cae3e978b851f5745cbb7c5b288e02846040518082815260200191505060405180910390a350505050565b600080611e03610aff565b1515611e125760009150611f80565b611e1a612b71565b905073ffffffffffffffffffffffffffffffffffffffff81161515611e425760009150611f80565b8073ffffffffffffffffffffffffffffffffffffffff1663fdef9106863087611e6a88613e8e565b6040517c010000000000000000000000000000000000000000000000000000000063ffffffff871602815273ffffffffffffffffffffffffffffffffffffffff808616600483019081529085166024830152604482018490526080606483019081528351608484015283519192909160a490910190602085019080838360005b83811015611f02578181015183820152602001611eea565b50505050905090810190601f168015611f2f5780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b158015611f5157600080fd5b505af1158015611f65573d6000803e3d6000fd5b505050506040513d6020811015611f7b57600080fd5b505191505b509392505050565b600080611f93612b71565b604080517fbe00bbd80000000000000000000000000000000000000000000000000000000081527fd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb60048201527fddbcfd564f642ab5627cf68b9b7d374fb4f8a36e941a75d89c87998cef03bd616024820152905173ffffffffffffffffffffffffffffffffffffffff929092169163be00bbd8916044808201926020929091908290030181600087803b158015610e5a57600080fd5b60006120546118e0565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a45440000000000000000602082015290156120f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50604080517f4352454154455f564f5445535f524f4c45000000000000000000000000000000815290519081900360110190207fe7dcd7275292e064d090fbc5f3bd7995be23b502c1fed5cd94cfddbbdcd32bbc1461214b57fe5b604080517f4d4f444946595f535550504f52545f524f4c4500000000000000000000000000815290519081900360130190207fda3972983e62bdf826c4b807c4c9c2b8a941e1f83dfa76d53d6aeac11e1be650146121a557fe5b604080517f4d4f444946595f51554f52554d5f524f4c450000000000000000000000000000815290519081900360120190207fad15e7261800b4bb73f1b69d3864565ffb1fd00cb93cf14fe48da8f1f2149f39146121ff57fe5b604080517f5345545f4d494e5f42414c414e43455f524f4c45000000000000000000000000815290519081900360140190207fb1f3f26f63ad27cd630737a426f990492f5c674208299d6fb23bb2b0733d3d661461225957fe5b604080517f5345545f4d494e5f54494d455f524f4c45000000000000000000000000000000815290519081900360110190207fe7ab0252519cd959720b328191bed7fe61b8e25f77613877be7070646d12daf0146122b357fe5b604080517f44495341424c455f564f54455f4352454154494f4e0000000000000000000000815290519081900360150190207f40b01f8b31b51596de2eeab8c325ff77cc3695c1c1875d66ff31176e7148d2a11461230d57fe5b604080517f454e41424c455f564f54455f4352454154494f4e000000000000000000000000815290519081900360140190207fecb50dc3e77ba8a59697a3cc090a29b4cbd3c1f2b6b3aea524e0d166969592b91461236757fe5b61236f613e98565b60408051808201909152601081527f564f54494e475f494e49545f5043545300000000000000000000000000000000602082015267ffffffffffffffff808c16908b16111561241a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5060408051808201909152601b81527f564f54494e475f494e49545f535550504f52545f544f4f5f42494700000000006020820152670de0b6b3a764000067ffffffffffffffff8c16106124ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b508487101580156124db5750838711155b15156124e657600080fd5b8286101580156124f65750818611155b151561250157600080fd5b8a6000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555089600060146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555088600160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555087600160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561264157600080fd5b505af1158015612655573d6000803e3d6000fd5b505050506040513d602081101561266b57600080fd5b505160ff16600a0a9050612685878263ffffffff613f7716565b600655600786905561269d858263ffffffff613f7716565b6002556126b0848263ffffffff613f7716565b6003556004839055600582905560065460408051918252517fbd5318adc778260bd213cc16f3ef06cfb4f729adb9309495fed0e10abc61c3759181900360200190a160075460408051918252517fcb34d0577abe5b2f96b65ea1bb5de2209ba6309c6909438c6d50dd277ca3b5809181900360200190a15050600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505050505050565b7fb1f3f26f63ad27cd630737a426f990492f5c674208299d6fb23bb2b0733d3d6681565b60045481565b60015468010000000000000000900467ffffffffffffffff1681565b7fe7dcd7275292e064d090fbc5f3bd7995be23b502c1fed5cd94cfddbbdcd32bbc81565b60006127fd837fe7dcd7275292e064d090fbc5f3bd7995be23b502c1fed5cd94cfddbbdcd32bbc6127f8614039565b611df8565b801561280d575061280d83610e8c565b9392505050565b7fe7ab0252519cd959720b328191bed7fe61b8e25f77613877be7070646d12daf081565b60065481565b604080516000808252602082019092527fb1f3f26f63ad27cd630737a426f990492f5c674208299d6fb23bb2b0733d3d669161287e91339184919061194d565b60408051808201909152600f81527f4150505f415554485f4641494c45440000000000000000000000000000000000602082015290151561291b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5081600254811015801561293157506003548111155b15156129c457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f4d696e2062616c616e63652073686f756c642062652077697468696e20696e6960448201527f7469616c697a6174696f6e2068617264636f646564206c696d69747300000000606482015290519081900360840190fd5b60068390556040805184815290517fbd5318adc778260bd213cc16f3ef06cfb4f729adb9309495fed0e10abc61c3759181900360200190a1505050565b600a5460408051808201909152600e81527f564f54494e475f4e4f5f564f544500000000000000000000000000000000000060208201526000918391908210612aa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50612ab08361404b565b91505b50919050565b600a5460408051808201909152600e81527f564f54494e475f4e4f5f564f544500000000000000000000000000000000000060208201526000918491908210612b5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50612b69848461356b565b949350505050565b60006118b77f4172f0f7d2289153072b0a6ca36959e0cbe2efc3afe50fc81636caa96338137b613c82565b604080516000808252602082019092527fe7dcd7275292e064d090fbc5f3bd7995be23b502c1fed5cd94cfddbbdcd32bbc90612bdc90339083908561194d565b60408051808201909152600f81527f4150505f415554485f4641494c454400000000000000000000000000000000006020820152901515612c79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50612ce686868080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f8c018190048102820181019092528a815294508a9350899250829150840183828082843782019150505050505060018061417a565b9695505050505050565b612cfa33826127c9565b60408051808201909152601681527f564f54494e475f43414e5f4e4f545f464f5257415244000000000000000000006020820152901515612d97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50612db581602060405190810160405280600081525060018061417a565b5050565b604080516000808252602082019092527f40b01f8b31b51596de2eeab8c325ff77cc3695c1c1875d66ff31176e7148d2a191612df991339184919061194d565b60408051808201909152600f81527f4150505f415554485f4641494c454400000000000000000000000000000000006020820152901515612e96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5050600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60015467ffffffffffffffff1681565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612efd6118e0565b14905090565b600a5481565b60008080612f2886826fffffffffffffffffffffffffffffffff6146bb565b600a5460408051808201909152600e81527f564f54494e475f4e4f5f564f54450000000000000000000000000000000000006020820152908210612fc8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50612fe58760006fffffffffffffffffffffffffffffffff6146bb565b9350612ffb87608067ffffffffffffffff6146bb565b92506130118760c067ffffffffffffffff6146bb565b915061301d843361356b565b60408051808201909152601381527f564f54494e475f43414e5f4e4f545f564f54450000000000000000000000000060208201529015156130ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50811580156130c7575082155b156130f35785156130e257670de0b6b3a764000091506130ee565b670de0b6b3a764000092505b6131b7565b851580156131185750670de0b6b3a7640000613115838563ffffffff61365216565b11155b60408051808201909152601981527f4d414c464f524d45445f434f4e54494e554f55535f564f54450000000000000060208201529015156131b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b505b6131c484838533896136f7565b50505050505050565b604080516000808252602082019092527fecb50dc3e77ba8a59697a3cc090a29b4cbd3c1f2b6b3aea524e0d166969592b99161320d91339184919061194d565b60408051808201909152600f81527f4150505f415554485f4641494c4544000000000000000000000000000000000060208201529015156132aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5050600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60055481565b60025481565b60085460ff1681565b604080516000808252602082019092527fe7dcd7275292e064d090fbc5f3bd7995be23b502c1fed5cd94cfddbbdcd32bbc9061332e90339083908561194d565b60408051808201909152600f81527f4150505f415554485f4641494c4544000000000000000000000000000000000060208201529015156133cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5061343788888080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f8e018190048102820181019092528c815294508c93508b92508291508401838280828437820191505050505050868661417a565b98975050505050505050565b600a5460408051808201909152600e81527f564f54494e475f4e4f5f564f54450000000000000000000000000000000000006020820152829182106134e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50612db5826146c8565b60005474010000000000000000000000000000000000000000900467ffffffffffffffff1681565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b670de0b6b3a764000081565b600190565b7f40b01f8b31b51596de2eeab8c325ff77cc3695c1c1875d66ff31176e7148d2a181565b4390565b600082815260096020526040812061358281613bc4565b8015612b695750600080548254604080517f4ee2cd7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152690100000000000000000090930467ffffffffffffffff16602482015290519190921691634ee2cd7e91604480830192602092919082900301818787803b15801561361d57600080fd5b505af1158015613631573d6000803e3d6000fd5b505050506040513d602081101561364757600080fd5b505111949350505050565b60408051808201909152601181527f4d4154485f4144445f4f564552464c4f5700000000000000000000000000000060208201526000908383019084821015611f80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b600085815260096020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845260068101909252822054909160ff909116908080808085600381111561374357fe5b146137af57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f43616e2774206368616e676520766f7465730000000000000000000000000000604482015290519081900360640190fd5b600080548754604080517f4ee2cd7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d81166004830152690100000000000000000090930467ffffffffffffffff16602482015290519190921692634ee2cd7e92604480820193602093909283900390910190829087803b15801561384657600080fd5b505af115801561385a573d6000803e3d6000fd5b505050506040513d602081101561387057600080fd5b505160015490945061391d9068010000000000000000900467ffffffffffffffff166139116138ea6138a061477b565b6001548b546138d49161010090910467ffffffffffffffff908116916801000000000000000090041663ffffffff61478d16565b67ffffffffffffffff169063ffffffff61483f16565b67ffffffffffffffff1661390560028963ffffffff613f7716565b9063ffffffff613f7716565b9063ffffffff6148ef16565b92508383111561392b578392505b613947670de0b6b3a7640000613911858d63ffffffff613f7716565b9150613965670de0b6b3a7640000613911858c63ffffffff613f7716565b9050600082111561398b576002860154613985908363ffffffff61365216565b60028701555b60008111156139af5760038601546139a9908263ffffffff61365216565b60038701555b8082146139cc578082116139c45760026139c7565b60015b6139cf565b60035b73ffffffffffffffffffffffffffffffffffffffff89166000908152600688016020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001836003811115613a2857fe5b02179055506000821115613a8d57604080516001815260208101849052815173ffffffffffffffffffffffffffffffffffffffff8b16928e927fb34ee265e3d4f5ec4e8b52d59b2a9be8fceca2f274ebc080d8fba797fea9391f929081900390910190a35b6000811115613aed57604080516000815260208101839052815173ffffffffffffffffffffffffffffffffffffffff8b16928e927fb34ee265e3d4f5ec4e8b52d59b2a9be8fceca2f274ebc080d8fba797fea9391f929081900390910190a35b868015613afe5750613afe8b61404b565b15613b0c57613b0c8b6149a6565b5050505050505050505050565b60408051808201909152601281527f4d4154485f5355425f554e444552464c4f5700000000000000000000000000006020820152600090819084841115613bbc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b505050900390565b6001548154600091613bfa91610100900467ffffffffffffffff908116916801000000000000000090041663ffffffff61478d16565b67ffffffffffffffff16613c0c61477b565b67ffffffffffffffff16108015610f8a5750505460ff161590565b604080516002808252606080830184529260208301908038833901905050905082816000815181101515613c5757fe5b602090810290910101528051829082906001908110613c7257fe5b6020908102909101015292915050565b5490565b5490565b60008073ffffffffffffffffffffffffffffffffffffffff83161515613cb35760009150612ab3565b50506000903b1190565b6040805173ffffffffffffffffffffffffffffffffffffffff83166024808301919091528251808303909101815260449091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a08231000000000000000000000000000000000000000000000000000000001790526000908180613d4a8684614ad9565b60408051808201909152601c81527f534146455f4552435f32305f42414c414e43455f52455645525445440000000060208201529193509150821515613dec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5095945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052600090613e858582614b0a565b95945050505050565b8051602002815290565b613ea06118e0565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a4544000000000000000060208201529015613f3c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50613f75613f48613567565b7febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e9063ffffffff614b5816565b565b600080831515613f8a5760009150611132565b50828202828482811515613f9a57fe5b60408051808201909152601181527f4d4154485f4d554c5f4f564552464c4f5700000000000000000000000000000060208201529291900414611f80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b60408051600081526020810190915290565b60008181526009602052604081208161406382613bc4565b156140715760009250614173565b815460ff16156140845760009250614173565b6002820154600483015483546140ba92919071010000000000000000000000000000000000900467ffffffffffffffff16614b5c565b156140c85760019250614173565b6140d182613bc4565b156140df5760009250614173565b600382015460028301546140f89163ffffffff61365216565b6002830154835491925061412c91839071010000000000000000000000000000000000900467ffffffffffffffff16614b5c565b151561413b5760009250614173565b60028201546004830154600184015461415f92919067ffffffffffffffff16614b5c565b151561416e5760009250614173565b600192505b5050919050565b60008060008061418933610e8c565b151561419457600080fd5b600161419e614b9e565b60008054604080517f981b24d00000000000000000000000000000000000000000000000000000000081529490930367ffffffffffffffff81166004860152925192965073ffffffffffffffffffffffffffffffffffffffff169263981b24d09260248083019360209383900390910190829087803b15801561422057600080fd5b505af1158015614234573d6000803e3d6000fd5b505050506040513d602081101561424a57600080fd5b505160408051808201909152601681527f564f54494e475f4e4f5f564f54494e475f504f574552000000000000000000006020820152909250600083116142ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5050600a805460018101909155600081815260096020526040902090935061431361477b565b81547fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff1661010067ffffffffffffffff92831602177fffffffffffffffffffffffffffffff0000000000000000ffffffffffffffffff16690100000000000000000085831602178083556000547fffffffffffffff0000000000000000ffffffffffffffffffffffffffffffffff9091167401000000000000000000000000000000000000000090910482167101000000000000000000000000000000000002178255600180549083018054919092167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090911617905560048101829055875161442690600583019060208b0190615335565b503373ffffffffffffffffffffffffffffffffffffffff16847f0730610a5322c6584fb6f5bb760719e650c888cfd965a2beb2d598bcd425e394896006546007546000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156144ec57600080fd5b505af1158015614500573d6000803e3d6000fd5b505050506040513d602081101561451657600080fd5b505160008054604080517f4ee2cd7e00000000000000000000000000000000000000000000000000000000815233600482015267ffffffffffffffff8e166024820152905173ffffffffffffffffffffffffffffffffffffffff90921692634ee2cd7e926044808401936020939083900390910190829087803b15801561459c57600080fd5b505af11580156145b0573d6000803e3d6000fd5b505050506040513d60208110156145c657600080fd5b5051604080516020818101879052918101859052606081018490526080810183905260a080825287519082015286519091829160c083019189019080838360005b8381101561461f578181015183820152602001614607565b50505050905090810190601f16801561464c5780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a361466561477b565b336000908152600b6020526040902067ffffffffffffffff9190911690558580156146955750614695843361356b565b156146b0576146b084670de0b6b3a7640000600033896136f7565b505050949350505050565b60029190910a9091041690565b6146d18161404b565b60408051808201909152601681527f564f54494e475f43414e5f4e4f545f4558454355544500000000000000000000602082015290151561476e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50614778816149a6565b50565b60006118b7614788614bab565b614baf565b60408051808201909152601381527f4d41544836345f4144445f4f564552464c4f570000000000000000000000000060208201526000908383019067ffffffffffffffff8086169083161015611f80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b60408051808201909152601481527f4d41544836345f5355425f554e444552464c4f570000000000000000000000006020820152600090819067ffffffffffffffff8086169085161115613bbc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b60408051808201909152600d81527f4d4154485f4449565f5a45524f0000000000000000000000000000000000000060208201526000908190818411614991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50828481151561499d57fe5b04949350505050565b600081815260096020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811782558251948552600582018054600292811615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff011691909104601f81018590048502860184018452938501848152919493614aa893850182828015614a8b5780601f10614a6057610100808354040283529160200191614a8b565b820191906000526020600020905b815481529060010190602001808311614a6e57829003601f168201915b50506040805160008152602081019091528693509150614c5f9050565b5060405183907fbf8e2b108bb7c980e08903a8a46527699d5e84905a082d56dacb4150725c8cab90600090a2505050565b6000806000806040516020818751602089018a5afa92506000831115614afe57805191505b50909590945092505050565b6000806040516020818551602087016000895af16000811115614b4e573d8015614b3b5760208114614b4457614b4c565b60019350614b4c565b600183511493505b505b5090949350505050565b9055565b600080831515614b6f5760009150611f80565b83614b8886670de0b6b3a764000063ffffffff613f7716565b811515614b9157fe5b0492909211949350505050565b60006118b7614788613567565b4290565b60408051808201909152601581527f55494e5436345f4e554d4245525f544f4f5f4249470000000000000000000000602082015260009067ffffffffffffffff831115614c58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b5090919050565b6060600080606080614c6f610aff565b60408051808201909152601481527f494e49545f4e4f545f494e495449414c495a45440000000000000000000000006020820152901515614d0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b50600080614d18612b71565b9150614d2261188c565b9050614d2d8a610d80565b60408051808201909152601b81527f45564d52554e5f4558454355544f525f554e415641494c41424c450000000000602082015290965073ffffffffffffffffffffffffffffffffffffffff87161515614de3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b506040516060602482019081528b5160848301528b517f279cea3500000000000000000000000000000000000000000000000000000000975087928d928d928d9282916044820191606481019160a490910190602089019080838360005b83811015614e59578181015183820152602001614e41565b50505050905090810190601f168015614e865780820380516001836020036101000a031916815260200191505b50848103835286518152865160209182019188019080838360005b83811015614eb9578181015183820152602001614ea1565b50505050905090810190601f168015614ee65780820380516001836020036101000a031916815260200191505b508481038252855181528551602091820191808801910280838360005b83811015614f1b578181015183820152602001614f03565b505050509050019650505050505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509350600080855160208701895af4604051935080801561502057603f3d118015614fbe5760203d03806020883e860160405261501a565b7f08c379a000000000000000000000000000000000000000000000000000000000865260206004870152601e60248701527f45564d52554e5f4558454355544f525f494e56414c49445f52455455524e00006044870152606486fd5b50615029565b3d6000863e3d85fd5b50508573ffffffffffffffffffffffffffffffffffffffff167f5229a5dba83a54ae8cb5b51bdd6de9474cacbe9dd332f5185f3a4f4f2e3f4ad98b8b8660405180806020018060200180602001848103845287818151815260200191508051906020019080838360005b838110156150ab578181015183820152602001615093565b50505050905090810190601f1680156150d85780820380516001836020036101000a031916815260200191505b50848103835286518152865160209182019188019080838360005b8381101561510b5781810151838201526020016150f3565b50505050905090810190601f1680156151385780820380516001836020036101000a031916815260200191505b50848103825285518152855160209182019187019080838360005b8381101561516b578181015183820152602001615153565b50505050905090810190601f1680156151985780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a28296508173ffffffffffffffffffffffffffffffffffffffff166151cb612b71565b73ffffffffffffffffffffffffffffffffffffffff16146040805190810160405280601f81526020017f45564d52554e5f50524f5445435445445f53544154455f4d4f44494649454400815250901515615281576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b508061528b61188c565b60408051808201909152601f81527f45564d52554e5f50524f5445435445445f53544154455f4d4f4449464945440060208201529114615327576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015610bd1578181015183820152602001610bb9565b505050505050509392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061537657805160ff19168380011785556153a3565b828001600101855582156153a3579182015b828111156153a3578251825591602001919060010190615388565b50610b259261102c9250905b80821115610b2557600081556001016153af5600a165627a7a72305820a65003a6c94965a7db45161c90b46146f2a025baf582adae16ed92d3028eccf90029ebb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e","name":"Voting","is_blueprint":false,"license_type":"none","is_fully_verified":false,"is_verified_via_eth_bytecode_db":true,"language":"solidity","evm_version":"byzantium","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":true,"additional_sources":[],"certified":false,"conflicting_implementations":null,"abi":[{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"minTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_voteId","type":"uint256"},{"name":"_yeaPct","type":"uint256"},{"name":"_nayPct","type":"uint256"},{"name":"_executesIfDecided","type":"bool"}],"name":"votePct","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_script","type":"bytes"}],"name":"getEVMScriptExecutor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"}],"name":"canCreateNewVote","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getRecoveryVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MODIFY_QUORUM_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_voteId","type":"uint256"},{"name":"_voter","type":"address"}],"name":"getVoterState","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_voteId","type":"uint256"}],"name":"getVote","outputs":[{"name":"open","type":"bool"},{"name":"executed","type":"bool"},{"name":"startDate","type":"uint64"},{"name":"snapshotBlock","type":"uint64"},{"name":"supportRequired","type":"uint64"},{"name":"minAcceptQuorum","type":"uint64"},{"name":"yea","type":"uint256"},{"name":"nay","type":"uint256"},{"name":"votingPower","type":"uint256"},{"name":"script","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_minAcceptQuorumPct","type":"uint64"}],"name":"changeMinAcceptQuorumPct","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MODIFY_SUPPORT_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"lastCreateVoteTimes","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_supportRequiredPct","type":"uint64"}],"name":"changeSupportRequiredPct","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"allowRecoverability","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"appId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ENABLE_VOTE_CREATION","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitializationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"minBalanceUpperLimit","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_minTime","type":"uint256"}],"name":"setMinTime","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"transferToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_params","type":"uint256[]"}],"name":"canPerform","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getEVMScriptRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"},{"name":"_supportRequiredPct","type":"uint64"},{"name":"_minAcceptQuorumPct","type":"uint64"},{"name":"_voteTime","type":"uint64"},{"name":"_minBalance","type":"uint256"},{"name":"_minTime","type":"uint256"},{"name":"_minBalanceLowerLimit","type":"uint256"},{"name":"_minBalanceUpperLimit","type":"uint256"},{"name":"_minTimeLowerLimit","type":"uint256"},{"name":"_minTimeUpperLimit","type":"uint256"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"SET_MIN_BALANCE_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"minTimeLowerLimit","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"voteTime","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CREATE_VOTES_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"","type":"bytes"}],"name":"canForward","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SET_MIN_TIME_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"minBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_minBalance","type":"uint256"}],"name":"setMinBalance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_voteId","type":"uint256"}],"name":"canExecute","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_voteId","type":"uint256"},{"name":"_voter","type":"address"}],"name":"canVote","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kernel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_executionScript","type":"bytes"},{"name":"_metadata","type":"string"}],"name":"newVote","outputs":[{"name":"voteId","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_evmScript","type":"bytes"}],"name":"forward","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"disableVoteCreationOnce","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"minAcceptQuorumPct","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPetrified","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"votesLength","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_voteData","type":"uint256"},{"name":"_supports","type":"bool"},{"name":"_executesIfDecided","type":"bool"}],"name":"vote","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"enableVoteCreationOnce","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"minTimeUpperLimit","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"minBalanceLowerLimit","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"enableVoteCreation","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_executionScript","type":"bytes"},{"name":"_metadata","type":"string"},{"name":"_castVote","type":"bool"},{"name":"_executesIfDecided","type":"bool"}],"name":"newVote","outputs":[{"name":"voteId","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_voteId","type":"uint256"}],"name":"executeVote","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"supportRequiredPct","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"token","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PCT_BASE","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isForwarder","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"DISABLE_VOTE_CREATION","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"voteId","type":"uint256"},{"indexed":true,"name":"creator","type":"address"},{"indexed":false,"name":"metadata","type":"string"},{"indexed":false,"name":"minBalance","type":"uint256"},{"indexed":false,"name":"minTime","type":"uint256"},{"indexed":false,"name":"totalSupply","type":"uint256"},{"indexed":false,"name":"creatorVotingPower","type":"uint256"}],"name":"StartVote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"voteId","type":"uint256"},{"indexed":true,"name":"voter","type":"address"},{"indexed":false,"name":"supports","type":"bool"},{"indexed":false,"name":"stake","type":"uint256"}],"name":"CastVote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"voteId","type":"uint256"}],"name":"ExecuteVote","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"supportRequiredPct","type":"uint64"}],"name":"ChangeSupportRequired","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"minAcceptQuorumPct","type":"uint64"}],"name":"ChangeMinQuorum","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"minBalance","type":"uint256"}],"name":"MinimumBalanceSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"minTime","type":"uint256"}],"name":"MinimumTimeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"executor","type":"address"},{"indexed":false,"name":"script","type":"bytes"},{"indexed":false,"name":"input","type":"bytes"},{"indexed":false,"name":"returnData","type":"bytes"}],"name":"ScriptResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"vault","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"RecoverToVault","type":"event"}],"is_changed_bytecode":false,"is_partially_verified":true,"constructor_args":null}