Contract 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f 2

Contract Overview

Balance:
0 BNB
Txn Hash Method
Block
From
To
Value [Txn Fee]
0xddc493e17a23b0ae09a2f60cee832a8031d4e4205dc7771fec65932445b078f5Mint126540912021-09-24 20:19:337 hrs 55 mins ago0xbbd4da3e86f610adcf555ff3b2f51869ed5c7cca IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.00120016
0x0583b1708d3dc4e989c98c0b5a00715846778ba4ba68ba6fb2db630d4c8b9cd4Approve126540762021-09-24 20:18:487 hrs 56 mins ago0xbbd4da3e86f610adcf555ff3b2f51869ed5c7cca IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.0004443
0x7afae3b206bcb84057d107642e9e9b166d0e41266537772c1a5dba5e18b45737Mint126540582021-09-24 20:17:547 hrs 57 mins ago0xbbd4da3e86f610adcf555ff3b2f51869ed5c7cca IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.00147992
0x8d9d6b054f23fd2a38a53e7ac5687efe87a3f04e508611ccfe56052d1f1a8f6fMint125838792021-09-22 9:38:412 days 18 hrs ago0x8710241aede4b6e11eb3f765cd81ac9a5d62da7b IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.00147992
0xf2e8243d13613572947377bacb70c5c08809b24ff733b83b20139c61a63088fcApprove124750262021-09-18 14:10:496 days 14 hrs ago0x792bdae2991fec8a8c805a489c1a8dbea5bbe244 IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.0004443
0x360abf4179653715665308d9c388bb42f7244217d282d1106a21d3d3cc7fc7a4Approve124750192021-09-18 14:10:286 days 14 hrs ago0x792bdae2991fec8a8c805a489c1a8dbea5bbe244 IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.0004443
0x89801c5bf26b9bea293b3031dad75ece1690e19cd333d4ae7d89b2650e9fac76Mint124749802021-09-18 14:08:316 days 14 hrs ago0x792bdae2991fec8a8c805a489c1a8dbea5bbe244 IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.00147992
0x4044e4a098746a5b1cbd50a7c8eba4b16bcedeab699ff98f8eb12a88a1106fb1Mint123967572021-09-15 20:12:109 days 8 hrs ago0x117100702097966dfde19c3c9f0676667d0e11a4 IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.00120016
0x158354444bb30716f254c882a98f82cf8a33ba7b758120ee845d77e63d0b5051Mint123967262021-09-15 20:10:379 days 8 hrs ago0x117100702097966dfde19c3c9f0676667d0e11a4 IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.00120016
0x0fc56334486bc369f8e085d1cfacd7cbebc30266eaa8ce08fb3c23cecda28688Approve123966202021-09-15 20:05:199 days 8 hrs ago0x117100702097966dfde19c3c9f0676667d0e11a4 IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.0004443
0x2a261f6a2f477855fa6ad4dde0aeaf56ee6c4147efa7da1f714e63526a87b5d6Mint123966072021-09-15 20:04:409 days 8 hrs ago0x117100702097966dfde19c3c9f0676667d0e11a4 IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.00147992
0x91eedc8c5c3f4cd9e71f76bf7a0c2772d3ae278192be5ccfb621a95fbc85087bApprove123844592021-09-15 9:57:169 days 18 hrs ago0x85a1a4d0d5ff4d35273fbfc70ec0f7a8a76acc3f IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.0004443
0xe34b4583163a19c07da619b004efa84310aac73444c83a2e7f6eeef766df9913Mint123844352021-09-15 9:56:049 days 18 hrs ago0x85a1a4d0d5ff4d35273fbfc70ec0f7a8a76acc3f IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.00147992
0x0ff066dfe39c09ad1ed71475c0efdc0f70a45a1e4cf52cbc529b715e2a60ac28Transfer123562542021-09-14 10:09:2510 days 18 hrs ago0x46be08bd59404f3f18f7079113f7f4040c50dd75 IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.00212993
0x4e5790119814d83506c997f06595988e013eb864cbc744910bf9b88dddaaa56aApprove123396772021-09-13 20:07:3411 days 8 hrs ago0x417c418692a488a5a1e31bc3c4a35db9d31f9b53 IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.0004443
0xb5365b739ec81f49137b498502cb4763cdc72794826635be4de8bf2a59b3576dMint123396512021-09-13 20:06:1611 days 8 hrs ago0x417c418692a488a5a1e31bc3c4a35db9d31f9b53 IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.00120016
0x156a82225344eec08cdc70e1257d6c6628e2af03cc7b06dd3ab6404b81e0c065Approve123395992021-09-13 20:03:4011 days 8 hrs ago0x417c418692a488a5a1e31bc3c4a35db9d31f9b53 IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.0004443
0xc8dcfe3eeed0eaaa24c56f70b90a5203e115486cc3038d583a08d45c3208c725Mint123395882021-09-13 20:03:0711 days 8 hrs ago0x417c418692a488a5a1e31bc3c4a35db9d31f9b53 IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.00147992
0xe88e828b2949dbc59abec770c0fe475a08fe58ddfb013f49c632f5bd4833a9aeApprove123071702021-09-12 17:00:5312 days 11 hrs ago0xfe8398a8193727c367491d3cac2a94050e090151 IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.0004443
0xf8c5a5b11e37d6ca29d29e9a6c13dc306b5c7713a8f5bf9232c5be4b4575b749Approve123054492021-09-12 15:34:5012 days 12 hrs ago0x46be08bd59404f3f18f7079113f7f4040c50dd75 IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.0004443
0x30f4a37abc5b14b6fa6d5987f2197e85ef08c2b620863238693168e946595db2Approve122978912021-09-12 8:51:1112 days 19 hrs ago0x8836a6d115b4396625dc7700d2eb6a2d7b6975cd IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.0004443
0x5a0d0cb729fd38641de8d11b83d4af3c5881daceb62b2a8c883f8cd7f5b365caApprove122793342021-09-11 17:19:0413 days 10 hrs ago0x229f40760c44c32681466d5d6f2f138408477f3f IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.0004443
0xbd2b15bdb2d1f09060cddb64c9a983e7992aa6f28a6580d2c8fcd7ee5637d026Mint122793212021-09-11 17:18:2513 days 10 hrs ago0x229f40760c44c32681466d5d6f2f138408477f3f IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.00120016
0xeb3c54bb2c704eb07eb9ed2a516074ac6290237be181dd898eda4fdfcb0753a2Mint122792832021-09-11 17:16:3113 days 10 hrs ago0x229f40760c44c32681466d5d6f2f138408477f3f IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.00120016
0xd1de28b20eb4bc3c260e8e433c74eca16ebb150eb9a185a004d9df493191c914Approve122792712021-09-11 17:15:5513 days 10 hrs ago0x229f40760c44c32681466d5d6f2f138408477f3f IN  0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB0.0004443
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xb2ed2b0ad58453186abe4689e38d7cd49b1163ea8b95089b083e38657848e4da126541312021-09-24 20:21:337 hrs 53 mins ago 0x58d2b3d193dfdc42fe4e3e6065307365d0157eca 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0xb2ed2b0ad58453186abe4689e38d7cd49b1163ea8b95089b083e38657848e4da126541312021-09-24 20:21:337 hrs 53 mins ago 0x58d2b3d193dfdc42fe4e3e6065307365d0157eca 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0x0195de2ea358edd7ca2bef8da6e30db287045b2013e42efe7a7aa8903daa9f7a126541052021-09-24 20:20:157 hrs 54 mins ago 0x58d2b3d193dfdc42fe4e3e6065307365d0157eca 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0x0195de2ea358edd7ca2bef8da6e30db287045b2013e42efe7a7aa8903daa9f7a126541052021-09-24 20:20:157 hrs 54 mins ago 0x58d2b3d193dfdc42fe4e3e6065307365d0157eca 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0xd83f88c2aeccee692a4bb132727930031e4b5d97d080181c872f03bf5ef86d0d126540832021-09-24 20:19:097 hrs 55 mins ago 0x58d2b3d193dfdc42fe4e3e6065307365d0157eca 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0xd83f88c2aeccee692a4bb132727930031e4b5d97d080181c872f03bf5ef86d0d126540832021-09-24 20:19:097 hrs 55 mins ago 0x58d2b3d193dfdc42fe4e3e6065307365d0157eca 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0xa3be809de6c83e259fa835e8dbea0118cafe279180f49e09e5297efcc5df7b0b124750362021-09-18 14:11:196 days 14 hrs ago 0xf269d144755f57eacb0adbd4e3150d1416a538cb 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0x7c459bf518deeee3ae44e3b9968a957e784654e5ec0471d339064fe1415d6934124750312021-09-18 14:11:046 days 14 hrs ago 0x58d2b3d193dfdc42fe4e3e6065307365d0157eca 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0x7c459bf518deeee3ae44e3b9968a957e784654e5ec0471d339064fe1415d6934124750312021-09-18 14:11:046 days 14 hrs ago 0x58d2b3d193dfdc42fe4e3e6065307365d0157eca 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0xa93eb516627dbc203d09d6780f39dac15d3b7cfa7d9e696c5bd11d2c266dfebd123967722021-09-15 20:12:559 days 8 hrs ago 0x58d2b3d193dfdc42fe4e3e6065307365d0157eca 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0xa93eb516627dbc203d09d6780f39dac15d3b7cfa7d9e696c5bd11d2c266dfebd123967722021-09-15 20:12:559 days 8 hrs ago 0x58d2b3d193dfdc42fe4e3e6065307365d0157eca 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0xc80ff24ed11b6d2430b1d8e48c44d831b9329b429448a9770878df0a0fbf03af123967382021-09-15 20:11:139 days 8 hrs ago 0x58d2b3d193dfdc42fe4e3e6065307365d0157eca 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0xc80ff24ed11b6d2430b1d8e48c44d831b9329b429448a9770878df0a0fbf03af123967382021-09-15 20:11:139 days 8 hrs ago 0x58d2b3d193dfdc42fe4e3e6065307365d0157eca 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0x71b9a4c8f3f84e1cb83b75eb5a99b1d4ecc9695b83a36d7680f040a71cc30d00123966282021-09-15 20:05:439 days 8 hrs ago 0x58d2b3d193dfdc42fe4e3e6065307365d0157eca 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0x71b9a4c8f3f84e1cb83b75eb5a99b1d4ecc9695b83a36d7680f040a71cc30d00123966282021-09-15 20:05:439 days 8 hrs ago 0x58d2b3d193dfdc42fe4e3e6065307365d0157eca 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0x3762a4f7a3d29fff5feccb36a0d6a6c5aa082e360ae915700269f710c1742e14123851042021-09-15 10:29:319 days 17 hrs ago 0xa3f6f86de2a87caa51546f246fda72ad60493697 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0x3d401c20b102d83f76f2f60be509840363d17adc4fc33338f4f3ea4176434e76123850842021-09-15 10:28:319 days 17 hrs ago 0xa3f6f86de2a87caa51546f246fda72ad60493697 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0xf9377fdac102f59c2b5daf8ab99e6bd6ac50bb873b4b7f37d3a1c3a27355c910123850542021-09-15 10:27:019 days 17 hrs ago 0xa3f6f86de2a87caa51546f246fda72ad60493697 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0x0ca71da54f6cc5f9d8492eeffb4cbb6d2c7b8875e8610e2148145b37f16c7ec3123850352021-09-15 10:26:049 days 17 hrs ago 0xa3f6f86de2a87caa51546f246fda72ad60493697 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0xa45937aa1edb27157167f18aa4bd8267cb46a64b28eb97dc257a0c9ffd27c0b0123849732021-09-15 10:22:589 days 17 hrs ago 0xa3f6f86de2a87caa51546f246fda72ad60493697 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0x64756e47e4c5024c75467928d0d5a4a7f0d2faf94c277f8dbd16941f303c89f2123848672021-09-15 10:17:409 days 17 hrs ago 0xa3f6f86de2a87caa51546f246fda72ad60493697 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0x3b35c6038ac27ef516ec6548d4eac168093fb8ff510d33c0855da2693b37f15c123848342021-09-15 10:16:019 days 17 hrs ago 0xa3f6f86de2a87caa51546f246fda72ad60493697 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0x5b587bbe49a37bb7956488209aa76bad0bf1dc02f8fee0b17cfc82a96f43a017123844742021-09-15 9:58:019 days 18 hrs ago 0xf269d144755f57eacb0adbd4e3150d1416a538cb 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0x7a846cfd34e9534cb4bdb2db79aa2090e73ea665b4d99b5516f51fb12e8b1072123787072021-09-15 5:09:409 days 23 hrs ago 0xa3f6f86de2a87caa51546f246fda72ad60493697 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
0xa5b431d613d96ee299b8232982c69181d20f9b253edc536536a022f52dda3fb0123781612021-09-15 4:42:229 days 23 hrs ago 0xa3f6f86de2a87caa51546f246fda72ad60493697 0x9081f0387ea6474220b5d59c040fe8c46c3f9c1f0 BNB
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
XpoolMintableTokenV1

Compiler Version
v0.7.5+commit.eb77ed08

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 11 : XpoolMintableTokenV1.sol
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.7.5;

import {MintableERC20} from '../open-zeppelin/MintableERC20.sol';
import {ITransferHook} from '../interfaces/ITransferHook.sol';
import {VersionedInitializable} from '../utils/VersionedInitializable.sol';
import {GovernancePowerDelegationMintableERC20} from './base/GovernancePowerDelegationMintableERC20.sol';
import {SafeMath} from '../open-zeppelin/SafeMath.sol';

/**
 * @notice implementation of the Xpool token contract
 * @author Xpool
 */
contract XpoolMintableTokenV1 is GovernancePowerDelegationMintableERC20, VersionedInitializable {
  using SafeMath for uint256;

  string internal constant NAME = 'Xpool';
  string internal constant SYMBOL = 'XPO';
  uint8 internal constant DECIMALS = 18;

  uint256 public constant REVISION = 1;

  address public owner = 0x584257E9299B159eaa462A41eEAf96E8B6501AC3;

  /// @dev owner => next valid nonce to submit with permit()
  mapping(address => uint256) public _nonces;

  mapping(address => mapping(uint256 => Snapshot)) public _votingSnapshots;

  mapping(address => uint256) public _votingSnapshotsCounts;

  /// @dev reference to the Xpool governance contract to call (if initialized) on _beforeTokenTransfer
  /// !!! IMPORTANT The Xppol governance is considered a trustable contract, being its responsibility
  /// to control all potential reentrancies by calling back the XpoolToken
  ITransferHook public _xpoolGovernance;

  bytes32 public DOMAIN_SEPARATOR;
  bytes public constant EIP712_REVISION = bytes('1');
  bytes32 internal constant EIP712_DOMAIN = keccak256(
    'EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'
  );
  bytes32 public constant PERMIT_TYPEHASH = keccak256(
    'Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)'
  );

  uint256 internal constant MINTED_AMOUNT = 13000000 ether;

  mapping(address => address) internal _votingDelegates;

  mapping(address => mapping(uint256 => Snapshot)) internal _propositionPowerSnapshots;
  mapping(address => uint256) internal _propositionPowerSnapshotsCounts;

  mapping(address => address) internal _propositionPowerDelegates;

  constructor() public MintableERC20(NAME, SYMBOL, 18) {}

  /**
   * @dev initializes the contract upon assignment to the InitializableAdminUpgradeabilityProxy
   */
  function initialize(
    ITransferHook xpoolGovernance
  ) external initializer {
    uint256 chainId;

    //solium-disable-next-line
    assembly {
      chainId := chainid()
    }

    DOMAIN_SEPARATOR = keccak256(
      abi.encode(
        EIP712_DOMAIN,
        keccak256(bytes(NAME)),
        keccak256(EIP712_REVISION),
        chainId,
        address(this)
      )
    );
    _name = NAME;
    _symbol = SYMBOL;
    _xpoolGovernance = xpoolGovernance;
    _mint(msg.sender, MINTED_AMOUNT);
  }

  /**
   * @dev implements the permit function as for https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md
   * @param owner the owner of the funds
   * @param spender the spender
   * @param value the amount
   * @param deadline the deadline timestamp, type(uint256).max for no deadline
   * @param v signature param
   * @param s signature param
   * @param r signature param
   */

  function permit(
    address owner,
    address spender,
    uint256 value,
    uint256 deadline,
    uint8 v,
    bytes32 r,
    bytes32 s
  ) external {
    require(owner != address(0), 'INVALID_OWNER');
    //solium-disable-next-line
    require(block.timestamp <= deadline, 'INVALID_EXPIRATION');
    uint256 currentValidNonce = _nonces[owner];
    bytes32 digest = keccak256(
      abi.encodePacked(
        '\x19\x01',
        DOMAIN_SEPARATOR,
        keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, currentValidNonce, deadline))
      )
    );

    require(owner == ecrecover(digest, v, r, s), 'INVALID_SIGNATURE');
    _nonces[owner] = currentValidNonce.add(1);
    _approve(owner, spender, value);
  }

  /// @notice External function called by the Xpool governance to set or replace sources of assets
  /// @param gov The addresses of the gorvernance
  function setNewGorvernance(ITransferHook gov)
    external
  {
    require(address(msg.sender) == owner, 'INVALID_ACTION');
    _xpoolGovernance = gov;
  }

  /**
   * @dev returns the revision of the implementation contract
   */
  function getRevision() internal override pure returns (uint256) {
    return REVISION;
  }

  /**
   * @dev Writes a snapshot before any operation involving transfer of value: _transfer, _mint and _burn
   * - On _transfer, it writes snapshots for both "from" and "to"
   * - On _mint, only for _to
   * - On _burn, only for _from
   * @param from the from address
   * @param to the to address
   * @param amount the amount to transfer
   */
  function _beforeTokenTransfer(
    address from,
    address to,
    uint256 amount
  ) internal override {
    address votingFromDelegatee = _getDelegatee(from, _votingDelegates);
    address votingToDelegatee = _getDelegatee(to, _votingDelegates);

    _moveDelegatesByType(
      votingFromDelegatee,
      votingToDelegatee,
      amount,
      DelegationType.VOTING_POWER
    );

    address propPowerFromDelegatee = _getDelegatee(from, _propositionPowerDelegates);
    address propPowerToDelegatee = _getDelegatee(to, _propositionPowerDelegates);

    _moveDelegatesByType(
      propPowerFromDelegatee,
      propPowerToDelegatee,
      amount,
      DelegationType.PROPOSITION_POWER
    );

    // caching the xpool governance address to avoid multiple state loads
    ITransferHook xpoolGovernance = _xpoolGovernance;
    if (xpoolGovernance != ITransferHook(0)) {
      xpoolGovernance.onTransfer(from, to, amount);
    }
  }

  function _getDelegationDataByType(DelegationType delegationType)
    internal
    override
    view
    returns (
      mapping(address => mapping(uint256 => Snapshot)) storage, //snapshots
      mapping(address => uint256) storage, //snapshots count
      mapping(address => address) storage //delegatees list
    )
  {
    if (delegationType == DelegationType.VOTING_POWER) {
      return (_votingSnapshots, _votingSnapshotsCounts, _votingDelegates);
    } else {
      return (
        _propositionPowerSnapshots,
        _propositionPowerSnapshotsCounts,
        _propositionPowerDelegates
      );
    }
  }

  /**
   * @dev Delegates power from signatory to `delegatee`
   * @param delegatee The address to delegate votes to
   * @param delegationType the type of delegation (VOTING_POWER, PROPOSITION_POWER)
   * @param nonce The contract state required to match the signature
   * @param expiry The time at which to expire the signature
   * @param v The recovery byte of the signature
   * @param r Half of the ECDSA signature pair
   * @param s Half of the ECDSA signature pair
   */
  function delegateByTypeBySig(
    address delegatee,
    DelegationType delegationType,
    uint256 nonce,
    uint256 expiry,
    uint8 v,
    bytes32 r,
    bytes32 s
  ) public {
    bytes32 structHash = keccak256(
      abi.encode(DELEGATE_BY_TYPE_TYPEHASH, delegatee, uint256(delegationType), nonce, expiry)
    );
    bytes32 digest = keccak256(abi.encodePacked('\x19\x01', DOMAIN_SEPARATOR, structHash));
    address signatory = ecrecover(digest, v, r, s);
    require(signatory != address(0), 'INVALID_SIGNATURE');
    require(nonce == _nonces[signatory]++, 'INVALID_NONCE');
    require(block.timestamp <= expiry, 'INVALID_EXPIRATION');
    _delegateByType(signatory, delegatee, delegationType);
  }

  /**
   * @dev Delegates power from signatory to `delegatee`
   * @param delegatee The address to delegate votes to
   * @param nonce The contract state required to match the signature
   * @param expiry The time at which to expire the signature
   * @param v The recovery byte of the signature
   * @param r Half of the ECDSA signature pair
   * @param s Half of the ECDSA signature pair
   */
  function delegateBySig(
    address delegatee,
    uint256 nonce,
    uint256 expiry,
    uint8 v,
    bytes32 r,
    bytes32 s
  ) public {
    bytes32 structHash = keccak256(abi.encode(DELEGATE_TYPEHASH, delegatee, nonce, expiry));
    bytes32 digest = keccak256(abi.encodePacked('\x19\x01', DOMAIN_SEPARATOR, structHash));
    address signatory = ecrecover(digest, v, r, s);
    require(signatory != address(0), 'INVALID_SIGNATURE');
    require(nonce == _nonces[signatory]++, 'INVALID_NONCE');
    require(block.timestamp <= expiry, 'INVALID_EXPIRATION');
    _delegateByType(signatory, delegatee, DelegationType.VOTING_POWER);
    _delegateByType(signatory, delegatee, DelegationType.PROPOSITION_POWER);
  }
}

File 2 of 11 : MintableERC20.sol
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.7.5;

import {ERC20} from './ERC20.sol';

/**
 * @title ERC20Mintable
 * @dev ERC20 minting logic
 */
contract MintableERC20 is ERC20 {
  constructor(
    string memory name,
    string memory symbol,
    uint8 decimals
  ) public ERC20(name, symbol) {
    _setupDecimals(decimals);
  }

  /**
   * @dev Function to mint tokens
   * @param value The amount of tokens to mint.
   * @return A boolean that indicates if the operation was successful.
   */
  function mint(uint256 value) public returns (bool) {
    _mint(_msgSender(), value);
    return true;
  }
}

File 3 of 11 : ITransferHook.sol
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.7.5;

interface ITransferHook {
    function onTransfer(address from, address to, uint256 amount) external;
}

File 4 of 11 : VersionedInitializable.sol
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.7.5;

/**
 * @title VersionedInitializable
 *
 * @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.
 *
 * @author Aave, inspired by the OpenZeppelin Initializable contract
 */
abstract contract VersionedInitializable {
    /**
   * @dev Indicates that the contract has been initialized.
   */
    uint256 internal lastInitializedRevision = 0;

   /**
   * @dev Modifier to use in the initializer function of a contract.
   */
    modifier initializer() {
        uint256 revision = getRevision();
        require(revision > lastInitializedRevision, "Contract instance has already been initialized");

        lastInitializedRevision = revision;

        _;

    }

    /// @dev returns the revision number of the contract.
    /// Needs to be defined in the inherited class as a constant.
    function getRevision() internal pure virtual returns(uint256);


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

File 5 of 11 : GovernancePowerDelegationMintableERC20.sol
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.7.5;

import {SafeMath} from '../../open-zeppelin/SafeMath.sol';
import {MintableERC20} from '../../open-zeppelin/MintableERC20.sol';
import {
  IGovernancePowerDelegationToken
} from '../../interfaces/IGovernancePowerDelegationToken.sol';

/**
 * @notice implementation of the Xpool token contract
 * @author Xpool
 */
abstract contract GovernancePowerDelegationMintableERC20 is MintableERC20, IGovernancePowerDelegationToken {
  using SafeMath for uint256;
  /// @notice The EIP-712 typehash for the delegation struct used by the contract
  bytes32 public constant DELEGATE_BY_TYPE_TYPEHASH = keccak256(
    'DelegateByType(address delegatee,uint256 type,uint256 nonce,uint256 expiry)'
  );

  bytes32 public constant DELEGATE_TYPEHASH = keccak256(
    'Delegate(address delegatee,uint256 nonce,uint256 expiry)'
  );

  /// @dev snapshot of a value on a specific block, used for votes
  struct Snapshot {
    uint128 blockNumber;
    uint128 value;
  }

  /**
   * @dev delegates one specific power to a delegatee
   * @param delegatee the user which delegated power has changed
   * @param delegationType the type of delegation (VOTING_POWER, PROPOSITION_POWER)
   **/
  function delegateByType(address delegatee, DelegationType delegationType) external override {
    _delegateByType(msg.sender, delegatee, delegationType);
  }

  /**
   * @dev delegates all the powers to a specific user
   * @param delegatee the user to which the power will be delegated
   **/
  function delegate(address delegatee) external override {
    _delegateByType(msg.sender, delegatee, DelegationType.VOTING_POWER);
    _delegateByType(msg.sender, delegatee, DelegationType.PROPOSITION_POWER);
  }

  /**
   * @dev returns the delegatee of an user
   * @param delegator the address of the delegator
   **/
  function getDelegateeByType(address delegator, DelegationType delegationType)
    external
    override
    view
    returns (address)
  {
    (, , mapping(address => address) storage delegates) = _getDelegationDataByType(delegationType);

    return _getDelegatee(delegator, delegates);
  }

  /**
   * @dev returns the current delegated power of a user. The current power is the
   * power delegated at the time of the last snapshot
   * @param user the user
   **/
  function getPowerCurrent(address user, DelegationType delegationType)
    external
    override
    view
    returns (uint256)
  {
    (
      mapping(address => mapping(uint256 => Snapshot)) storage snapshots,
      mapping(address => uint256) storage snapshotsCounts,

    ) = _getDelegationDataByType(delegationType);

    return _searchByBlockNumber(snapshots, snapshotsCounts, user, block.number);
  }

  /**
   * @dev returns the delegated power of a user at a certain block
   * @param user the user
   **/
  function getPowerAtBlock(
    address user,
    uint256 blockNumber,
    DelegationType delegationType
  ) external override view returns (uint256) {
    (
      mapping(address => mapping(uint256 => Snapshot)) storage snapshots,
      mapping(address => uint256) storage snapshotsCounts,

    ) = _getDelegationDataByType(delegationType);

    return _searchByBlockNumber(snapshots, snapshotsCounts, user, blockNumber);
  }

  /**
   * @dev returns the total supply at a certain block number
   * used by the voting strategy contracts to calculate the total votes needed for threshold/quorum
   * In this initial implementation with no XPO minting, simply returns the current supply
   * A snapshots mapping will need to be added in case a mint function is added to the XPO token in the future
   **/
  function totalSupplyAt(uint256 blockNumber) external override view returns (uint256) {
    return super.totalSupply();
  }

  /**
   * @dev delegates the specific power to a delegatee
   * @param delegatee the user which delegated power has changed
   * @param delegationType the type of delegation (VOTING_POWER, PROPOSITION_POWER)
   **/
  function _delegateByType(
    address delegator,
    address delegatee,
    DelegationType delegationType
  ) internal {
    require(delegatee != address(0), 'INVALID_DELEGATEE');

    (, , mapping(address => address) storage delegates) = _getDelegationDataByType(delegationType);

    uint256 delegatorBalance = balanceOf(delegator);

    address previousDelegatee = _getDelegatee(delegator, delegates);

    delegates[delegator] = delegatee;

    _moveDelegatesByType(previousDelegatee, delegatee, delegatorBalance, delegationType);
    emit DelegateChanged(delegator, delegatee, delegationType);
  }

  /**
   * @dev moves delegated power from one user to another
   * @param from the user from which delegated power is moved
   * @param to the user that will receive the delegated power
   * @param amount the amount of delegated power to be moved
   * @param delegationType the type of delegation (VOTING_POWER, PROPOSITION_POWER)
   **/
  function _moveDelegatesByType(
    address from,
    address to,
    uint256 amount,
    DelegationType delegationType
  ) internal {
    if (from == to) {
      return;
    }

    (
      mapping(address => mapping(uint256 => Snapshot)) storage snapshots,
      mapping(address => uint256) storage snapshotsCounts,

    ) = _getDelegationDataByType(delegationType);

    if (from != address(0)) {
      uint256 previous = 0;
      uint256 fromSnapshotsCount = snapshotsCounts[from];

      if (fromSnapshotsCount != 0) {
        previous = snapshots[from][fromSnapshotsCount - 1].value;
      } else {
        previous = balanceOf(from);
      }

      _writeSnapshot(
        snapshots,
        snapshotsCounts,
        from,
        uint128(previous),
        uint128(previous.sub(amount))
      );

      emit DelegatedPowerChanged(from, previous.sub(amount), delegationType);
    }
    if (to != address(0)) {
      uint256 previous = 0;
      uint256 toSnapshotsCount = snapshotsCounts[to];
      if (toSnapshotsCount != 0) {
        previous = snapshots[to][toSnapshotsCount - 1].value;
      } else {
        previous = balanceOf(to);
      }

      _writeSnapshot(
        snapshots,
        snapshotsCounts,
        to,
        uint128(previous),
        uint128(previous.add(amount))
      );

      emit DelegatedPowerChanged(to, previous.add(amount), delegationType);
    }
  }

  /**
   * @dev searches a snapshot by block number. Uses binary search.
   * @param snapshots the snapshots mapping
   * @param snapshotsCounts the number of snapshots
   * @param user the user for which the snapshot is being searched
   * @param blockNumber the block number being searched
   **/
  function _searchByBlockNumber(
    mapping(address => mapping(uint256 => Snapshot)) storage snapshots,
    mapping(address => uint256) storage snapshotsCounts,
    address user,
    uint256 blockNumber
  ) internal view returns (uint256) {
    require(blockNumber <= block.number, 'INVALID_BLOCK_NUMBER');

    uint256 snapshotsCount = snapshotsCounts[user];

    if (snapshotsCount == 0) {
      return balanceOf(user);
    }

    // First check most recent balance
    if (snapshots[user][snapshotsCount - 1].blockNumber <= blockNumber) {
      return snapshots[user][snapshotsCount - 1].value;
    }

    // Next check implicit zero balance
    if (snapshots[user][0].blockNumber > blockNumber) {
      return 0;
    }

    uint256 lower = 0;
    uint256 upper = snapshotsCount - 1;
    while (upper > lower) {
      uint256 center = upper - (upper - lower) / 2; // ceil, avoiding overflow
      Snapshot memory snapshot = snapshots[user][center];
      if (snapshot.blockNumber == blockNumber) {
        return snapshot.value;
      } else if (snapshot.blockNumber < blockNumber) {
        lower = center;
      } else {
        upper = center - 1;
      }
    }
    return snapshots[user][lower].value;
  }

  /**
   * @dev returns the delegation data (snapshot, snapshotsCount, list of delegates) by delegation type
   * NOTE: Ideal implementation would have mapped this in a struct by delegation type. Unfortunately,
   * the XPO token and StakeToken already include a mapping for the snapshots, so we require contracts
   * who inherit from this to provide access to the delegation data by overriding this method.
   * @param delegationType the type of delegation
   **/
  function _getDelegationDataByType(DelegationType delegationType)
    internal
    virtual
    view
    returns (
      mapping(address => mapping(uint256 => Snapshot)) storage, //snapshots
      mapping(address => uint256) storage, //snapshots count
      mapping(address => address) storage //delegatees list
    );

  /**
   * @dev Writes a snapshot for an owner of tokens
   * @param owner The owner of the tokens
   * @param oldValue The value before the operation that is gonna be executed after the snapshot
   * @param newValue The value after the operation
   */
  function _writeSnapshot(
    mapping(address => mapping(uint256 => Snapshot)) storage snapshots,
    mapping(address => uint256) storage snapshotsCounts,
    address owner,
    uint128 oldValue,
    uint128 newValue
  ) internal {
    uint128 currentBlock = uint128(block.number);

    uint256 ownerSnapshotsCount = snapshotsCounts[owner];
    mapping(uint256 => Snapshot) storage snapshotsOwner = snapshots[owner];

    // Doing multiple operations in the same block
    if (
      ownerSnapshotsCount != 0 &&
      snapshotsOwner[ownerSnapshotsCount - 1].blockNumber == currentBlock
    ) {
      snapshotsOwner[ownerSnapshotsCount - 1].value = newValue;
    } else {
      snapshotsOwner[ownerSnapshotsCount] = Snapshot(currentBlock, newValue);
      snapshotsCounts[owner] = ownerSnapshotsCount + 1;
    }
  }

  /**
   * @dev returns the user delegatee. If a user never performed any delegation,
   * his delegated address will be 0x0. In that case we simply return the user itself
   * @param delegator the address of the user for which return the delegatee
   * @param delegates the array of delegates for a particular type of delegation
   **/
  function _getDelegatee(address delegator, mapping(address => address) storage delegates)
    internal
    view
    returns (address)
  {
    address previousDelegatee = delegates[delegator];

    if (previousDelegatee == address(0)) {
      return delegator;
    }

    return previousDelegatee;
  }
}

File 6 of 11 : SafeMath.sol
pragma solidity ^0.7.5;

/**
 * @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.
     */
    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.
     */
    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.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

File 7 of 11 : ERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.7.5;

import "./Context.sol";
import "../interfaces/IERC20.sol";
import "./SafeMath.sol";
import "./Address.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20 {
    using SafeMath for uint256;
    using Address for address;

    mapping (address => uint256) private _balances;

    mapping (address => mapping (address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string internal _name;
    string internal _symbol;
    uint8 private _decimals;

    /**
     * @dev Sets the values for {name} and {symbol}, initializes {decimals} with
     * a default value of 18.
     *
     * To select a different value for {decimals}, use {_setupDecimals}.
     *
     * All three of these values are immutable: they can only be set once during
     * construction.
     */
    constructor (string memory name, string memory symbol) public {
        _name = name;
        _symbol = symbol;
        _decimals = 18;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is
     * called.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view returns (uint8) {
        return _decimals;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20};
     *
     * Requirements:
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.
     *
     * This is internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Sets {decimals} to a value other than the default one of 18.
     *
     * WARNING: This function should only be called from the constructor. Most
     * applications that interact with token contracts will not expect
     * {decimals} to ever change, and may work incorrectly if it does.
     */
    function _setupDecimals(uint8 decimals_) internal {
        _decimals = decimals_;
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be to transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}

File 8 of 11 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.7.5;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address payable) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

File 9 of 11 : IERC20.sol
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.7.5;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 10 of 11 : Address.sol
pragma solidity ^0.7.5;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
        // for accounts without code, i.e. `keccak256('')`
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        // solhint-disable-next-line no-inline-assembly
        assembly { codehash := extcodehash(account) }
        return (codehash != accountHash && codehash != 0x0);
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }
}

File 11 of 11 : IGovernancePowerDelegationToken.sol
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.7.5;

interface IGovernancePowerDelegationToken {
  
  enum DelegationType {VOTING_POWER, PROPOSITION_POWER}

  /**
   * @dev emitted when a user delegates to another
   * @param delegator the delegator
   * @param delegatee the delegatee
   * @param delegationType the type of delegation (VOTING_POWER, PROPOSITION_POWER)
   **/
  event DelegateChanged(
    address indexed delegator,
    address indexed delegatee,
    DelegationType delegationType
  );

  /**
   * @dev emitted when an action changes the delegated power of a user
   * @param user the user which delegated power has changed
   * @param amount the amount of delegated power for the user
   * @param delegationType the type of delegation (VOTING_POWER, PROPOSITION_POWER)
   **/
  event DelegatedPowerChanged(address indexed user, uint256 amount, DelegationType delegationType);

  /**
   * @dev delegates the specific power to a delegatee
   * @param delegatee the user which delegated power has changed
   * @param delegationType the type of delegation (VOTING_POWER, PROPOSITION_POWER)
   **/
  function delegateByType(address delegatee, DelegationType delegationType) external virtual;
  /**
   * @dev delegates all the powers to a specific user
   * @param delegatee the user to which the power will be delegated
   **/
  function delegate(address delegatee) external virtual;
  /**
   * @dev returns the delegatee of an user
   * @param delegator the address of the delegator
   **/
  function getDelegateeByType(address delegator, DelegationType delegationType)
    external
    virtual
    view
    returns (address);

  /**
   * @dev returns the current delegated power of a user. The current power is the
   * power delegated at the time of the last snapshot
   * @param user the user
   **/
  function getPowerCurrent(address user, DelegationType delegationType)
    external
    virtual
    view
    returns (uint256);

  /**
   * @dev returns the delegated power of a user at a certain block
   * @param user the user
   **/
  function getPowerAtBlock(
    address user,
    uint256 blockNumber,
    DelegationType delegationType
  ) external virtual view returns (uint256);
 
  /**
  * @dev returns the total supply at a certain block number
  **/
  function totalSupplyAt(uint256 blockNumber) external virtual view returns (uint256);
}

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

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":true,"internalType":"address","name":"delegatee","type":"address"},{"indexed":false,"internalType":"enum IGovernancePowerDelegationToken.DelegationType","name":"delegationType","type":"uint8"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"enum IGovernancePowerDelegationToken.DelegationType","name":"delegationType","type":"uint8"}],"name":"DelegatedPowerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DELEGATE_BY_TYPE_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DELEGATE_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EIP712_REVISION","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REVISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"_votingSnapshots","outputs":[{"internalType":"uint128","name":"blockNumber","type":"uint128"},{"internalType":"uint128","name":"value","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_votingSnapshotsCounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_xpoolGovernance","outputs":[{"internalType":"contract ITransferHook","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegateBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"enum IGovernancePowerDelegationToken.DelegationType","name":"delegationType","type":"uint8"}],"name":"delegateByType","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"enum IGovernancePowerDelegationToken.DelegationType","name":"delegationType","type":"uint8"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegateByTypeBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegator","type":"address"},{"internalType":"enum IGovernancePowerDelegationToken.DelegationType","name":"delegationType","type":"uint8"}],"name":"getDelegateeByType","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"enum IGovernancePowerDelegationToken.DelegationType","name":"delegationType","type":"uint8"}],"name":"getPowerAtBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"enum IGovernancePowerDelegationToken.DelegationType","name":"delegationType","type":"uint8"}],"name":"getPowerCurrent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ITransferHook","name":"xpoolGovernance","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ITransferHook","name":"gov","type":"address"}],"name":"setNewGorvernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"totalSupplyAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]

60806040526000600655603980546001600160a01b03191673584257e9299b159eaa462a41eeaf96e8b6501ac31790553480156200003c57600080fd5b5060405180604001604052806005815260200164161c1bdbdb60da1b8152506040518060400160405280600381526020016258504f60e81b81525060128282816003908051906020019062000093929190620000e3565b508051620000a9906004906020840190620000e3565b50506005805460ff1916601217905550620000c481620000cd565b5050506200018f565b6005805460ff191660ff92909216919091179055565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200011b576000855562000166565b82601f106200013657805160ff191683800117855562000166565b8280016001018555821562000166579182015b828111156200016657825182559160200191906001019062000149565b506200017492915062000178565b5090565b5b8082111562000174576000815560010162000179565b6122ce806200019f6000396000f3fe608060405234801561001057600080fd5b50600436106102065760003560e01c80638da5cb5b1161011a578063b9844d8d116100ad578063d505accf1161007c578063d505accf1461066b578063dc937e1c146106bc578063dd62ed3e146106eb578063dde43cba14610719578063f713d8a81461072157610206565b8063b9844d8d146105a3578063c2ffbb91146105c9578063c3cda520146105fe578063c4d66de81461064557610206565b8063a457c2d7116100e9578063a457c2d714610514578063a9059cbb14610540578063aa9fbe021461056c578063b2f4201d1461057457610206565b80638da5cb5b146104ca57806395d89b41146104d2578063981b24d0146104da578063a0712d68146104f757610206565b806341cbf54a1161019d5780636f50458d1161016c5780636f50458d1461042157806370a082311461045057806378160376146104765780637bb73c971461047e57806388f5c276146104a457610206565b806341cbf54a146103725780635b3cc0cf1461037a5780635c19a95c146103d55780635c7774cd146103fd57610206565b806330adf81f116101d957806330adf81f14610318578063313ce567146103205780633644e5151461033e578063395093511461034657610206565b806306fdde031461020b578063095ea7b31461028857806318160ddd146102c857806323b872dd146102e2575b600080fd5b610213610772565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561024d578181015183820152602001610235565b50505050905090810190601f16801561027a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102b46004803603604081101561029e57600080fd5b506001600160a01b038135169060200135610808565b604080519115158252519081900360200190f35b6102d0610826565b60408051918252519081900360200190f35b6102b4600480360360608110156102f857600080fd5b506001600160a01b0381358116916020810135909116906040013561082c565b6102d06108b3565b6103286108d7565b6040805160ff9092168252519081900360200190f35b6102d06108e0565b6102b46004803603604081101561035c57600080fd5b506001600160a01b0381351690602001356108e6565b6102d0610934565b6103a66004803603604081101561039057600080fd5b506001600160a01b038135169060200135610958565b60405180836001600160801b03168152602001826001600160801b031681526020019250505060405180910390f35b6103fb600480360360208110156103eb57600080fd5b50356001600160a01b0316610989565b005b6104056109a4565b604080516001600160a01b039092168252519081900360200190f35b6104056004803603604081101561043757600080fd5b5080356001600160a01b0316906020013560ff166109b3565b6102d06004803603602081101561046657600080fd5b50356001600160a01b03166109d5565b6102136109f0565b6102d06004803603602081101561049457600080fd5b50356001600160a01b0316610a0d565b6103fb600480360360208110156104ba57600080fd5b50356001600160a01b0316610a1f565b610405610a91565b610213610aa0565b6102d0600480360360208110156104f057600080fd5b5035610b01565b6102b46004803603602081101561050d57600080fd5b5035610b0b565b6102b46004803603604081101561052a57600080fd5b506001600160a01b038135169060200135610b26565b6102b46004803603604081101561055657600080fd5b506001600160a01b038135169060200135610b8e565b6102d0610ba2565b6102d06004803603604081101561058a57600080fd5b5080356001600160a01b0316906020013560ff16610bc6565b6102d0600480360360208110156105b957600080fd5b50356001600160a01b0316610bee565b6102d0600480360360608110156105df57600080fd5b5080356001600160a01b0316906020810135906040013560ff16610c00565b6103fb600480360360c081101561061457600080fd5b506001600160a01b038135169060208101359060408101359060ff6060820135169060808101359060a00135610c29565b6103fb6004803603602081101561065b57600080fd5b50356001600160a01b0316610e4b565b6103fb600480360360e081101561068157600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c00135610fef565b6103fb600480360360408110156106d257600080fd5b5080356001600160a01b0316906020013560ff1661122b565b6102d06004803603604081101561070157600080fd5b506001600160a01b038135811691602001351661123a565b6102d0611265565b6103fb600480360360e081101561073757600080fd5b506001600160a01b038135169060ff602082013581169160408101359160608201359160808101359091169060a08101359060c0013561126a565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156107fe5780601f106107d3576101008083540402835291602001916107fe565b820191906000526020600020905b8154815290600101906020018083116107e157829003601f168201915b5050505050905090565b600061081c61081561149d565b84846114a1565b5060015b92915050565b60025490565b600061083984848461158d565b6108a98461084561149d565b6108a4856040518060600160405280602881526020016121d5602891396001600160a01b038a1660009081526001602052604081209061088361149d565b6001600160a01b0316815260208101919091526040016000205491906116e8565b6114a1565b5060019392505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60055460ff1690565b603e5481565b600061081c6108f361149d565b846108a4856001600061090461149d565b6001600160a01b03908116825260208083019390935260409182016000908120918c16815292529020549061177f565b7f9a9a49b990ba9bb39f8048c490a40ab25c18f55d208d5fbcf958261a9b48716d81565b603b6020908152600092835260408084209091529082529020546001600160801b0380821691600160801b90041682565b610995338260006117e0565b6109a1338260016117e0565b50565b603d546001600160a01b031681565b6000806109bf836118f1565b925050506109cd848261192b565b949350505050565b6001600160a01b031660009081526020819052604090205490565b604051806040016040528060018152602001603160f81b81525081565b603c6020526000908152604090205481565b6039546001600160a01b03163314610a6f576040805162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa0a1aa24a7a760911b604482015290519081900360640190fd5b603d80546001600160a01b0319166001600160a01b0392909216919091179055565b6039546001600160a01b031681565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156107fe5780601f106107d3576101008083540402835291602001916107fe565b6000610820610826565b6000610b1e610b1861149d565b83611956565b506001919050565b600061081c610b3361149d565b846108a4856040518060600160405280602581526020016122746025913960016000610b5d61149d565b6001600160a01b03908116825260208083019390935260409182016000908120918d168152925290205491906116e8565b600061081c610b9b61149d565b848461158d565b7f10d8d059343739efce7dad10d09f0806da52b252b3e6a7951920d2d6ec4102e581565b6000806000610bd4846118f1565b5091509150610be582828743611a46565b95945050505050565b603a6020526000908152604090205481565b6000806000610c0e846118f1565b5091509150610c1f82828888611a46565b9695505050505050565b604080517f9a9a49b990ba9bb39f8048c490a40ab25c18f55d208d5fbcf958261a9b48716d6020808301919091526001600160a01b038916828401526060820188905260808083018890528351808403909101815260a083018452805190820120603e5461190160f01b60c085015260c284015260e2808401829052845180850390910181526101028401808652815191840191909120600091829052610122850180875281905260ff891661014286015261016285018890526101828501879052945191949390926001926101a280840193601f198301929081900390910190855afa158015610d1e573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610d7a576040805162461bcd60e51b8152602060048201526011602482015270494e56414c49445f5349474e415455524560781b604482015290519081900360640190fd5b6001600160a01b0381166000908152603a602052604090208054600181019091558814610dde576040805162461bcd60e51b815260206004820152600d60248201526c494e56414c49445f4e4f4e434560981b604482015290519081900360640190fd5b86421115610e28576040805162461bcd60e51b815260206004820152601260248201527124a72b20a624a22fa2ac2824a920aa24a7a760711b604482015290519081900360640190fd5b610e34818a60006117e0565b610e40818a60016117e0565b505050505050505050565b6000610e55611c61565b90506006548111610e975760405162461bcd60e51b815260040180806020018281038252602e8152602001806121fd602e913960400191505060405180910390fd5b6006819055604080518082018252600580825264161c1bdbdb60da1b60209283018190528351808501855260018152603160f81b9084015283517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818501527f43b86342ba7637b5c04c0b9e26bbb89decc5f5bdd730c2e0332f0720a9b77c0c818601527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6606082015246608082018190523060a0808401919091528651808403909101815260c0830180885281519190960120603e5561010082019095529282905260e0909201918252610f8e916003916120b1565b506040805180820190915260038082526258504f60e81b6020909201918252610fb9916004916120b1565b50603d80546001600160a01b0319166001600160a01b038516179055610fea336a0ac0db698068112d000000611956565b505050565b6001600160a01b03871661103a576040805162461bcd60e51b815260206004820152600d60248201526c24a72b20a624a22fa7aba722a960991b604482015290519081900360640190fd5b83421115611084576040805162461bcd60e51b815260206004820152601260248201527124a72b20a624a22fa2ac2824a920aa24a7a760711b604482015290519081900360640190fd5b6001600160a01b038088166000818152603a6020908152604080832054603e5482517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98186015280840196909652958c166060860152608085018b905260a0850181905260c08086018b90528251808703909101815260e08601835280519084012061190160f01b6101008701526101028601969096526101228086019690965281518086039096018652610142850180835286519684019690962093909552610162840180825283905260ff88166101828501526101a284018790526101c284018690525191926001926101e28083019392601f198301929081900390910190855afa158015611199573d6000803e3d6000fd5b505050602060405103516001600160a01b0316896001600160a01b0316146111fc576040805162461bcd60e51b8152602060048201526011602482015270494e56414c49445f5349474e415455524560781b604482015290519081900360640190fd5b61120782600161177f565b6001600160a01b038a166000908152603a6020526040902055610e408989896114a1565b6112363383836117e0565b5050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b600181565b60007f10d8d059343739efce7dad10d09f0806da52b252b3e6a7951920d2d6ec4102e58888600181111561129a57fe5b604080516020808201959095526001600160a01b039093168382015260608301919091526080820189905260a08083018990528151808403909101815260c083018252805190840120603e5461190160f01b60e085015260e2840152610102808401829052825180850390910181526101228401808452815191860191909120600091829052610142850180855281905260ff8a1661016286015261018285018990526101a285018890529251919550919391926001926101c2808301939192601f198301929081900390910190855afa15801561137c573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166113d8576040805162461bcd60e51b8152602060048201526011602482015270494e56414c49445f5349474e415455524560781b604482015290519081900360640190fd5b6001600160a01b0381166000908152603a60205260409020805460018101909155881461143c576040805162461bcd60e51b815260206004820152600d60248201526c494e56414c49445f4e4f4e434560981b604482015290519081900360640190fd5b86421115611486576040805162461bcd60e51b815260206004820152601260248201527124a72b20a624a22fa2ac2824a920aa24a7a760711b604482015290519081900360640190fd5b611491818b8b6117e0565b50505050505050505050565b3390565b6001600160a01b0383166114e65760405162461bcd60e51b81526004018080602001828103825260248152602001806122506024913960400191505060405180910390fd5b6001600160a01b03821661152b5760405162461bcd60e51b815260040180806020018281038252602281526020018061218d6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0383166115d25760405162461bcd60e51b815260040180806020018281038252602581526020018061222b6025913960400191505060405180910390fd5b6001600160a01b0382166116175760405162461bcd60e51b815260040180806020018281038252602381526020018061216a6023913960400191505060405180910390fd5b611622838383611c66565b61165f816040518060600160405280602681526020016121af602691396001600160a01b03861660009081526020819052604090205491906116e8565b6001600160a01b03808516600090815260208190526040808220939093559084168152205461168e908261177f565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600081848411156117775760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561173c578181015183820152602001611724565b50505050905090810190601f1680156117695780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000828201838110156117d9576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b03821661182f576040805162461bcd60e51b8152602060048201526011602482015270494e56414c49445f44454c45474154454560781b604482015290519081900360640190fd5b600061183a826118f1565b925050506000611849856109d5565b90506000611857868461192b565b6001600160a01b03878116600090815260208690526040902080546001600160a01b031916918816919091179055905061189381868487611d59565b846001600160a01b0316866001600160a01b03167fe8d51c8e11bd570db1734c8ec775785330e77007feed45c43b608ef33ff914bd86604051808260018111156118d957fe5b815260200191505060405180910390a3505050505050565b600080808084600181111561190257fe5b14156119185750603b9150603c9050603f611924565b50604091506041905060425b9193909250565b6001600160a01b03808316600090815260208390526040812054909116806117d95783915050610820565b6001600160a01b0382166119b1576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b6119bd60008383611c66565b6002546119ca908261177f565b6002556001600160a01b0382166000908152602081905260409020546119f0908261177f565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600043821115611a94576040805162461bcd60e51b815260206004820152601460248201527324a72b20a624a22fa12627a1a5afa72aa6a122a960611b604482015290519081900360640190fd5b6001600160a01b03831660009081526020859052604090205480611ac357611abb846109d5565b9150506109cd565b6001600160a01b038416600090815260208781526040808320600019850184529091529020546001600160801b03168310611b36576001600160a01b038416600090815260208781526040808320600019909401835292905220546001600160801b03600160801b9091041690506109cd565b6001600160a01b0384166000908152602087815260408083208380529091529020546001600160801b0316831015611b725760009150506109cd565b600060001982015b81811115611c24576002828203048103611b9261213d565b506001600160a01b038716600090815260208a815260408083208484528252918290208251808401909352546001600160801b03808216808552600160801b9092041691830191909152871415611bfc57602001516001600160801b031694506109cd9350505050565b80516001600160801b0316871115611c1657819350611c1d565b6001820392505b5050611b7a565b506001600160a01b0385166000908152602088815260408083209383529290522054600160801b90046001600160801b0316915050949350505050565b600190565b6000611c7384603f61192b565b90506000611c8284603f61192b565b9050611c918282856000611d59565b6000611c9e86604261192b565b90506000611cad86604261192b565b9050611cbc8282876001611d59565b603d546001600160a01b03168015611d4f57806001600160a01b0316634a3931498989896040518463ffffffff1660e01b815260040180846001600160a01b03168152602001836001600160a01b031681526020018281526020019350505050600060405180830381600087803b158015611d3657600080fd5b505af1158015611d4a573d6000803e3d6000fd5b505050505b5050505050505050565b826001600160a01b0316846001600160a01b03161415611d7857611f62565b600080611d84836118f1565b5090925090506001600160a01b03861615611e77576001600160a01b0386166000908152602082905260408120548015611df5576001600160a01b03881660009081526020858152604080832060001985018452909152902054600160801b90046001600160801b03169150611e01565b611dfe886109d5565b91505b611e1784848a85611e12818c611f68565b611faa565b6001600160a01b0388167fa0a19463ee116110c9b282012d9b65cc5522dc38a9520340cbaf3142e550127f611e4c8489611f68565b8760405180838152602001826001811115611e6357fe5b81526020019250505060405180910390a250505b6001600160a01b03851615611f5f576001600160a01b0385166000908152602082905260408120548015611ee2576001600160a01b03871660009081526020858152604080832060001985018452909152902054600160801b90046001600160801b03169150611eee565b611eeb876109d5565b91505b611eff84848985611e12818c61177f565b6001600160a01b0387167fa0a19463ee116110c9b282012d9b65cc5522dc38a9520340cbaf3142e550127f611f34848961177f565b8760405180838152602001826001811115611f4b57fe5b81526020019250505060405180910390a250505b50505b50505050565b60006117d983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506116e8565b6001600160a01b03831660009081526020858152604080832054918890529091204391908115801590611ffb575060001982016000908152602082905260409020546001600160801b038481169116145b15612030576000198201600090815260208290526040902080546001600160801b03808716600160801b029116179055611d4f565b6040805180820182526001600160801b038086168252868116602080840191825260008781528682528581209451855493518516600160801b029085166fffffffffffffffffffffffffffffffff1990941693909317909316919091179092556001600160a01b038916815290899052206001830190555050505050505050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826120e7576000855561212d565b82601f1061210057805160ff191683800117855561212d565b8280016001018555821561212d579182015b8281111561212d578251825591602001919060010190612112565b50612139929150612154565b5090565b604080518082019091526000808252602082015290565b5b80821115612139576000815560010161215556fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a656445524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa26469706673582212208e341c9493012f3d03a30aee03119baa001a0fcb4170c4ed5007bffbf61dde9664736f6c63430007050033

Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading