Contract 0x9f266ada47711c2a942a4987a0b5dd5344887aea

Contract Overview

Balance:
0 FTM
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x6ccc7ca3bac15374d6335fb6b525ff0ad7f8d51907ad466e075e19f3fc383378Create122132322022-11-23 10:36:2866 days 13 hrs ago0xcc8b10332478e26f676bccfc73f8c687e3ad1d04 IN  0x9f266ada47711c2a942a4987a0b5dd5344887aea100 FTM0.006180955
0x0ecb7d251586cca0934641d262dd2593dbe356c3f2711a4588dda7bbc164d941Create121800112022-11-21 13:07:0768 days 11 hrs ago0xcc8b10332478e26f676bccfc73f8c687e3ad1d04 IN  0x9f266ada47711c2a942a4987a0b5dd5344887aea100 FTM0.0061821925
0x842b6360a0163ca457c704c57bc57e57d4a2bdad4bf2702e82e47e60d4c46d43Create121799882022-11-21 13:04:3968 days 11 hrs ago0xcc8b10332478e26f676bccfc73f8c687e3ad1d04 IN  0x9f266ada47711c2a942a4987a0b5dd5344887aea100 FTM0.00607337
0xbb337920298c729bbd61241e5ca5394bfec0ba4cd222bc8c74d39dcc82206b35Create121799772022-11-21 13:03:1168 days 11 hrs ago0xcc8b10332478e26f676bccfc73f8c687e3ad1d04 IN  0x9f266ada47711c2a942a4987a0b5dd5344887aea100 FTM0.0062265325
0xb3505829b4c7c159ccf73db8fa290a4b2b4d60b35fd7dbf7615cb71d5b27930cCreate121798922022-11-21 12:52:2468 days 11 hrs ago0xcc8b10332478e26f676bccfc73f8c687e3ad1d04 IN  0x9f266ada47711c2a942a4987a0b5dd5344887aea100 FTM0.00618263
0x1a3c5d3272e3786396fd9f82169d66cbbd8e43474bedda9a54eae691aa934205Create121798752022-11-21 12:50:1268 days 11 hrs ago0xcc8b10332478e26f676bccfc73f8c687e3ad1d04 IN  0x9f266ada47711c2a942a4987a0b5dd5344887aea100 FTM0.0061157175
0xc3f549acfa8106dfeb9e5f3ed9bccd24acebea59c761344a9d131b041a4986baCreate121797562022-11-21 12:39:5068 days 11 hrs ago0xcc8b10332478e26f676bccfc73f8c687e3ad1d04 IN  0x9f266ada47711c2a942a4987a0b5dd5344887aea100 FTM0.0060715325
0xd3ba5c9822e786eb2810893a55c4c0a712dace4537251b812c6a7b10261ca19cCreate121797342022-11-21 12:37:3068 days 11 hrs ago0xcc8b10332478e26f676bccfc73f8c687e3ad1d04 IN  0x9f266ada47711c2a942a4987a0b5dd5344887aea100 FTM0.0061142225
0x9f95034ac1dd7186f0fb03c2dd587830869d6c806c3c822e2d099735007292f7Create121796182022-11-21 12:26:5868 days 11 hrs ago0xcc8b10332478e26f676bccfc73f8c687e3ad1d04 IN  0x9f266ada47711c2a942a4987a0b5dd5344887aea100 FTM0.006080465
0x5a4234f1067a8f9115cc695ac65ae1fe94b0de1e5226e8420eba5aed3e01e3ecCreate121795902022-11-21 12:24:0668 days 11 hrs ago0xcc8b10332478e26f676bccfc73f8c687e3ad1d04 IN  0x9f266ada47711c2a942a4987a0b5dd5344887aea100 FTM0.00628892
0x7a94035ffa39b457aa4f9c525c55f7c2b3108c25c496a032e01e079a323ce964Create121794832022-11-21 12:13:4368 days 12 hrs ago0xcc8b10332478e26f676bccfc73f8c687e3ad1d04 IN  0x9f266ada47711c2a942a4987a0b5dd5344887aea100 FTM0.0060702275
0x3ae0ca2e50ecbe9658e7408b238240c983ef1d5dad58de49f7fceecbdd96f36bCreate121794752022-11-21 12:12:2368 days 12 hrs ago0xcc8b10332478e26f676bccfc73f8c687e3ad1d04 IN  0x9f266ada47711c2a942a4987a0b5dd5344887aea100 FTM0.0060701475
0x86bb97a738e8ea5101d7738882cedd5ca01ae255539d903bc69d3a6f3248c0c9Create121794452022-11-21 12:10:3968 days 12 hrs ago0xcc8b10332478e26f676bccfc73f8c687e3ad1d04 IN  0x9f266ada47711c2a942a4987a0b5dd5344887aea100 FTM0.006223855
0x2454534be7430136020a6e53a849b77f217429170dc57fc6c9bd2c848c2e953eCreate121780122022-11-21 10:27:1668 days 13 hrs ago0xcc8b10332478e26f676bccfc73f8c687e3ad1d04 IN  0x9f266ada47711c2a942a4987a0b5dd5344887aea100 FTM0.0063384975
0x2633a5fbc5ffeff6180f40c4a8051a2338c0f5973171a7ff84ab4ae335d92261Create121778392022-11-21 10:16:4868 days 13 hrs ago0x567b6f3d4ba1f55652cf90df6db90ad6d8f9abc1 IN  0x9f266ada47711c2a942a4987a0b5dd5344887aea100 FTM0.00622998
0xc36a8dee5c58ba60f3cd2da4d6b67ff320260108bad493db00cf47101de3a602Create121765442022-11-21 9:00:1268 days 15 hrs ago0xcc8b10332478e26f676bccfc73f8c687e3ad1d04 IN  0x9f266ada47711c2a942a4987a0b5dd5344887aea100 FTM0.0062279
0xfc10b5ef866751c6b3193932c0587748b62eb670341baef73838115bbc090834Create121354732022-11-18 7:26:5171 days 16 hrs ago0xcc8b10332478e26f676bccfc73f8c687e3ad1d04 IN  0x9f266ada47711c2a942a4987a0b5dd5344887aea100 FTM0.00629293
0x171ba7e8f71485c5c5799224c61f43d72c36cc19f18800bc49a067fb51a1e5bcCreate121354012022-11-18 7:21:4671 days 16 hrs ago0xcc8b10332478e26f676bccfc73f8c687e3ad1d04 IN  0x9f266ada47711c2a942a4987a0b5dd5344887aea100 FTM0.00639805
0xe17cafc7d1f8652e5292e6dd3517988ab73a9d4755f9119dae2ee377928228b50x60806040121353562022-11-18 7:18:5671 days 16 hrs ago0xd5a4a401e6762171b4201adc5032f2649c4e0cf5 IN  Contract Creation0 FTM0.003141013537
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x6ccc7ca3bac15374d6335fb6b525ff0ad7f8d51907ad466e075e19f3fc383378122132322022-11-23 10:36:2866 days 13 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea 0xaa3a160e91f63f1db959640e0a7b8911b6bd5b95100 FTM
0x6ccc7ca3bac15374d6335fb6b525ff0ad7f8d51907ad466e075e19f3fc383378122132322022-11-23 10:36:2866 days 13 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea  Contract Creation100 FTM
0x0ecb7d251586cca0934641d262dd2593dbe356c3f2711a4588dda7bbc164d941121800112022-11-21 13:07:0768 days 11 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea 0xaa3a160e91f63f1db959640e0a7b8911b6bd5b95100 FTM
0x0ecb7d251586cca0934641d262dd2593dbe356c3f2711a4588dda7bbc164d941121800112022-11-21 13:07:0768 days 11 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea  Contract Creation100 FTM
0x842b6360a0163ca457c704c57bc57e57d4a2bdad4bf2702e82e47e60d4c46d43121799882022-11-21 13:04:3968 days 11 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea 0xaa3a160e91f63f1db959640e0a7b8911b6bd5b95100 FTM
0x842b6360a0163ca457c704c57bc57e57d4a2bdad4bf2702e82e47e60d4c46d43121799882022-11-21 13:04:3968 days 11 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea  Contract Creation100 FTM
0xbb337920298c729bbd61241e5ca5394bfec0ba4cd222bc8c74d39dcc82206b35121799772022-11-21 13:03:1168 days 11 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea 0xaa3a160e91f63f1db959640e0a7b8911b6bd5b95100 FTM
0xbb337920298c729bbd61241e5ca5394bfec0ba4cd222bc8c74d39dcc82206b35121799772022-11-21 13:03:1168 days 11 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea  Contract Creation100 FTM
0xb3505829b4c7c159ccf73db8fa290a4b2b4d60b35fd7dbf7615cb71d5b27930c121798922022-11-21 12:52:2468 days 11 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea 0xaa3a160e91f63f1db959640e0a7b8911b6bd5b95100 FTM
0xb3505829b4c7c159ccf73db8fa290a4b2b4d60b35fd7dbf7615cb71d5b27930c121798922022-11-21 12:52:2468 days 11 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea  Contract Creation100 FTM
0x1a3c5d3272e3786396fd9f82169d66cbbd8e43474bedda9a54eae691aa934205121798752022-11-21 12:50:1268 days 11 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea 0xaa3a160e91f63f1db959640e0a7b8911b6bd5b95100 FTM
0x1a3c5d3272e3786396fd9f82169d66cbbd8e43474bedda9a54eae691aa934205121798752022-11-21 12:50:1268 days 11 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea  Contract Creation100 FTM
0xc3f549acfa8106dfeb9e5f3ed9bccd24acebea59c761344a9d131b041a4986ba121797562022-11-21 12:39:5068 days 11 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea 0xaa3a160e91f63f1db959640e0a7b8911b6bd5b95100 FTM
0xc3f549acfa8106dfeb9e5f3ed9bccd24acebea59c761344a9d131b041a4986ba121797562022-11-21 12:39:5068 days 11 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea  Contract Creation100 FTM
0xd3ba5c9822e786eb2810893a55c4c0a712dace4537251b812c6a7b10261ca19c121797342022-11-21 12:37:3068 days 11 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea 0xaa3a160e91f63f1db959640e0a7b8911b6bd5b95100 FTM
0xd3ba5c9822e786eb2810893a55c4c0a712dace4537251b812c6a7b10261ca19c121797342022-11-21 12:37:3068 days 11 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea  Contract Creation100 FTM
0x9f95034ac1dd7186f0fb03c2dd587830869d6c806c3c822e2d099735007292f7121796182022-11-21 12:26:5868 days 11 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea 0xaa3a160e91f63f1db959640e0a7b8911b6bd5b95100 FTM
0x9f95034ac1dd7186f0fb03c2dd587830869d6c806c3c822e2d099735007292f7121796182022-11-21 12:26:5868 days 11 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea  Contract Creation100 FTM
0x5a4234f1067a8f9115cc695ac65ae1fe94b0de1e5226e8420eba5aed3e01e3ec121795902022-11-21 12:24:0668 days 11 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea 0xaa3a160e91f63f1db959640e0a7b8911b6bd5b95100 FTM
0x5a4234f1067a8f9115cc695ac65ae1fe94b0de1e5226e8420eba5aed3e01e3ec121795902022-11-21 12:24:0668 days 11 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea  Contract Creation100 FTM
0x7a94035ffa39b457aa4f9c525c55f7c2b3108c25c496a032e01e079a323ce964121794832022-11-21 12:13:4368 days 12 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea 0xaa3a160e91f63f1db959640e0a7b8911b6bd5b95100 FTM
0x7a94035ffa39b457aa4f9c525c55f7c2b3108c25c496a032e01e079a323ce964121794832022-11-21 12:13:4368 days 12 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea  Contract Creation100 FTM
0x3ae0ca2e50ecbe9658e7408b238240c983ef1d5dad58de49f7fceecbdd96f36b121794752022-11-21 12:12:2368 days 12 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea 0xaa3a160e91f63f1db959640e0a7b8911b6bd5b95100 FTM
0x3ae0ca2e50ecbe9658e7408b238240c983ef1d5dad58de49f7fceecbdd96f36b121794752022-11-21 12:12:2368 days 12 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea  Contract Creation100 FTM
0x86bb97a738e8ea5101d7738882cedd5ca01ae255539d903bc69d3a6f3248c0c9121794452022-11-21 12:10:3968 days 12 hrs ago 0x9f266ada47711c2a942a4987a0b5dd5344887aea 0xaa3a160e91f63f1db959640e0a7b8911b6bd5b95100 FTM
[ Download CSV Export 
Loading

Similar Match Source Code
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0x09F44D7F15dd65529CF261c5ea8364e09A51d7C3

Contract Name:
NetworkParameterProposalFactory

Compiler Version
v0.5.17+commit.d19bba13

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 22 : Decimal.sol
pragma solidity ^0.5.0;

library Decimal {
    // unit is used for decimals, e.g. 0.123456
    function unit() internal pure returns (uint256) {
        return 1e18;
    }
}

File 2 of 22 : Initializable.sol
pragma solidity >=0.4.24 <0.7.0;


/**
 * @title Initializable
 *
 * @dev Helper contract to support initializer functions. To use it, replace
 * the constructor with a function that has the `initializer` modifier.
 * WARNING: Unlike constructors, initializer functions must be manually
 * invoked. This applies both to deploying an Initializable contract, as well
 * as extending an Initializable contract via inheritance.
 * WARNING: When used with inheritance, manual care must be taken to not invoke
 * a parent initializer twice, or ensure that all initializers are idempotent,
 * because this is not dealt with automatically as with constructors.
 */
contract Initializable {

  /**
   * @dev Indicates that the contract has been initialized.
   */
  bool private initialized;

  /**
   * @dev Indicates that the contract is in the process of being initialized.
   */
  bool private initializing;

  /**
   * @dev Modifier to use in the initializer function of a contract.
   */
  modifier initializer() {
    require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized");

    bool isTopLevelCall = !initializing;
    if (isTopLevelCall) {
      initializing = true;
      initialized = true;
    }

    _;

    if (isTopLevelCall) {
      initializing = false;
    }
  }

  /// @dev Returns true if and only if the function is running in the constructor
  function isConstructor() private view returns (bool) {
    // extcodesize checks the size of the code stored in an address, and
    // address returns the current address. Since the code is still not
    // deployed when running a constructor, any checks on its code size will
    // yield zero, making it an effective way to detect if a contract is
    // under construction or not.
    address self = address(this);
    uint256 cs;
    assembly { cs := extcodesize(self) }
    return cs == 0;
  }

  // Reserved storage space to allow for layout changes in the future.
  uint256[50] private ______gap;
}

File 3 of 22 : ReentrancyGuard.sol
pragma solidity ^0.5.0;
import "./Initializable.sol";

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

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

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

    uint256[50] private ______gap;
}

File 4 of 22 : SafeMath.sol
pragma solidity ^0.5.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

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

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

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

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

File 5 of 22 : Constants.sol
pragma solidity ^0.5.0;

import "../common/SafeMath.sol";
import "../common/Decimal.sol";

contract StatusConstants {
    enum Status {
        INITIAL,
        RESOLVED,
        FAILED
    }

    // bit map
    uint256 constant STATUS_INITIAL = 0;
    uint256 constant STATUS_RESOLVED = 1;
    uint256 constant STATUS_FAILED = 1 << 1;
    uint256 constant STATUS_CANCELED = 1 << 2;
    uint256 constant STATUS_EXECUTION_EXPIRED = 1 << 3;

    function statusInitial() internal pure returns (uint256) {
        return STATUS_INITIAL;
    }

    function statusExecutionExpired() internal pure returns (uint256) {
        return STATUS_EXECUTION_EXPIRED;
    }

    function statusFailed() internal pure returns (uint256) {
        return STATUS_FAILED;
    }

    function statusCanceled() internal pure returns (uint256) {
        return STATUS_CANCELED;
    }

    function statusResolved() internal pure returns (uint256) {
        return STATUS_RESOLVED;
    }

    function isInitialStatus(uint256 status) internal pure returns (bool) {
        return status == STATUS_INITIAL;
    }

    // task assignments
    uint256 constant TASK_VOTING = 1;
}

contract Constants is StatusConstants {
    using SafeMath for uint256;

    function minVotesAbsolute(uint256 totalWeight, uint256 minVotesRatio) public pure returns (uint256) {
        return totalWeight * minVotesRatio / Decimal.unit();
    }

    function bytes32ToString(bytes32 _bytes32) public pure returns (string memory) {
        bytes memory bytesArray = new bytes(32);
        for (uint256 i; i < 32; i++) {
            bytesArray[i] = _bytes32[i];
        }
        return string(bytesArray);
    }
}

File 6 of 22 : Governance.sol
pragma solidity ^0.5.0;

import "../common/ReentrancyGuard.sol";
import "../common/SafeMath.sol";
import "../model/Governable.sol";
import "../proposal/base/IProposal.sol";
import "../verifiers/IProposalVerifier.sol";
import "../proposal/SoftwareUpgradeProposal.sol";
import "./Proposal.sol";
import "./Constants.sol";
import "./GovernanceSettings.sol";
import "./LRC.sol";
import "../version/Version.sol";
import "../votebook/votebook.sol";

contract Governance is Initializable, ReentrancyGuard, GovernanceSettings, Version {
    using SafeMath for uint256;
    using LRC for LRC.Option;

    struct Vote {
        uint256 weight;
        uint256[] choices;
    }

    struct ProposalState {
        Proposal.Parameters params;

        // voting state
        mapping(uint256 => LRC.Option) options;
        uint256 winnerOptionID;
        uint256 votes; // total weight of votes

        uint256 status;
    }

    struct Task {
        bool active;
        uint256 assignment;
        uint256 proposalID;
    }

    Governable governableContract;
    IProposalVerifier proposalVerifier;
    uint256 public lastProposalID;
    Task[] tasks;

    mapping(uint256 => ProposalState) proposals;
    mapping(address => mapping(uint256 => uint256)) public overriddenWeight; // voter address, proposalID -> weight
    mapping(address => mapping(address => mapping(uint256 => Vote))) _votes; // voter, delegationReceiver, proposalID -> Vote

    VotesBookKeeper votebook;

    event ProposalCreated(uint256 proposalID);
    event ProposalResolved(uint256 proposalID);
    event ProposalRejected(uint256 proposalID);
    event ProposalCanceled(uint256 proposalID);
    event ProposalExecutionExpired(uint256 proposalID);
    event TasksHandled(uint256 startIdx, uint256 endIdx, uint256 handled);
    event TasksErased(uint256 quantity);
    event VoteWeightOverridden(address voter, uint256 diff);
    event VoteWeightUnOverridden(address voter, uint256 diff);
    event Voted(address voter, address delegatedTo, uint256 proposalID, uint256[] choices, uint256 weight);
    event VoteCanceled(address voter, address delegatedTo, uint256 proposalID);

    function initialize(address _governableContract, address _proposalVerifier, address _votebook) public initializer {
        ReentrancyGuard.initialize();
        governableContract = Governable(_governableContract);
        proposalVerifier = IProposalVerifier(_proposalVerifier);
        votebook = VotesBookKeeper(_votebook);
    }

    function proposalParams(uint256 proposalID) public view returns (uint256 pType, Proposal.ExecType executable, uint256 minVotes, uint256 minAgreement, uint256[] memory opinionScales, bytes32[] memory options, address proposalContract, uint256 votingStartTime, uint256 votingMinEndTime, uint256 votingMaxEndTime) {
        Proposal.Parameters memory p = proposals[proposalID].params;
        return (p.pType, p.executable, p.minVotes, p.minAgreement, p.opinionScales, p.options, p.proposalContract, p.deadlines.votingStartTime, p.deadlines.votingMinEndTime, p.deadlines.votingMaxEndTime);
    }

    function proposalOptionState(uint256 proposalID, uint256 optionID) public view returns (uint256 votes, uint256 agreementRatio, uint256 agreement) {
        ProposalState storage prop = proposals[proposalID];
        LRC.Option storage opt = prop.options[optionID];
        return (opt.votes, LRC.agreementRatio(opt), opt.agreement);
    }

    function proposalState(uint256 proposalID) public view returns (uint256 winnerOptionID, uint256 votes, uint256 status) {
        ProposalState memory p = proposals[proposalID];
        return (p.winnerOptionID, p.votes, p.status);
    }

    function getVote(address from, address delegatedTo, uint256 proposalID) public view returns (uint256 weight, uint256[] memory choices) {
        Vote memory v = _votes[from][delegatedTo][proposalID];
        return (v.weight, v.choices);
    }

    function tasksCount() public view returns (uint256) {
        return (tasks.length);
    }

    function getTask(uint256 i) public view returns (bool active, uint256 assignment, uint256 proposalID) {
        Task memory t = tasks[i];
        return (t.active, t.assignment, t.proposalID);
    }

    function vote(address delegatedTo, uint256 proposalID, uint256[] calldata choices) nonReentrant external {
        if (delegatedTo == address(0)) {
            delegatedTo = msg.sender;
        }

        ProposalState storage prop = proposals[proposalID];

        require(prop.params.proposalContract != address(0), "proposal with a given ID doesnt exist");
        require(isInitialStatus(prop.status), "proposal isn't active");
        require(block.timestamp >= prop.params.deadlines.votingStartTime, "proposal voting has't begun");
        require(_votes[msg.sender][delegatedTo][proposalID].weight == 0, "vote already exists");
        require(choices.length == prop.params.options.length, "wrong number of choices");

        uint256 weight = _processNewVote(proposalID, msg.sender, delegatedTo, choices);
        require(weight != 0, "zero weight");
    }

    function createProposal(address proposalContract) nonReentrant external payable {
        require(msg.value == proposalFee(), "paid proposal fee is wrong");

        lastProposalID++;
        _createProposal(lastProposalID, proposalContract);
        addTasks(lastProposalID);

        // burn a non-reward part of the proposal fee
        burn(proposalBurntFee());

        emit ProposalCreated(lastProposalID);
    }

    function _createProposal(uint256 proposalID, address proposalContract) internal {
        require(proposalContract != address(0), "empty proposal address");
        IProposal p = IProposal(proposalContract);
        // capture the parameters once to ensure that contract will not return different values
        uint256 pType = p.pType();
        Proposal.ExecType executable = p.executable();
        uint256 minVotes = p.minVotes();
        uint256 minAgreement = p.minAgreement();
        uint256[] memory opinionScales = p.opinionScales();
        uint256 votingStartTime = p.votingStartTime();
        uint256 votingMinEndTime = p.votingMinEndTime();
        uint256 votingMaxEndTime = p.votingMaxEndTime();
        bytes32[] memory options = p.options();
        // check the parameters and contract
        require(options.length != 0, "proposal options are empty - nothing to vote for");
        require(options.length <= maxOptions(), "too many options");
        bool ok;
        ok = proposalVerifier.verifyProposalParams(pType, executable, minVotes, minAgreement, opinionScales, votingStartTime, votingMinEndTime, votingMaxEndTime);
        require(ok, "proposal parameters failed verification");
        ok = proposalVerifier.verifyProposalContract(pType, proposalContract);
        require(ok, "proposal contract failed verification");
        // save the parameters
        ProposalState storage prop = proposals[proposalID];
        prop.params.pType = pType;
        prop.params.executable = executable;
        prop.params.minVotes = minVotes;
        prop.params.minAgreement = minAgreement;
        prop.params.opinionScales = opinionScales;
        prop.params.proposalContract = proposalContract;
        prop.params.deadlines.votingStartTime = votingStartTime;
        prop.params.deadlines.votingMinEndTime = votingMinEndTime;
        prop.params.deadlines.votingMaxEndTime = votingMaxEndTime;
        prop.params.options = options;
    }

    // cancelProposal cancels the proposal if no one managed to vote yet
    // must be sent from the proposal contract
    function cancelProposal(uint256 proposalID) nonReentrant external {
        ProposalState storage prop = proposals[proposalID];
        require(prop.params.proposalContract != address(0), "proposal with a given ID doesnt exist");
        require(isInitialStatus(prop.status), "proposal isn't active");
        require(prop.votes == 0, "voting has already begun");
        require(msg.sender == prop.params.proposalContract, "must be sent from the proposal contract");

        prop.status = statusCanceled();
        emit ProposalCanceled(proposalID);
    }

    // handleTasks triggers proposal deadlines processing for a specified range of tasks
    function handleTasks(uint256 startIdx, uint256 quantity) nonReentrant external {
        uint256 handled = 0;
        uint256 i;
        for (i = startIdx; i < tasks.length && i < startIdx + quantity; i++) {
            if (handleTask(i)) {
                handled += 1;
            }
        }

        require(handled != 0, "no tasks handled");

        emit TasksHandled(startIdx, i, handled);
        // reward the sender
        msg.sender.transfer(handled.mul(taskHandlingReward()));
    }

    // tasksCleanup erases inactive (handled) tasks backwards until an active task is met
    function tasksCleanup(uint256 quantity) nonReentrant external {
        uint256 erased;
        for (erased = 0; tasks.length > 0 && erased < quantity; erased++) {
            if (!tasks[tasks.length - 1].active) {
                tasks.length--;
            } else {
                break;
                // stop when first active task was met
            }
        }
        require(erased > 0, "no tasks erased");
        emit TasksErased(erased);
        // reward the sender
        msg.sender.transfer(erased.mul(taskErasingReward()));
    }

    // handleTask calls handleTaskAssignments and marks task as inactive if it was handled
    function handleTask(uint256 taskIdx) internal returns (bool handled) {
        require(taskIdx < tasks.length, "incorrect task index");
        Task storage task = tasks[taskIdx];
        if (!task.active) {
            return false;
        }
        handled = handleTaskAssignments(tasks[taskIdx].proposalID, task.assignment);
        if (handled) {
            task.active = false;
        }
        return handled;
    }

    // handleTaskAssignments iterates through assignment types and calls a specific handler
    function handleTaskAssignments(uint256 proposalID, uint256 assignment) internal returns (bool handled) {
        ProposalState storage prop = proposals[proposalID];
        if (!isInitialStatus(prop.status)) {
            // deactivate all tasks for non-active proposals
            return true;
        }
        if (assignment == TASK_VOTING) {
            return handleVotingTask(proposalID, prop);
        }
        return false;
    }

    // handleVotingTask handles only TASK_VOTING
    function handleVotingTask(uint256 proposalID, ProposalState storage prop) internal returns (bool handled) {
        uint256 minVotesAbs = minVotesAbsolute(governableContract.getTotalWeight(), prop.params.minVotes);
        bool must = block.timestamp >= prop.params.deadlines.votingMaxEndTime;
        bool may = block.timestamp >= prop.params.deadlines.votingMinEndTime && prop.votes >= minVotesAbs;
        if (!must && !may) {
            return false;
        }
        (bool proposalResolved, uint256 winnerID) = _calculateVotingTally(prop);
        if (proposalResolved) {
            (bool ok, bool expired) = executeProposal(prop, winnerID);
            if (!ok) {
                return false;
            }
            if (!expired) {
                prop.status = statusResolved();
                prop.winnerOptionID = winnerID;
                emit ProposalResolved(proposalID);
            } else {
                prop.status = statusExecutionExpired();
                emit ProposalExecutionExpired(proposalID);
            }
        } else {
            prop.status = statusFailed();
            emit ProposalRejected(proposalID);
        }
        return true;
    }

    function executeProposal(ProposalState storage prop, uint256 winnerOptionID) internal returns (bool, bool) {
        bool executable = prop.params.executable == Proposal.ExecType.CALL || prop.params.executable == Proposal.ExecType.DELEGATECALL;
        if (!executable) {
            return (true, false);
        }

        bool executionExpired = block.timestamp > prop.params.deadlines.votingMaxEndTime + maxExecutionPeriod();
        if (executionExpired) {
            // protection against proposals which revert or consume too much gas
            return (true, true);
        }
        address propAddr = prop.params.proposalContract;
        bool success;
        bytes memory result;
        if (prop.params.executable == Proposal.ExecType.CALL) {
            (success, result) = propAddr.call(abi.encodeWithSignature("execute_call(uint256)", winnerOptionID));
        } else {
            (success, result) = propAddr.delegatecall(abi.encodeWithSignature("execute_delegatecall(address,uint256)", propAddr, winnerOptionID));
        }
        result;
        return (success, false);
    }

    function _calculateVotingTally(ProposalState storage prop) internal view returns (bool, uint256) {
        uint256 minVotesAbs = minVotesAbsolute(governableContract.getTotalWeight(), prop.params.minVotes);
        uint256 mostAgreement = 0;
        uint256 winnerID = prop.params.options.length;
        if (prop.votes < minVotesAbs) {
            return (false, winnerID);
        }
        for (uint256 i = 0; i < prop.params.options.length; i++) {
            uint256 optionID = i;
            uint256 agreement = LRC.agreementRatio(prop.options[optionID]);

            if (agreement < prop.params.minAgreement) {
                // critical resistance against this option
                continue;
            }

            if (mostAgreement == 0 || agreement > mostAgreement) {
                mostAgreement = agreement;
                winnerID = i;
            }
        }

        return (winnerID != prop.params.options.length, winnerID);
    }

    // calculateVotingTally calculates the voting tally and returns {is finished, won option ID, total weight of votes}
    function calculateVotingTally(uint256 proposalID) external view returns (bool proposalResolved, uint256 winnerID, uint256 votes) {
        ProposalState storage prop = proposals[proposalID];
        (proposalResolved, winnerID) = _calculateVotingTally(prop);
        return (proposalResolved, winnerID, prop.votes);
    }

    function cancelVote(address delegatedTo, uint256 proposalID) nonReentrant external {
        if (delegatedTo == address(0)) {
            delegatedTo = msg.sender;
        }
        Vote memory v = _votes[msg.sender][delegatedTo][proposalID];
        require(v.weight != 0, "doesn't exist");
        require(isInitialStatus(proposals[proposalID].status), "proposal isn't active");
        _cancelVote(msg.sender, delegatedTo, proposalID);
    }

    function _cancelVote(address voter, address delegatedTo, uint256 proposalID) internal {
        Vote storage v = _votes[voter][delegatedTo][proposalID];
        if (v.weight == 0) {
            return;
        }

        if (voter != delegatedTo) {
            unOverrideDelegationWeight(delegatedTo, proposalID, v.weight);
        }

        removeChoicesFromProp(proposalID, v.choices, v.weight);
        delete _votes[voter][delegatedTo][proposalID];

        if (address(votebook) != address(0)) {
            votebook.onVoteCanceled(voter, delegatedTo, proposalID);
        }

        emit VoteCanceled(voter, delegatedTo, proposalID);
    }

    function makeVote(uint256 proposalID, address voter, address delegatedTo, uint256[] memory choices, uint256 weight) internal {
        _votes[voter][delegatedTo][proposalID] = Vote(weight, choices);
        addChoicesToProp(proposalID, choices, weight);

        if (address(votebook) != address(0)) {
            votebook.onVoted(voter, delegatedTo, proposalID);
        }

        emit Voted(voter, delegatedTo, proposalID, choices, weight);
    }

    function _processNewVote(uint256 proposalID, address voterAddr, address delegatedTo, uint256[] memory choices) internal returns (uint256) {
        if (delegatedTo == voterAddr) {
            // voter isn't a delegator
            uint256 weight = governableContract.getReceivedWeight(voterAddr);
            uint256 overridden = overriddenWeight[voterAddr][proposalID];
            if (weight > overridden) {
                weight -= overridden;
            } else {
                weight = 0;
            }
            if (weight == 0) {
                return 0;
            }
            makeVote(proposalID, voterAddr, voterAddr, choices, weight);
            return weight;
        } else {
            if (_votes[delegatedTo][delegatedTo][proposalID].choices.length > 0) {
                // recount vote from delegatedTo
                // Needed only in a case if delegatedTo's received weight has changed without calling recountVote
                _recountVote(delegatedTo, delegatedTo, proposalID);
            }
            // votes through one of delegations, overrides previous vote of "delegatedTo" (if any)
            uint256 delegatedWeight = governableContract.getWeight(voterAddr, delegatedTo);
            // reduce weight of vote of "delegatedTo" (current vote or any future vote)
            overrideDelegationWeight(delegatedTo, proposalID, delegatedWeight);
            if (delegatedWeight == 0) {
                return 0;
            }
            // make own vote
            makeVote(proposalID, voterAddr, delegatedTo, choices, delegatedWeight);
            return delegatedWeight;
        }
    }

    function recountVote(address voterAddr, address delegatedTo, uint256 proposalID) nonReentrant external {
        Vote storage v = _votes[voterAddr][delegatedTo][proposalID];
        Vote storage vSuper = _votes[delegatedTo][delegatedTo][proposalID];
        require(v.choices.length > 0, "doesn't exist");
        require(isInitialStatus(proposals[proposalID].status), "proposal isn't active");
        uint256 beforeSelf = v.weight;
        uint256 beforeSuper = vSuper.weight;
        _recountVote(voterAddr, delegatedTo, proposalID);
        uint256 afterSelf = v.weight;
        uint256 afterSuper = vSuper.weight;
        // check that some weight has changed due to recounting
        require(beforeSelf != afterSelf || beforeSuper != afterSuper, "nothing changed");
    }

    function _recountVote(address voterAddr, address delegatedTo, uint256 proposalID) internal returns (uint256) {
        uint256[] memory origChoices = _votes[voterAddr][delegatedTo][proposalID].choices;
        // cancel previous vote
        _cancelVote(voterAddr, delegatedTo, proposalID);
        // re-make vote
        return _processNewVote(proposalID, voterAddr, delegatedTo, origChoices);
    }

    function overrideDelegationWeight(address delegatedTo, uint256 proposalID, uint256 weight) internal {
        uint256 overridden = overriddenWeight[delegatedTo][proposalID];
        overridden = overridden.add(weight);
        overriddenWeight[delegatedTo][proposalID] = overridden;
        Vote storage v = _votes[delegatedTo][delegatedTo][proposalID];
        if (v.choices.length > 0) {
            v.weight = v.weight.sub(weight);
            removeChoicesFromProp(proposalID, v.choices, weight);
        }
        emit VoteWeightOverridden(delegatedTo, weight);
    }

    function unOverrideDelegationWeight(address delegatedTo, uint256 proposalID, uint256 weight) internal {
        uint256 overridden = overriddenWeight[delegatedTo][proposalID];
        overridden = overridden.sub(weight);
        overriddenWeight[delegatedTo][proposalID] = overridden;
        Vote storage v = _votes[delegatedTo][delegatedTo][proposalID];
        if (v.choices.length > 0) {
            v.weight = v.weight.add(weight);
            addChoicesToProp(proposalID, v.choices, weight);
        }
        emit VoteWeightUnOverridden(delegatedTo, weight);
    }

    function addChoicesToProp(uint256 proposalID, uint256[] memory choices, uint256 weight) internal {
        ProposalState storage prop = proposals[proposalID];

        prop.votes = prop.votes.add(weight);

        for (uint256 i = 0; i < prop.params.options.length; i++) {
            prop.options[i].addVote(choices[i], weight, prop.params.opinionScales);
        }
    }

    function removeChoicesFromProp(uint256 proposalID, uint256[] memory choices, uint256 weight) internal {
        ProposalState storage prop = proposals[proposalID];

        prop.votes = prop.votes.sub(weight);

        for (uint256 i = 0; i < prop.params.options.length; i++) {
            prop.options[i].removeVote(choices[i], weight, prop.params.opinionScales);
        }
    }

    function addTasks(uint256 proposalID) internal {
        tasks.push(Task(true, TASK_VOTING, proposalID));
    }

    function burn(uint256 amount) internal {
        address(0).transfer(amount);
    }

    function sanitizeWinnerID(uint256 proposalID) external {
        ProposalState storage prop = proposals[proposalID];
        require(prop.status == STATUS_RESOLVED, "proposal isn't resolved");
        require(prop.params.executable == Proposal.ExecType.NONE, "proposal is executable");
        require(prop.winnerOptionID == 0, "winner ID is correct");
        (, prop.winnerOptionID) = _calculateVotingTally(prop);
    }

    function upgrade(address _votebook) external {
        require(address(votebook) == address(0), "already set");
        votebook = VotesBookKeeper(_votebook);
        // erase leftovers from upgradeability proxy
        assembly {
            sstore(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103, 0)
            sstore(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc, 0)
        }
    }
}

File 7 of 22 : GovernanceSettings.sol
pragma solidity ^0.5.0;

import "../common/Decimal.sol";
import "../common/SafeMath.sol";
import "../model/Governable.sol";
import "../proposal/SoftwareUpgradeProposal.sol";
import "./Constants.sol";

/**
 * @dev Various constants for governance governance settings
 */
contract GovernanceSettings is Constants {
    uint256 constant _proposalFee = _proposalBurntFee + _taskHandlingReward + _taskErasingReward;
    uint256 constant _proposalBurntFee = 50 * 1e18;
    uint256 constant _taskHandlingReward = 40 * 1e18;
    uint256 constant _taskErasingReward = 10 * 1e18;
    uint256 constant _maxOptions = 10;
    uint256 constant _maxExecutionPeriod = 3 days;

    // @dev proposalFee is the fee for a proposal
    function proposalFee() public pure returns (uint256) {
        return _proposalFee;
    }

    // @dev proposalBurntFee is the burnt part of fee for a proposal
    function proposalBurntFee() public pure returns (uint256) {
        return _proposalBurntFee;
    }

    // @dev taskHandlingReward is a reward for handling each task
    function taskHandlingReward() public pure returns (uint256) {
        return _taskHandlingReward;
    }

    // @dev taskErasingReward is a reward for erasing each task
    function taskErasingReward() public pure returns (uint256) {
        return _taskErasingReward;
    }

    // @dev maxOptions maximum number of options to choose
    function maxOptions() public pure returns (uint256) {
        return _maxOptions;
    }

    // maxExecutionPeriod is maximum time for which proposal is executable after maximum voting end date
    function maxExecutionPeriod() public pure returns (uint256) {
        return _maxExecutionPeriod;
    }
}

File 8 of 22 : LRC.sol
pragma solidity ^0.5.0;

import "../common/Decimal.sol";
import "../common/SafeMath.sol";

/**
 * @dev LRC implements the "least resistant consensus" paper. More detailed description can be found in Fantom's docs.
 */
library LRC {
    using SafeMath for uint256;

    struct Option {
        uint256 votes;
        uint256 agreement;
    }

    // agreementRatio is a ratio of option agreement (higher -> option is less supported)
    function agreementRatio(Option storage self) internal view returns (uint256) {
        if (self.votes == 0) {
            // avoid division by zero
            return 0;
        }
        return self.agreement.mul(Decimal.unit()).div(self.votes);
    }

    function maxAgreementScale(uint256[] storage opinionScales) internal view returns (uint256) {
        return opinionScales[opinionScales.length - 1];
    }

    function addVote(Option storage self, uint256 opinionID, uint256 weight, uint256[] storage opinionScales) internal {
        require(opinionID < opinionScales.length, "wrong opinion ID");

        uint256 scale = opinionScales[opinionID];

        self.votes = self.votes.add(weight);
        self.agreement = self.agreement.add(weight.mul(scale).div(maxAgreementScale(opinionScales)));
    }

    function removeVote(Option storage self, uint256 opinionID, uint256 weight, uint256[] storage opinionScales) internal {
        require(opinionID < opinionScales.length, "wrong opinion ID");

        uint256 scale = opinionScales[opinionID];

        self.votes = self.votes.sub(weight);
        self.agreement = self.agreement.sub(weight.mul(scale).div(maxAgreementScale(opinionScales)));
    }
}

File 9 of 22 : Proposal.sol
pragma solidity ^0.5.0;

import "../proposal/base/IProposal.sol";

library Proposal {
    struct Timeline {
        uint256 votingStartTime; // date when the voting starts
        uint256 votingMinEndTime; // date of earliest possible voting end
        uint256 votingMaxEndTime; // date of latest possible voting end
    }

    enum ExecType {
        NONE,
        CALL,
        DELEGATECALL
    }

    struct Parameters {
        uint256 pType; // type of proposal (e.g. plaintext, software upgrade)
        ExecType executable; // proposal execution type when proposal gets resolved
        uint256 minVotes; // min. quorum (ratio)
        // minAgreement is the minimum acceptable ratio of agreement for an option.
        // It's guaranteed not to win otherwise.
        uint256 minAgreement; // min. agreement threshold for options (ratio)
        uint256[] opinionScales;
        address proposalContract; // contract which stores the proposal data and executes its logic
        bytes32[] options;
        Timeline deadlines;
    }
}

File 10 of 22 : Governable.sol
pragma solidity ^0.5.0;

/**
 * @dev Governable defines the main interface for all governable items
 */
interface Governable {
    // Gets the total weight of voters
    function getTotalWeight() external view returns (uint256);

    // Gets the received delegated weight
    function getReceivedWeight(address addr) external view returns (uint256);

    // Gets the voting weight which is delegated from the specified address to the specified address
    function getWeight(address from, address to) external view returns (uint256);
}

File 11 of 22 : Ownable.sol
pragma solidity ^0.5.0;

import "../common/Initializable.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be aplied to your functions to restrict their use to
 * the owner.
 */
contract Ownable is Initializable {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    function initialize(address sender) internal initializer {
        _owner = sender;
        emit OwnershipTransferred(address(0), _owner);
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Returns true if the caller is the current owner.
     */
    function isOwner() public view returns (bool) {
        return msg.sender == _owner;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * > Note: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }

    uint256[50] private ______gap;
}

File 12 of 22 : NetworkParameterProposalFactory.sol
pragma solidity ^0.5.0;

import "../common/SafeMath.sol";
import "../governance/Governance.sol";
import "../proposal/NetworkParameterProposal.sol";
import "../verifiers/ScopedVerifier.sol";

contract NetworkParameterProposalFactory is ScopedVerifier {
    using SafeMath for uint256;
    Governance internal gov;
    address internal constsAddress;
    address public lastNetworkProposal;

    constructor(address _governance, address _constsAddress) public {
        gov = Governance(_governance);
        constsAddress = _constsAddress;
    }

    function create(
        string memory __description,
        uint8 __methodID,
        uint256[] memory __optionVals,
        uint256 __minVotes, uint256 __minAgreement, uint256 __start, uint256 __minEnd, uint256 __maxEnd
    ) public payable {
        NetworkParameterProposal proposal = new NetworkParameterProposal(
            __description,
            __methodID,
            __optionVals,
            constsAddress,
            __minVotes,
            __minAgreement,
            __start,
            __minEnd,
            __maxEnd,
            address(0));
        proposal.transferOwnership(msg.sender);
        lastNetworkProposal = address(proposal);

        unlockedFor = address(proposal);
        gov.createProposal.value(msg.value)(address(proposal));
        unlockedFor = address(0);
    }
}

File 13 of 22 : BaseProposal.sol
pragma solidity ^0.5.0;

import "../../common/SafeMath.sol";
import "./IProposal.sol";
import "../../verifiers/IProposalVerifier.sol";
import "../../governance/Proposal.sol";

/**
 * @dev A base for any proposal
 */
contract BaseProposal is IProposal {
    using SafeMath for uint256;

    string _name;
    string _description;
    bytes32[] _options;

    uint256 _minVotes;
    uint256 _minAgreement;
    uint256[] _opinionScales;

    uint256 _start;
    uint256 _minEnd;
    uint256 _maxEnd;

    // verifyProposalParams passes proposal parameters to a given verifier
    function verifyProposalParams(address verifier) public view returns (bool) {
        IProposalVerifier proposalVerifier = IProposalVerifier(verifier);
        return proposalVerifier.verifyProposalParams(pType(), executable(), minVotes(), minAgreement(), opinionScales(), votingStartTime(), votingMinEndTime(), votingMaxEndTime());
    }

    function pType() public view returns (uint256) {
        require(false, "must be overridden");
        return uint256(StdProposalTypes.NOT_INIT);
    }

    function executable() public view returns (Proposal.ExecType) {
        require(false, "must be overridden");
        return Proposal.ExecType.NONE;
    }

    function minVotes() public view returns (uint256) {
        return _minVotes;
    }

    function minAgreement() public view returns (uint256) {
        return _minAgreement;
    }

    function opinionScales() public view returns (uint256[] memory) {
        return _opinionScales;
    }

    function options() public view returns (bytes32[] memory) {
        return _options;
    }

    function votingStartTime() public view returns (uint256) {
        return block.timestamp + _start;
    }

    function votingMinEndTime() public view returns (uint256) {
        return votingStartTime() + _minEnd;
    }

    function votingMaxEndTime() public view returns (uint256) {
        return votingStartTime() + _maxEnd;
    }

    function name() public view returns (string memory) {
        return _name;
    }

    function description() public view returns (string memory) {
        return _description;
    }

    function execute_delegatecall(address, uint256) external {
        require(false, "not delegatecall-executable");
    }

    function execute_call(uint256) external {
        require(false, "not call-executable");
    }
}

File 14 of 22 : Cancelable.sol
pragma solidity ^0.5.0;

import "../../ownership/Ownable.sol";
import "../../governance/Governance.sol";

contract Cancelable is Ownable {
    constructor() public {
        Ownable.initialize(msg.sender);
    }

    function cancel(uint256 myID, address govAddress) external onlyOwner {
        Governance gov = Governance(govAddress);
        gov.cancelProposal(myID);
    }
}

File 15 of 22 : DelegatecallExecutableProposal.sol
pragma solidity ^0.5.0;

import "./BaseProposal.sol";
import "../../governance/Proposal.sol";

contract DelegatecallExecutableProposal is BaseProposal {
    // Returns execution type
    function executable() public view returns (Proposal.ExecType) {
        return Proposal.ExecType.DELEGATECALL;
    }

    function pType() public view returns (uint256) {
        return uint256(StdProposalTypes.UNKNOWN_DELEGATECALL_EXECUTABLE);
    }

    function execute_delegatecall(address, uint256) external {
        require(false, "must be overridden");
    }
}

File 16 of 22 : IProposal.sol
pragma solidity ^0.5.0;

import "../../governance/Proposal.sol";

/**
 * @dev An abstract proposal
 */
contract IProposal {
    // Get type of proposal (e.g. plaintext, software upgrade)
    function pType() external view returns (uint256);
    // Proposal execution type when proposal gets resolved
    function executable() external view returns (Proposal.ExecType);
    // Get min. turnout (ratio)
    function minVotes() external view returns (uint256);
    // Get min. agreement for options (ratio)
    function minAgreement() external view returns (uint256);
    // Get scales for opinions
    function opinionScales() external view returns (uint256[] memory);
    // Get options to choose from
    function options() external view returns (bytes32[] memory);
    // Get date when the voting starts
    function votingStartTime() external view returns (uint256);
    // Get date of earliest possible voting end
    function votingMinEndTime() external view returns (uint256);
    // Get date of latest possible voting end
    function votingMaxEndTime() external view returns (uint256);

    // execute proposal logic on approval (if executable == call)
    // Called via call opcode from governance contract
    function execute_call(uint256 optionID) external;

    // execute proposal logic on approval (if executable == delegatecall)
    // Called via delegatecall opcode from governance contract, hence selfAddress is provided
    function execute_delegatecall(address selfAddress, uint256 optionID) external;

    // Get human-readable name
    function name() external view returns (string memory);
    // Get human-readable description
    function description() external view returns (string memory);

    // Standard proposal types. The standard may be outdated, actual proposal templates may differ
    enum StdProposalTypes {
        NOT_INIT,
        UNKNOWN_NON_EXECUTABLE,
        UNKNOWN_CALL_EXECUTABLE,
        UNKNOWN_DELEGATECALL_EXECUTABLE
    }
}

File 17 of 22 : NetworkParameterProposal.sol
pragma solidity ^0.5.0;

import "./base/Cancelable.sol";
import "./base/DelegatecallExecutableProposal.sol";

interface ConstsI {
    function updateMinSelfStake(uint256 v) external;

    function updateMaxDelegatedRatio(uint256 v) external;

    function updateValidatorCommission(uint256 v) external;

    function updateBurntFeeShare(uint256 v) external; // 4

    function updateTreasuryFeeShare(uint256 v) external;

    function updateUnlockedRewardRatio(uint256 v) external;

    function updateMinLockupDuration(uint256 v) external;

    function updateMaxLockupDuration(uint256 v) external; // 8

    function updateWithdrawalPeriodEpochs(uint256 v) external;

    function updateWithdrawalPeriodTime(uint256 v) external;

    function updateBaseRewardPerSecond(uint256 v) external;

    function updateOfflinePenaltyThresholdTime(uint256 v) external; // 12

    function updateOfflinePenaltyThresholdBlocksNum(uint256 v) external;

    function updateTargetGasPowerPerSecond(uint256 v) external;

    function updateGasPriceBalancingCounterweight(uint256 v) external; // 15
}

/**
 * @dev NetworkParameterProposal proposal
 */
contract NetworkParameterProposal is DelegatecallExecutableProposal, Cancelable {
    using SafeMath for uint256;
    Proposal.ExecType _exec;
    ConstsI public consts;
    uint8 public methodID;
    uint256[] public getOptionVal;

    constructor(
        string memory __description,
        uint8 __methodID,
        uint256[] memory __optionsVals,
        address __consts,
        uint256 __minVotes, uint256 __minAgreement, uint256 __start, uint256 __minEnd, uint256 __maxEnd,
        address verifier
    ) public {
        require(__methodID >= 1 && __methodID <= 15, "wrong methodID");
        if (__methodID == 1) {
            _name = "Update minimum self-stake";
            _options = uintsToStrs(__optionsVals, 1e18, " FTM");
        } else if (__methodID == 2) {
            _name = "Update maximum delegated stake ratio";
            _options = uintsToStrs(__optionsVals, 1e16, " %");
        } else if (__methodID == 3) {
            _name = "Update validator rewards commission";
            _options = uintsToStrs(__optionsVals, 1e16, " %");
        } else if (__methodID == 4) {
            _name = "Update burnt fee share";
            _options = uintsToStrs(__optionsVals, 1e16, " %");
        } else if (__methodID == 5) {
            _name = "Update treasury fee share";
            _options = uintsToStrs(__optionsVals, 1e16, " %");
        } else if (__methodID == 6) {
            _name = "Update unlocked reward ratio";
            _options = uintsToStrs(__optionsVals, 1e16, " %");
        } else if (__methodID == 7) {
            _name = "Update minimum lockup duration";
            _options = uintsToStrs(__optionsVals, 1440 minutes, " days");
        } else if (__methodID == 8) {
            _name = "Update maximum lockup duration";
            _options = uintsToStrs(__optionsVals, 1440 minutes, " days");
        } else if (__methodID == 9) {
            _name = "Update number epochs of withdrawal period";
            _options = uintsToStrs(__optionsVals, 1, "");
        } else if (__methodID == 10) {
            _name = "Update withdrawal period";
            _options = uintsToStrs(__optionsVals, 60 minutes, " hours");
        } else if (__methodID == 11) {
            _name = "Update base reward per second";
            _options = uintsToStrs(__optionsVals, 1e18, " FTM");
        } else if (__methodID == 12) {
            _name = "Update time threshold for offline penalty";
            _options = uintsToStrs(__optionsVals, 60 minutes, " hours");
        } else if (__methodID == 13) {
            _name = "Update blocks threshold for offline penalty";
            _options = uintsToStrs(__optionsVals, 1, "");
        } else if (__methodID == 14) {
            _name = "Update target gas power second";
            _options = uintsToStrs(__optionsVals, 1e6, " M");
        } else {
            _name = "Update gas price balancing period";
            _options = uintsToStrs(__optionsVals, 1 minutes, " minutes");
        }
        _description = __description;
        methodID = __methodID;
        _minVotes = __minVotes;
        _minAgreement = __minAgreement;
        _start = __start;
        _minEnd = __minEnd;
        _maxEnd = __maxEnd;
        getOptionVal = __optionsVals;
        _opinionScales = [0, 1, 2, 3, 4];
        consts = ConstsI(__consts);
        // verify the proposal right away to avoid deploying a wrong proposal
        if (verifier != address(0)) {
            require(verifyProposalParams(verifier), "failed verification");
        }
    }

    function pType() public view returns (uint256) {
        // return 6003;
        return 4;
    }

    function optionVals() external view returns (uint256[] memory) {
        return getOptionVal;
    }

    event NetworkParameterUpgradeIsDone(uint256 newValue);

    function execute_delegatecall(address selfAddr, uint256 winnerOptionID) external {
        NetworkParameterProposal self = NetworkParameterProposal(selfAddr);
        uint256 __methodID = self.methodID();

        if (__methodID == 1) {
            self.consts().updateMinSelfStake(self.getOptionVal(winnerOptionID));
        } else if (__methodID == 2) {
            self.consts().updateMaxDelegatedRatio(self.getOptionVal(winnerOptionID));
        } else if (__methodID == 3) {
            self.consts().updateValidatorCommission(self.getOptionVal(winnerOptionID));
        } else if (__methodID == 4) {
            self.consts().updateBurntFeeShare(self.getOptionVal(winnerOptionID));
        } else if (__methodID == 5) {
            self.consts().updateTreasuryFeeShare(self.getOptionVal(winnerOptionID));
        } else if (__methodID == 6) {
            self.consts().updateUnlockedRewardRatio(self.getOptionVal(winnerOptionID));
        } else if (__methodID == 7) {
            self.consts().updateMinLockupDuration(self.getOptionVal(winnerOptionID));
        } else if (__methodID == 8) {
            self.consts().updateMaxLockupDuration(self.getOptionVal(winnerOptionID));
        } else if (__methodID == 9) {
            self.consts().updateWithdrawalPeriodEpochs(self.getOptionVal(winnerOptionID));
        } else if (__methodID == 10) {
            self.consts().updateWithdrawalPeriodTime(self.getOptionVal(winnerOptionID));
        } else if (__methodID == 11) {
            self.consts().updateBaseRewardPerSecond(self.getOptionVal(winnerOptionID));
        } else if (__methodID == 12) {
            self.consts().updateOfflinePenaltyThresholdTime(self.getOptionVal(winnerOptionID));
        } else if (__methodID == 13) {
            self.consts().updateOfflinePenaltyThresholdBlocksNum(self.getOptionVal(winnerOptionID));
        } else if (__methodID == 14) {
            self.consts().updateTargetGasPowerPerSecond(self.getOptionVal(winnerOptionID));
        } else {
            self.consts().updateGasPriceBalancingCounterweight(self.getOptionVal(winnerOptionID));
        }

        emit NetworkParameterUpgradeIsDone(self.getOptionVal(winnerOptionID));
    }

    function decimalsNum(uint256 num) internal pure returns (uint256) {
        uint decimals;
        while (num != 0) {
            decimals++;
            num /= 10;
        }
        return decimals;
    }

    function uint256ToB(uint256 num) internal pure returns (bytes memory) {
        if (num == 0) {
            return bytes("0");
        }
        uint decimals = decimalsNum(num);
        bytes memory bstr = new bytes(decimals);
        uint strIdx = decimals - 1;
        while (num != 0) {
            bstr[strIdx] = byte(uint8(48 + num % 10));
            num /= 10;
            strIdx--;
        }
        return bstr;
    }

    function uint256ToStr(uint256 num) internal pure returns (string memory) {
        return string(uint256ToB(num));
    }

    function decimalToStr(uint256 interger, uint256 fractional) internal pure returns (string memory) {
        bytes memory intStr = uint256ToB(interger);
        bytes memory fraStr = uint256ToB(fractional);
        // replace leading 1 with .
        fraStr[0] = byte(uint8(46));
        return string(abi.encodePacked(intStr, fraStr));
    }

    function unpackDecimal(uint256 num, uint256 unit) internal pure returns (uint256 interger, uint256 fractional) {
        assert(unit <= 1e18);
        fractional = (num % unit).mul(1e18).div(unit);
        return (num / unit, trimFractional(1e18 + fractional));
    }

    function trimFractional(uint256 fractional) internal pure returns (uint256) {
        if (fractional == 0) {
            return 0;
        }
        while (fractional % 10 == 0) {
            fractional /= 10;
        }
        return fractional;
    }

    function uintsToStrs(uint256[] memory vals, uint256 unit, string memory symbol) internal pure returns (bytes32[] memory) {
        bytes32[] memory res = new bytes32[](vals.length);
        for (uint256 i = 0; i < vals.length; i++) {
            (uint256 interger, uint256 fractional) = unpackDecimal(vals[i], unit);
            if (fractional == 1) {
                res[i] = strToB32(string(abi.encodePacked(uint256ToStr(interger), symbol)));
            } else {
                res[i] = strToB32(string(abi.encodePacked(decimalToStr(interger, fractional), symbol)));
            }
        }
        return res;
    }

    function strToB32(string memory str) internal pure returns (bytes32 result) {
        bytes memory tempEmptyStringTest = bytes(str);
        require(tempEmptyStringTest.length <= 32, "string is too long");
        if (tempEmptyStringTest.length == 0) {
            return 0x0;
        }
        assembly {
            result := mload(add(tempEmptyStringTest, 32))
        }
    }
}

File 18 of 22 : SoftwareUpgradeProposal.sol
pragma solidity ^0.5.0;

import "./base/Cancelable.sol";
import "./base/DelegatecallExecutableProposal.sol";

/**
 * @dev An interface to update this contract to a destination address
 */
interface Upgradability {
    function upgradeTo(address newImplementation) external;
}

/**
 * @dev SoftwareUpgrade proposal
 */
contract SoftwareUpgradeProposal is DelegatecallExecutableProposal, Cancelable {
    address public upgradeableContract;
    address public newImplementation;

    constructor(string memory __name, string memory __description,
        uint256 __minVotes, uint256 __minAgreement, uint256 __start, uint256 __minEnd, uint256 __maxEnd,
        address __upgradeableContract, address __newImplementation, address verifier) public {
        _name = __name;
        _description = __description;
        _options.push(bytes32("Level of agreement"));
        _minVotes = __minVotes;
        _minAgreement = __minAgreement;
        _opinionScales = [0, 1, 2, 3, 4];
        _start = __start;
        _minEnd = __minEnd;
        _maxEnd = __maxEnd;
        upgradeableContract = __upgradeableContract;
        newImplementation = __newImplementation;
        // verify the proposal right away to avoid deploying a wrong proposal
        if (verifier != address(0)) {
            require(verifyProposalParams(verifier), "failed verification");
        }
    }

    function execute_delegatecall(address selfAddr, uint256) external {
        SoftwareUpgradeProposal self = SoftwareUpgradeProposal(selfAddr);
        Upgradability(self.upgradeableContract()).upgradeTo(self.newImplementation());
    }
}

File 19 of 22 : IProposalVerifier.sol
pragma solidity ^0.5.0;

import "../governance/Proposal.sol";

/**
 * @dev A verifier can verify a proposal's inputs such as proposal parameters and proposal contract.
 */
interface IProposalVerifier {
    // Verifies proposal parameters with respect to the stored template of same type
    function verifyProposalParams(uint256 pType, Proposal.ExecType executable, uint256 minVotes, uint256 minAgreement, uint256[] calldata opinionScales, uint256 start, uint256 minEnd, uint256 maxEnd) external view returns (bool);

    // Verifies proposal contract of the specified type and address
    function verifyProposalContract(uint256 pType, address propAddr) external view returns (bool);
}

File 20 of 22 : ScopedVerifier.sol
pragma solidity ^0.5.0;

import "./IProposalVerifier.sol";
import "../governance/Governance.sol";

contract ScopedVerifier is IProposalVerifier {
    address internal unlockedFor;

    // verifyProposalParams checks proposal parameters
    function verifyProposalParams(uint256, Proposal.ExecType, uint256, uint256, uint256[] calldata, uint256, uint256, uint256) external view returns (bool) {
        return true;
    }

    // verifyProposalContract verifies proposal creator
    function verifyProposalContract(uint256, address propAddr) external view returns (bool) {
        return propAddr == unlockedFor;
    }
}

File 21 of 22 : Version.sol
pragma solidity ^0.5.0;

/**
 * @dev The version info of this contract
 */
contract Version {
    /**
     * @dev Returns the version of this contract.
     */
    function version() public pure returns (bytes4) {
        // version 00.0.2
        return "0002";
    }
}

File 22 of 22 : votebook.sol
pragma solidity ^0.5.0;

import "../ownership/Ownable.sol";

interface GovernanceI {
    function recountVote(address voterAddr, address delegatedTo, uint256 proposalID) external;

    function proposalState(uint256 proposalID) external view returns (uint256 winnerOptionID, uint256 votes, uint256 status);
}

contract VotesBookKeeper is Initializable, Ownable {
    address gov;

    uint256 public maxProposalsPerVoter;

    // voter, delegatedTo -> []proposal IDs
    mapping(address => mapping(address => uint256[])) votesList;

    // voter, delegatedTo, proposal ID -> {index in the list + 1}
    mapping(address => mapping(address => mapping(uint256 => uint256))) votesIndex;

    function initialize(address _owner, address _gov, uint256 _maxProposalsPerVoter) public initializer {
        Ownable.initialize(_owner);
        gov = _gov;
        maxProposalsPerVoter = _maxProposalsPerVoter;
    }

    function getProposalIDs(address voter, address delegatedTo) public view returns (uint256[] memory) {
        return votesList[voter][delegatedTo];
    }

    // returns vote index plus 1 if vote exists. Returns 0 if vote doesn't exist
    function getVoteIndex(address voter, address delegatedTo, uint256 proposalID) public view returns (uint256) {
        return votesIndex[voter][delegatedTo][proposalID];
    }

    function recountVotes(address voter, address delegatedTo) public {
        uint256[] storage list = votesList[voter][delegatedTo];
        uint256 origLen = list.length;
        uint256 i = 0;
        for (uint256 iter = 0; iter < origLen; iter++) {
            (bool success,) = gov.call(abi.encodeWithSignature("recountVote(address,address,uint256)", voter, delegatedTo, list[i]));
            bool evicted = false;
            if (!success) {
                // unindex if proposal isn't active
                (,, uint256 status) = GovernanceI(gov).proposalState(list[i]);
                if (status != 0) {
                    eraseVote(voter, delegatedTo, list[i], i + 1);
                    evicted = true;
                }
            }
            if (!evicted) {
                i++;
            }
        }
    }

    function onVoted(address voter, address delegatedTo, uint256 proposalID) external {
        uint256 idx = votesIndex[voter][delegatedTo][proposalID];
        if (idx > 0) {
            return;
        }
        if (votesList[voter][delegatedTo].length >= maxProposalsPerVoter) {
            // erase votes for outdated proposals
            recountVotes(voter, delegatedTo);
        }
        votesList[voter][delegatedTo].push(proposalID);
        idx = votesList[voter][delegatedTo].length;
        require(idx <= maxProposalsPerVoter, "too many votes");
        votesIndex[voter][delegatedTo][proposalID] = idx;
    }

    function onVoteCanceled(address voter, address delegatedTo, uint256 proposalID) external {
        uint256 idx = votesIndex[voter][delegatedTo][proposalID];
        if (idx == 0) {
            return;
        }
        eraseVote(voter, delegatedTo, proposalID, idx);
    }

    function eraseVote(address voter, address delegatedTo, uint256 proposalID, uint256 idx) internal {
        votesIndex[voter][delegatedTo][proposalID] = 0;
        uint256[] storage list = votesList[voter][delegatedTo];
        uint256 len = list.length;
        if (len == idx) {
            // last element
            list.length--;
        } else {
            uint256 last = list[len - 1];
            list[idx - 1] = last;
            list.length--;
            votesIndex[voter][delegatedTo][last] = idx;
        }
    }

    function setMaxProposalsPerVoter(uint256 v) onlyOwner external {
        maxProposalsPerVoter = v;
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_governance","type":"address"},{"internalType":"address","name":"_constsAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"constant":false,"inputs":[{"internalType":"string","name":"__description","type":"string"},{"internalType":"uint8","name":"__methodID","type":"uint8"},{"internalType":"uint256[]","name":"__optionVals","type":"uint256[]"},{"internalType":"uint256","name":"__minVotes","type":"uint256"},{"internalType":"uint256","name":"__minAgreement","type":"uint256"},{"internalType":"uint256","name":"__start","type":"uint256"},{"internalType":"uint256","name":"__minEnd","type":"uint256"},{"internalType":"uint256","name":"__maxEnd","type":"uint256"}],"name":"create","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"lastNetworkProposal","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"propAddr","type":"address"}],"name":"verifyProposalContract","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"enum Proposal.ExecType","name":"","type":"uint8"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"verifyProposalParams","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b5060405161362d38038061362d8339818101604052604081101561003357600080fd5b508051602090910151600180546001600160a01b039384166001600160a01b031991821617909155600280549390921692169190911790556135b38061007a6000396000f3fe608060405260043610620000445760003560e01c80632b6103bb146200004957806384d1113c146200007d578063d294ed2814620001d5578063f3f4ef791462000226575b600080fd5b3480156200005657600080fd5b5062000061620002d2565b604080516001600160a01b039092168252519081900360200190f35b620001d360048036036101008110156200009657600080fd5b810190602081018135640100000000811115620000b257600080fd5b820183602082011115620000c557600080fd5b80359060200191846001830284011164010000000083111715620000e857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929560ff8535169590949093506040810192506020013590506401000000008111156200014757600080fd5b8201836020820111156200015a57600080fd5b803590602001918460208302840111640100000000831117156200017d57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505082359350505060208101359060408101359060608101359060800135620002e1565b005b348015620001e257600080fd5b506200021260048036036040811015620001fb57600080fd5b50803590602001356001600160a01b03166200054b565b604080519115158252519081900360200190f35b3480156200023357600080fd5b506200021260048036036101008110156200024d57600080fd5b81359160ff6020820135169160408201359160608101359181019060a0810160808201356401000000008111156200028457600080fd5b8201836020820111156200029757600080fd5b80359060200191846020830284011164010000000083111715620002ba57600080fd5b91935091508035906020810135906040013562000561565b6003546001600160a01b031681565b6000888888600260009054906101000a90046001600160a01b031689898989896000604051620003119062000570565b80806020018b60ff1660ff168152602001806020018a6001600160a01b03166001600160a01b03168152602001898152602001888152602001878152602001868152602001858152602001846001600160a01b03166001600160a01b0316815260200183810383528d818151815260200191508051906020019080838360005b83811015620003ab57818101518382015260200162000391565b50505050905090810190601f168015620003d95780820380516001836020036101000a031916815260200191505b5083810382528b5181528b51602091820191808e01910280838360005b8381101562000410578181015183820152602001620003f6565b505050509050019c50505050505050505050505050604051809103906000f08015801562000442573d6000803e3d6000fd5b506040805163f2fde38b60e01b815233600482015290519192506001600160a01b0383169163f2fde38b9160248082019260009290919082900301818387803b1580156200048f57600080fd5b505af1158015620004a4573d6000803e3d6000fd5b5050600380546001600160a01b038086166001600160a01b031992831681179093556000805490921683178255600154604080516307eecaf560e01b8152600481019590955251911694506307eecaf593503492602480820193929182900301818588803b1580156200051657600080fd5b505af11580156200052b573d6000803e3d6000fd5b5050600080546001600160a01b0319169055505050505050505050505050565b6000546001600160a01b03908116911614919050565b60019998505050505050505050565b613000806200057f8339019056fe60806040523480156200001157600080fd5b50604051620030003803806200300083398181016040526101408110156200003857600080fd5b81019080805160405193929190846401000000008211156200005957600080fd5b9083019060208201858111156200006f57600080fd5b82516401000000008111828201881017156200008a57600080fd5b82525081516020918201929091019080838360005b83811015620000b95781810151838201526020016200009f565b50505050905090810190601f168015620000e75780820380516001836020036101000a031916815260200191505b506040818152602083015192018051929491939192846401000000008211156200011057600080fd5b9083019060208201858111156200012657600080fd5b82518660208202830111640100000000821117156200014457600080fd5b82525081516020918201928201910280838360005b838110156200017357818101518382015260200162000159565b50505050919091016040908152602083810151918401516060850151608086015160a087015160c088015160e090980151959950929750909590945090929091620001c9903390620017db62000943821b17901c565b60018960ff1610158015620001e25750600f8960ff1611155b62000225576040805162461bcd60e51b815260206004820152600e60248201526d1ddc9bdb99c81b595d1a1bd9125160921b604482015290519081900360640190fd5b8860ff1660011415620002cd576040805180820190915260198082527f557064617465206d696e696d756d2073656c662d7374616b650000000000000060209092019182526200027891600091620012db565b50620002b088670de0b6b3a7640000604051806040016040528060048152602001632046544d60e01b81525062000a4660201b60201c565b8051620002c6916002916020909101906200135c565b5062000805565b8860ff16600214156200033f5760405180606001604052806024815260200162002fbb6024913980516200030a91600091602090910190620012db565b50620002b088662386f26fc1000060405180604001604052806002815260200161202560f01b81525062000a4660201b60201c565b8860ff16600314156200037c5760405180606001604052806023815260200162002f6a6023913980516200030a91600091602090910190620012db565b8860ff1660041415620003cf576040805180820190915260168082527f557064617465206275726e74206665652073686172650000000000000000000060209092019182526200030a91600091620012db565b8860ff166005141562000422576040805180820190915260198082527f557064617465207472656173757279206665652073686172650000000000000060209092019182526200030a91600091620012db565b8860ff1660061415620004755760408051808201909152601c8082527f55706461746520756e6c6f636b65642072657761726420726174696f0000000060209092019182526200030a91600091620012db565b8860ff1660071415620004fc5760408051808201909152601e8082527f557064617465206d696e696d756d206c6f636b7570206475726174696f6e00006020909201918252620004c891600091620012db565b50620002b0886201518060405180604001604052806005815260200164206461797360d81b81525062000a4660201b60201c565b8860ff16600814156200054f5760408051808201909152601e8082527f557064617465206d6178696d756d206c6f636b7570206475726174696f6e00006020909201918252620004c891600091620012db565b8860ff1660091415620005b05760405180606001604052806029815260200162002ef76029913980516200058c91600091602090910190620012db565b50620002b08860016040518060200160405280600081525062000a4660201b60201c565b8860ff16600a141562000637576040805180820190915260188082527f557064617465207769746864726177616c20706572696f64000000000000000060209092019182526200060391600091620012db565b50620002b088610e106040518060400160405280600681526020016520686f75727360d01b81525062000a4660201b60201c565b8860ff16600b14156200068a5760408051808201909152601d8082527f55706461746520626173652072657761726420706572207365636f6e6400000060209092019182526200027891600091620012db565b8860ff16600c1415620006c75760405180606001604052806029815260200162002f206029913980516200060391600091602090910190620012db565b8860ff16600d141562000704576040518060600160405280602b815260200162002ecc602b913980516200058c91600091602090910190620012db565b8860ff16600e1415620007885760408051808201909152601e8082527f557064617465207461726765742067617320706f776572207365636f6e64000060209092019182526200075791600091620012db565b50620002b088620f424060405180604001604052806002815260200161204d60f01b81525062000a4660201b60201c565b60405180606001604052806021815260200162002fdf602191398051620007b891600091602090910190620012db565b50620007ed88603c60405180604001604052806008815260200167206d696e7574657360c01b81525062000a4660201b60201c565b805162000803916002916020909101906200135c565b505b89516200081a9060019060208d0190620012db565b50606f805460ff60a81b1916600160a81b60ff8c1602179055600386905560048590556006849055600783905560088290558751620008619060709060208b01906200135c565b506040805160a081018252600081526001602082015260029181019190915260036060820152600460808201526200089d906005908162001399565b50606f80546001600160a01b03808a1661010002610100600160a81b0319909216919091179091558116156200093357620008e1816001600160e01b0362000bfa16565b62000933576040805162461bcd60e51b815260206004820152601360248201527f6661696c656420766572696669636174696f6e00000000000000000000000000604482015290519081900360640190fd5b50505050505050505050620013f9565b600954610100900460ff1680620009685750620009686001600160e01b0362000d9016565b8062000977575060095460ff16155b620009b45760405162461bcd60e51b815260040180806020018281038252602e81526020018062002f8d602e913960400191505060405180910390fd5b600954610100900460ff16158015620009e0576009805460ff1961ff0019909116610100171660011790555b603c80546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3801562000a42576009805461ff00191690555b5050565b606080845160405190808252806020026020018201604052801562000a75578160200160208202803883390190505b50905060005b855181101562000bf15760008062000aae88848151811062000a9957fe5b60200260200101518862000d9760201b60201c565b91509150806001141562000bb35762000b9462000ad4836001600160e01b0362000e2816565b876040516020018083805190602001908083835b6020831062000b095780518252601f19909201916020918201910162000ae8565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b6020831062000b535780518252601f19909201916020918201910162000b32565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405262000e4460201b60201c565b84848151811062000ba157fe5b60200260200101818152505062000be6565b62000bcc62000ad483836001600160e01b0362000eb416565b84848151811062000bd957fe5b6020026020010181815250505b505060010162000a7b565b50949350505050565b6000816001600160a01b03811663f3f4ef7962000c1f6001600160e01b0362000fce16565b62000c326001600160e01b0362000fd316565b62000c456001600160e01b0362000fd816565b62000c586001600160e01b0362000fde16565b62000c6b6001600160e01b0362000fe416565b62000c7e6001600160e01b036200103e16565b62000c916001600160e01b036200104616565b62000ca46001600160e01b036200106516565b6040518963ffffffff1660e01b81526004018089815260200188600281111562000cca57fe5b60ff16815260200187815260200186815260200180602001858152602001848152602001838152602001828103825286818151815260200191508051906020019060200280838360005b8381101562000d2e57818101518382015260200162000d14565b50505050905001995050505050505050505060206040518083038186803b15801562000d5957600080fd5b505afa15801562000d6e573d6000803e3d6000fd5b505050506040513d602081101562000d8557600080fd5b50519150505b919050565b303b155b90565b600080670de0b6b3a764000083111562000dad57fe5b62000df28362000dde670de0b6b3a764000086888162000dc957fe5b066200107e60201b620018cd1790919060201c565b620010e360201b6200192f1790919060201c565b905082848162000dfe57fe5b0462000e1d670de0b6b3a764000083016001600160e01b036200112d16565b915091509250929050565b606062000e3e826001600160e01b036200115716565b92915050565b6000606082905060208151111562000e98576040805162461bcd60e51b8152602060048201526012602482015271737472696e6720697320746f6f206c6f6e6760701b604482015290519081900360640190fd5b805162000eaa57506000905062000d8b565b6020015192915050565b60608062000ecb846001600160e01b036200115716565b9050606062000ee3846001600160e01b036200115716565b9050602e60f81b8160008151811062000ef857fe5b60200101906001600160f81b031916908160001a90535081816040516020018083805190602001908083835b6020831062000f455780518252601f19909201916020918201910162000f24565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b6020831062000f8f5780518252601f19909201916020918201910162000f6e565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040529250505092915050565b600490565b600290565b60035490565b60045490565b606060058054806020026020016040519081016040528092919081815260200182805480156200103457602002820191906000526020600020905b8154815260200190600101908083116200101f575b5050505050905090565b600654420190565b6007546000906200105f6001600160e01b036200103e16565b01905090565b6008546000906200105f6001600160e01b036200103e16565b6000826200108f5750600062000e3e565b828202828482816200109d57fe5b0414620010dc5760405162461bcd60e51b815260040180806020018281038252602181526020018062002f496021913960400191505060405180910390fd5b9392505050565b6000620010dc83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506200121a60201b60201c565b6000816200113e5750600062000d8b565b600a82066200115357600a820491506200113e565b5090565b6060816200117e57506040805180820190915260018152600360fc1b602082015262000d8b565b600062001194836001600160e01b03620012c116565b90506060816040519080825280601f01601f191660200182016040528015620011c4576020820181803883390190505b50905060001982015b84156200121257600a850660300160f81b828281518110620011eb57fe5b60200101906001600160f81b031916908160001a905350600a8504945060001901620011cd565b509392505050565b60008183620012aa5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156200126e57818101518382015260200162001254565b50505050905090810190601f1680156200129c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581620012b757fe5b0495945050505050565b6000805b821562000e3e57600101600a83049250620012c5565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200131e57805160ff19168380011785556200134e565b828001600101855582156200134e579182015b828111156200134e57825182559160200191906001019062001331565b5062001153929150620013dc565b8280548282559060005260206000209081019282156200134e57916020028201828111156200134e57825182559160200191906001019062001331565b8280548282559060005260206000209081019282156200134e579160200282015b828111156200134e578251829060ff16905591602001919060010190620013ba565b62000d9491905b80821115620011535760008155600101620013e3565b611ac380620014096000396000f3fe608060405234801561001057600080fd5b506004361061014d5760003560e01c8063715018a6116100c3578063a61e393a1161007c578063a61e393a14610355578063aa3daba91461035d578063cb00e7d314610389578063d86d744e146103af578063e6f94d55146103b7578063f2fde38b146103d55761014d565b8063715018a6146102e05780637284e416146102e857806389d5b8ea146102f05780638da5cb5b1461030d5780638f32d59b146103315780639b3a8a071461034d5761014d565b80632842f0c2116101155780632842f0c2146102755780633cc228fd1461027d57806357d682c41461028557806363012d01146102b35780636eb067a0146102d05780636f24f8a1146102d85761014d565b806306fdde03146101525780631069143a146101cf57806316131a18146102275780632019a60814610253578063216b91161461026d575b600080fd5b61015a6103fb565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561019457818101518382015260200161017c565b50505050905090810190601f1680156101c15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101d7610491565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156102135781810151838201526020016101fb565b505050509050019250505060405180910390f35b61022f6104e8565b6040518082600281111561023f57fe5b60ff16815260200191505060405180910390f35b61025b6104ed565b60408051918252519081900360200190f35b61025b6104f5565b6101d76104fa565b61025b610550565b6102b16004803603604081101561029b57600080fd5b50803590602001356001600160a01b0316610556565b005b6102b1600480360360208110156102c957600080fd5b5035610617565b61025b61065d565b6101d7610663565b6102b16106b9565b61015a61075c565b61025b6004803603602081101561030657600080fd5b50356107bc565b6103156107da565b604080516001600160a01b039092168252519081900360200190f35b6103396107e9565b604080519115158252519081900360200190f35b61025b6107fa565b61025b61080d565b6102b16004803603604081101561037357600080fd5b506001600160a01b03813516906020013561081a565b6103396004803603602081101561039f57600080fd5b50356001600160a01b0316611583565b6103156116b9565b6103bf6116cd565b6040805160ff9092168252519081900360200190f35b6102b1600480360360208110156103eb57600080fd5b50356001600160a01b03166116dd565b60008054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104875780601f1061045c57610100808354040283529160200191610487565b820191906000526020600020905b81548152906001019060200180831161046a57829003601f168201915b5050505050905090565b6060600280548060200260200160405190810160405280929190818152602001828054801561048757602002820191906000526020600020905b8154815260200190600101908083116104cb575050505050905090565b600290565b600654420190565b600490565b6060607080548060200260200160405190810160405280929190818152602001828054801561048757602002820191906000526020600020908154815260200190600101908083116104cb575050505050905090565b60035490565b61055e6107e9565b6105af576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6000819050806001600160a01b031663e0a8f6f5846040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156105fa57600080fd5b505af115801561060e573d6000803e3d6000fd5b50505050505050565b6040805162461bcd60e51b81526020600482015260136024820152726e6f742063616c6c2d65786563757461626c6560681b604482015290519081900360640190fd5b50565b60045490565b6060600580548060200260200160405190810160405280929190818152602001828054801561048757602002820191906000526020600020908154815260200190600101908083116104cb575050505050905090565b6106c16107e9565b610712576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b603c546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603c80546001600160a01b0319169055565b60018054604080516020601f600260001961010087891615020190951694909404938401819004810282018101909252828152606093909290918301828280156104875780601f1061045c57610100808354040283529160200191610487565b607081815481106107c957fe5b600091825260209091200154905081565b603c546001600160a01b031690565b603c546001600160a01b0316331490565b60006007546108076104ed565b01905090565b60006008546108076104ed565b60008290506000816001600160a01b031663e6f94d556040518163ffffffff1660e01b815260040160206040518083038186803b15801561085a57600080fd5b505afa15801561086e573d6000803e3d6000fd5b505050506040513d602081101561088457600080fd5b505160ff16905060018114156109d357816001600160a01b031663d86d744e6040518163ffffffff1660e01b815260040160206040518083038186803b1580156108cd57600080fd5b505afa1580156108e1573d6000803e3d6000fd5b505050506040513d60208110156108f757600080fd5b5051604080516344eadc7560e11b81526004810186905290516001600160a01b039283169263866c4b1792908616916389d5b8ea91602480820192602092909190829003018186803b15801561094c57600080fd5b505afa158015610960573d6000803e3d6000fd5b505050506040513d602081101561097657600080fd5b5051604080516001600160e01b031960e085901b168152600481019290925251602480830192600092919082900301818387803b1580156109b657600080fd5b505af11580156109ca573d6000803e3d6000fd5b505050506114db565b8060021415610a9457816001600160a01b031663d86d744e6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a1557600080fd5b505afa158015610a29573d6000803e3d6000fd5b505050506040513d6020811015610a3f57600080fd5b5051604080516344eadc7560e11b81526004810186905290516001600160a01b03928316926381ffcdf192908616916389d5b8ea91602480820192602092909190829003018186803b15801561094c57600080fd5b8060031415610b5557816001600160a01b031663d86d744e6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ad657600080fd5b505afa158015610aea573d6000803e3d6000fd5b505050506040513d6020811015610b0057600080fd5b5051604080516344eadc7560e11b81526004810186905290516001600160a01b0392831692632ee7113292908616916389d5b8ea91602480820192602092909190829003018186803b15801561094c57600080fd5b8060041415610c1657816001600160a01b031663d86d744e6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b9757600080fd5b505afa158015610bab573d6000803e3d6000fd5b505050506040513d6020811015610bc157600080fd5b5051604080516344eadc7560e11b81526004810186905290516001600160a01b0392831692632bb9fe8d92908616916389d5b8ea91602480820192602092909190829003018186803b15801561094c57600080fd5b8060051415610cd757816001600160a01b031663d86d744e6040518163ffffffff1660e01b815260040160206040518083038186803b158015610c5857600080fd5b505afa158015610c6c573d6000803e3d6000fd5b505050506040513d6020811015610c8257600080fd5b5051604080516344eadc7560e11b81526004810186905290516001600160a01b039283169263f8d5177e92908616916389d5b8ea91602480820192602092909190829003018186803b15801561094c57600080fd5b8060061415610d9857816001600160a01b031663d86d744e6040518163ffffffff1660e01b815260040160206040518083038186803b158015610d1957600080fd5b505afa158015610d2d573d6000803e3d6000fd5b505050506040513d6020811015610d4357600080fd5b5051604080516344eadc7560e11b81526004810186905290516001600160a01b0392831692637945ef9992908616916389d5b8ea91602480820192602092909190829003018186803b15801561094c57600080fd5b8060071415610e5957816001600160a01b031663d86d744e6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dda57600080fd5b505afa158015610dee573d6000803e3d6000fd5b505050506040513d6020811015610e0457600080fd5b5051604080516344eadc7560e11b81526004810186905290516001600160a01b039283169263bf25338b92908616916389d5b8ea91602480820192602092909190829003018186803b15801561094c57600080fd5b8060081415610f1a57816001600160a01b031663d86d744e6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e9b57600080fd5b505afa158015610eaf573d6000803e3d6000fd5b505050506040513d6020811015610ec557600080fd5b5051604080516344eadc7560e11b81526004810186905290516001600160a01b039283169263ad7b3f7b92908616916389d5b8ea91602480820192602092909190829003018186803b15801561094c57600080fd5b8060091415610fdb57816001600160a01b031663d86d744e6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f5c57600080fd5b505afa158015610f70573d6000803e3d6000fd5b505050506040513d6020811015610f8657600080fd5b5051604080516344eadc7560e11b81526004810186905290516001600160a01b0392831692638f078bfa92908616916389d5b8ea91602480820192602092909190829003018186803b15801561094c57600080fd5b80600a141561109c57816001600160a01b031663d86d744e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561101d57600080fd5b505afa158015611031573d6000803e3d6000fd5b505050506040513d602081101561104757600080fd5b5051604080516344eadc7560e11b81526004810186905290516001600160a01b039283169263455366a492908616916389d5b8ea91602480820192602092909190829003018186803b15801561094c57600080fd5b80600b141561115d57816001600160a01b031663d86d744e6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110de57600080fd5b505afa1580156110f2573d6000803e3d6000fd5b505050506040513d602081101561110857600080fd5b5051604080516344eadc7560e11b81526004810186905290516001600160a01b039283169263b6d9edd592908616916389d5b8ea91602480820192602092909190829003018186803b15801561094c57600080fd5b80600c141561121e57816001600160a01b031663d86d744e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561119f57600080fd5b505afa1580156111b3573d6000803e3d6000fd5b505050506040513d60208110156111c957600080fd5b5051604080516344eadc7560e11b81526004810186905290516001600160a01b0392831692636348ebb892908616916389d5b8ea91602480820192602092909190829003018186803b15801561094c57600080fd5b80600d14156112df57816001600160a01b031663d86d744e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561126057600080fd5b505afa158015611274573d6000803e3d6000fd5b505050506040513d602081101561128a57600080fd5b5051604080516344eadc7560e11b81526004810186905290516001600160a01b0392831692632e84e8e692908616916389d5b8ea91602480820192602092909190829003018186803b15801561094c57600080fd5b80600e14156113a057816001600160a01b031663d86d744e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561132157600080fd5b505afa158015611335573d6000803e3d6000fd5b505050506040513d602081101561134b57600080fd5b5051604080516344eadc7560e11b81526004810186905290516001600160a01b0392831692634332686792908616916389d5b8ea91602480820192602092909190829003018186803b15801561094c57600080fd5b816001600160a01b031663d86d744e6040518163ffffffff1660e01b815260040160206040518083038186803b1580156113d957600080fd5b505afa1580156113ed573d6000803e3d6000fd5b505050506040513d602081101561140357600080fd5b5051604080516344eadc7560e11b81526004810186905290516001600160a01b039283169263d3f48dbe92908616916389d5b8ea91602480820192602092909190829003018186803b15801561145857600080fd5b505afa15801561146c573d6000803e3d6000fd5b505050506040513d602081101561148257600080fd5b5051604080516001600160e01b031960e085901b168152600481019290925251602480830192600092919082900301818387803b1580156114c257600080fd5b505af11580156114d6573d6000803e3d6000fd5b505050505b7f429f0e2ca73311a31e395b735e0bff6a88fb01c4f53b8dcdde0a6f208ee2f6ce826001600160a01b03166389d5b8ea856040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561154057600080fd5b505afa158015611554573d6000803e3d6000fd5b505050506040513d602081101561156a57600080fd5b505160408051918252519081900360200190a150505050565b6000816001600160a01b03811663f3f4ef7961159d6104f5565b6115a56104e8565b6115ad610550565b6115b561065d565b6115bd610663565b6115c56104ed565b6115cd6107fa565b6115d561080d565b6040518963ffffffff1660e01b8152600401808981526020018860028111156115fa57fe5b60ff16815260200187815260200186815260200180602001858152602001848152602001838152602001828103825286818151815260200191508051906020019060200280838360005b8381101561165c578181015183820152602001611644565b50505050905001995050505050505050505060206040518083038186803b15801561168657600080fd5b505afa15801561169a573d6000803e3d6000fd5b505050506040513d60208110156116b057600080fd5b50519392505050565b606f5461010090046001600160a01b031681565b606f54600160a81b900460ff1681565b6116e56107e9565b611736576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b61065a816001600160a01b03811661177f5760405162461bcd60e51b8152600401808060200182810382526026815260200180611a1a6026913960400191505060405180910390fd5b603c546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603c80546001600160a01b0319166001600160a01b0392909216919091179055565b600954610100900460ff16806117f457506117f4611971565b80611802575060095460ff16155b61183d5760405162461bcd60e51b815260040180806020018281038252602e815260200180611a61602e913960400191505060405180910390fd5b600954610100900460ff16158015611868576009805460ff1961ff0019909116610100171660011790555b603c80546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a380156118c9576009805461ff00191690555b5050565b6000826118dc57506000611929565b828202828482816118e957fe5b04146119265760405162461bcd60e51b8152600401808060200182810382526021815260200180611a406021913960400191505060405180910390fd5b90505b92915050565b600061192683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611977565b303b1590565b60008183611a035760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156119c85781810151838201526020016119b0565b50505050905090810190601f1680156119f55780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581611a0f57fe5b049594505050505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564a265627a7a72315820d9717271113959374c09d444a1ba5eafcc9e63b058830c9d7dc03b72e8c0b14b64736f6c6343000511003255706461746520626c6f636b73207468726573686f6c6420666f72206f66666c696e652070656e616c7479557064617465206e756d6265722065706f636873206f66207769746864726177616c20706572696f645570646174652074696d65207468726573686f6c6420666f72206f66666c696e652070656e616c7479536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775570646174652076616c696461746f72207265776172647320636f6d6d697373696f6e436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a6564557064617465206d6178696d756d2064656c656761746564207374616b6520726174696f557064617465206761732070726963652062616c616e63696e6720706572696f64a265627a7a72315820e5a8126504e5adc65c22d0a64f04531f942f3b7928f32e565a6f49e44e7314d264736f6c63430005110032000000000000000000000000aa3a160e91f63f1db959640e0a7b8911b6bd5b95000000000000000000000000f58d44b8957ab7a6384c9a6079f7554311d52e9c

Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Validator ID :
0 FTM

Amount Staked
0

Amount Delegated
0

Staking Total
0

Staking Start Epoch
0

Staking Start Time
0

Proof of Importance
0

Origination Score
0

Validation Score
0

Active
0

Online
0

Downtime
0 s
Address Amount claimed Rewards Created On Epoch Created On
Block Uncle Number Difficulty Gas Used Reward
Loading