false
true
0

Contract Address Details

0xEC568fffba86c094cf06b22134B23074DFE2252c

Contract Name
AaveGovernanceV2
Creator
0x46bcf3–aba1f2 at 0x645324–1698a0
Balance
0.01 PLS ( )
Tokens
Fetching tokens...
Transactions
20,313 Transactions
Transfers
0 Transfers
Gas Used
0
Last Balance Update
26046014
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
AaveGovernanceV2




Optimization enabled
true
Compiler version
v0.7.5+commit.eb77ed08




Optimization runs
200
EVM Version
istanbul




Verified at
2025-07-15T06:16:07.109682Z

Constructor Arguments

0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ca76ebd8617a03126b6fb84f9b1c1a0fb71c263300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000

Arg [0] (address) : 0x0000000000000000000000000000000000000000
Arg [1] (uint256) : 0
Arg [2] (address) : 0xca76ebd8617a03126b6fb84f9b1c1a0fb71c2633
Arg [3] (address[]) : []

              

Contract source code

/**
 *Submitted for verification at Etherscan.io on 2020-12-10
*/

// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.7.5;
pragma abicoder v2;

function getChainId() pure returns (uint256) {
  uint256 chainId;
  assembly {
    chainId := chainid()
  }
  return chainId;
}

function isContract(address account) 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 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;
  }
}

/**
 * @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.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
contract Ownable is Context {
  address private _owner;

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

  /**
   * @dev Initializes the contract setting the deployer as the initial owner.
   */
  constructor() {
    address msgSender = _msgSender();
    _owner = msgSender;
    emit OwnershipTransferred(address(0), msgSender);
  }

  /**
   * @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(_owner == _msgSender(), 'Ownable: caller is not the 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 virtual 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 virtual onlyOwner {
    require(newOwner != address(0), 'Ownable: new owner is the zero address');
    emit OwnershipTransferred(_owner, newOwner);
    _owner = newOwner;
  }
}

/**
 * @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;
  }
}

interface IVotingStrategy {
  function getVotingPowerAt(address user, uint256 blockNumber) external view returns (uint256);
}

interface IProposalValidator {
  /**
   * @dev Called to validate a proposal (e.g when creating new proposal in Governance)
   * @param governance Governance Contract
   * @param user Address of the proposal creator
   * @param blockNumber Block Number against which to make the test (e.g proposal creation block -1).
   * @return boolean, true if can be created
   **/
  function validateCreatorOfProposal(
    IAaveGovernanceV2 governance,
    address user,
    uint256 blockNumber
  ) external view returns (bool);

  /**
   * @dev Called to validate the cancellation of a proposal
   * @param governance Governance Contract
   * @param user Address of the proposal creator
   * @param blockNumber Block Number against which to make the test (e.g proposal creation block -1).
   * @return boolean, true if can be cancelled
   **/
  function validateProposalCancellation(
    IAaveGovernanceV2 governance,
    address user,
    uint256 blockNumber
  ) external view returns (bool);

  /**
   * @dev Returns whether a user has enough Proposition Power to make a proposal.
   * @param governance Governance Contract
   * @param user Address of the user to be challenged.
   * @param blockNumber Block Number against which to make the challenge.
   * @return true if user has enough power
   **/
  function isPropositionPowerEnough(
    IAaveGovernanceV2 governance,
    address user,
    uint256 blockNumber
  ) external view returns (bool);

  /**
   * @dev Returns the minimum Proposition Power needed to create a proposition.
   * @param governance Governance Contract
   * @param blockNumber Blocknumber at which to evaluate
   * @return minimum Proposition Power needed
   **/
  function getMinimumPropositionPowerNeeded(IAaveGovernanceV2 governance, uint256 blockNumber)
    external
    view
    returns (uint256);

  /**
   * @dev Returns whether a proposal passed or not
   * @param governance Governance Contract
   * @param proposalId Id of the proposal to set
   * @return true if proposal passed
   **/
  function isProposalPassed(IAaveGovernanceV2 governance, uint256 proposalId)
    external
    view
    returns (bool);

  /**
   * @dev Check whether a proposal has reached quorum, ie has enough FOR-voting-power
   * Here quorum is not to understand as number of votes reached, but number of for-votes reached
   * @param governance Governance Contract
   * @param proposalId Id of the proposal to verify
   * @return voting power needed for a proposal to pass
   **/
  function isQuorumValid(IAaveGovernanceV2 governance, uint256 proposalId)
    external
    view
    returns (bool);

  /**
   * @dev Check whether a proposal has enough extra FOR-votes than AGAINST-votes
   * FOR VOTES - AGAINST VOTES > VOTE_DIFFERENTIAL * voting supply
   * @param governance Governance Contract
   * @param proposalId Id of the proposal to verify
   * @return true if enough For-Votes
   **/
  function isVoteDifferentialValid(IAaveGovernanceV2 governance, uint256 proposalId)
    external
    view
    returns (bool);

  /**
   * @dev Calculates the minimum amount of Voting Power needed for a proposal to Pass
   * @param votingSupply Total number of oustanding voting tokens
   * @return voting power needed for a proposal to pass
   **/
  function getMinimumVotingPowerNeeded(uint256 votingSupply) external view returns (uint256);

  /**
   * @dev Get proposition threshold constant value
   * @return the proposition threshold value (100 <=> 1%)
   **/
  function PROPOSITION_THRESHOLD() external view returns (uint256);

  /**
   * @dev Get voting duration constant value
   * @return the voting duration value in seconds
   **/
  function VOTING_DURATION() external view returns (uint256);

  /**
   * @dev Get the vote differential threshold constant value
   * to compare with % of for votes/total supply - % of against votes/total supply
   * @return the vote differential threshold value (100 <=> 1%)
   **/
  function VOTE_DIFFERENTIAL() external view returns (uint256);

  /**
   * @dev Get quorum threshold constant value
   * to compare with % of for votes/total supply
   * @return the quorum threshold value (100 <=> 1%)
   **/
  function MINIMUM_QUORUM() external view returns (uint256);

  /**
   * @dev precision helper: 100% = 10000
   * @return one hundred percents with our chosen precision
   **/
  function ONE_HUNDRED_WITH_PRECISION() external view returns (uint256);
}

interface IGovernanceStrategy {
  /**
   * @dev Returns the Proposition Power of a user at a specific block number.
   * @param user Address of the user.
   * @param blockNumber Blocknumber at which to fetch Proposition Power
   * @return Power number
   **/
  function getPropositionPowerAt(address user, uint256 blockNumber) external view returns (uint256);

  /**
   * @dev Returns the total supply of Outstanding Proposition Tokens
   * @param blockNumber Blocknumber at which to evaluate
   * @return total supply at blockNumber
   **/
  function getTotalPropositionSupplyAt(uint256 blockNumber) external view returns (uint256);

  /**
   * @dev Returns the total supply of Outstanding Voting Tokens
   * @param blockNumber Blocknumber at which to evaluate
   * @return total supply at blockNumber
   **/
  function getTotalVotingSupplyAt(uint256 blockNumber) external view returns (uint256);

  /**
   * @dev Returns the Vote Power of a user at a specific block number.
   * @param user Address of the user.
   * @param blockNumber Blocknumber at which to fetch Vote Power
   * @return Vote number
   **/
  function getVotingPowerAt(address user, uint256 blockNumber) external view returns (uint256);
}

interface IExecutorWithTimelock {
  /**
   * @dev emitted when a new pending admin is set
   * @param newPendingAdmin address of the new pending admin
   **/
  event NewPendingAdmin(address newPendingAdmin);

  /**
   * @dev emitted when a new admin is set
   * @param newAdmin address of the new admin
   **/
  event NewAdmin(address newAdmin);

  /**
   * @dev emitted when a new delay (between queueing and execution) is set
   * @param delay new delay
   **/
  event NewDelay(uint256 delay);

  /**
   * @dev emitted when a new (trans)action is Queued.
   * @param actionHash hash of the action
   * @param target address of the targeted contract
   * @param value wei value of the transaction
   * @param signature function signature of the transaction
   * @param data function arguments of the transaction or callData if signature empty
   * @param executionTime time at which to execute the transaction
   * @param withDelegatecall boolean, true = transaction delegatecalls the target, else calls the target
   **/
  event QueuedAction(
    bytes32 actionHash,
    address indexed target,
    uint256 value,
    string signature,
    bytes data,
    uint256 executionTime,
    bool withDelegatecall
  );

  /**
   * @dev emitted when an action is Cancelled
   * @param actionHash hash of the action
   * @param target address of the targeted contract
   * @param value wei value of the transaction
   * @param signature function signature of the transaction
   * @param data function arguments of the transaction or callData if signature empty
   * @param executionTime time at which to execute the transaction
   * @param withDelegatecall boolean, true = transaction delegatecalls the target, else calls the target
   **/
  event CancelledAction(
    bytes32 actionHash,
    address indexed target,
    uint256 value,
    string signature,
    bytes data,
    uint256 executionTime,
    bool withDelegatecall
  );

  /**
   * @dev emitted when an action is Cancelled
   * @param actionHash hash of the action
   * @param target address of the targeted contract
   * @param value wei value of the transaction
   * @param signature function signature of the transaction
   * @param data function arguments of the transaction or callData if signature empty
   * @param executionTime time at which to execute the transaction
   * @param withDelegatecall boolean, true = transaction delegatecalls the target, else calls the target
   * @param resultData the actual callData used on the target
   **/
  event ExecutedAction(
    bytes32 actionHash,
    address indexed target,
    uint256 value,
    string signature,
    bytes data,
    uint256 executionTime,
    bool withDelegatecall,
    bytes resultData
  );

  /**
   * @dev Getter of the current admin address (should be governance)
   * @return The address of the current admin
   **/
  function getAdmin() external view returns (address);

  /**
   * @dev Getter of the current pending admin address
   * @return The address of the pending admin
   **/
  function getPendingAdmin() external view returns (address);

  /**
   * @dev Getter of the delay between queuing and execution
   * @return The delay in seconds
   **/
  function getDelay() external view returns (uint256);

  /**
   * @dev Returns whether an action (via actionHash) is queued
   * @param actionHash hash of the action to be checked
   * keccak256(abi.encode(target, value, signature, data, executionTime, withDelegatecall))
   * @return true if underlying action of actionHash is queued
   **/
  function isActionQueued(bytes32 actionHash) external view returns (bool);

  /**
   * @dev Checks whether a proposal is over its grace period
   * @param governance Governance contract
   * @param proposalId Id of the proposal against which to test
   * @return true of proposal is over grace period
   **/
  function isProposalOverGracePeriod(IAaveGovernanceV2 governance, uint256 proposalId)
    external
    view
    returns (bool);

  /**
   * @dev Getter of grace period constant
   * @return grace period in seconds
   **/
  function GRACE_PERIOD() external view returns (uint256);

  /**
   * @dev Getter of minimum delay constant
   * @return minimum delay in seconds
   **/
  function MINIMUM_DELAY() external view returns (uint256);

  /**
   * @dev Getter of maximum delay constant
   * @return maximum delay in seconds
   **/
  function MAXIMUM_DELAY() external view returns (uint256);

  /**
   * @dev Function, called by Governance, that queue a transaction, returns action hash
   * @param target smart contract target
   * @param value wei value of the transaction
   * @param signature function signature of the transaction
   * @param data function arguments of the transaction or callData if signature empty
   * @param executionTime time at which to execute the transaction
   * @param withDelegatecall boolean, true = transaction delegatecalls the target, else calls the target
   **/
  function queueTransaction(
    address target,
    uint256 value,
    string memory signature,
    bytes memory data,
    uint256 executionTime,
    bool withDelegatecall
  ) external returns (bytes32);

  /**
   * @dev Function, called by Governance, that cancels a transaction, returns the callData executed
   * @param target smart contract target
   * @param value wei value of the transaction
   * @param signature function signature of the transaction
   * @param data function arguments of the transaction or callData if signature empty
   * @param executionTime time at which to execute the transaction
   * @param withDelegatecall boolean, true = transaction delegatecalls the target, else calls the target
   **/
  function executeTransaction(
    address target,
    uint256 value,
    string memory signature,
    bytes memory data,
    uint256 executionTime,
    bool withDelegatecall
  ) external payable returns (bytes memory);

  /**
   * @dev Function, called by Governance, that cancels a transaction, returns action hash
   * @param target smart contract target
   * @param value wei value of the transaction
   * @param signature function signature of the transaction
   * @param data function arguments of the transaction or callData if signature empty
   * @param executionTime time at which to execute the transaction
   * @param withDelegatecall boolean, true = transaction delegatecalls the target, else calls the target
   **/
  function cancelTransaction(
    address target,
    uint256 value,
    string memory signature,
    bytes memory data,
    uint256 executionTime,
    bool withDelegatecall
  ) external returns (bytes32);
}

interface IAaveGovernanceV2 {
  enum ProposalState {Pending, Canceled, Active, Failed, Succeeded, Queued, Expired, Executed}

  struct Vote {
    bool support;
    uint248 votingPower;
  }

  struct Proposal {
    uint256 id;
    address creator;
    IExecutorWithTimelock executor;
    address[] targets;
    uint256[] values;
    string[] signatures;
    bytes[] calldatas;
    bool[] withDelegatecalls;
    uint256 startBlock;
    uint256 endBlock;
    uint256 executionTime;
    uint256 forVotes;
    uint256 againstVotes;
    bool executed;
    bool canceled;
    address strategy;
    bytes32 ipfsHash;
    mapping(address => Vote) votes;
  }

  struct ProposalWithoutVotes {
    uint256 id;
    address creator;
    IExecutorWithTimelock executor;
    address[] targets;
    uint256[] values;
    string[] signatures;
    bytes[] calldatas;
    bool[] withDelegatecalls;
    uint256 startBlock;
    uint256 endBlock;
    uint256 executionTime;
    uint256 forVotes;
    uint256 againstVotes;
    bool executed;
    bool canceled;
    address strategy;
    bytes32 ipfsHash;
  }

  /**
   * @dev emitted when a new proposal is created
   * @param id Id of the proposal
   * @param creator address of the creator
   * @param executor The ExecutorWithTimelock contract that will execute the proposal
   * @param targets list of contracts called by proposal's associated transactions
   * @param values list of value in wei for each propoposal's associated transaction
   * @param signatures list of function signatures (can be empty) to be used when created the callData
   * @param calldatas list of calldatas: if associated signature empty, calldata ready, else calldata is arguments
   * @param withDelegatecalls boolean, true = transaction delegatecalls the taget, else calls the target
   * @param startBlock block number when vote starts
   * @param endBlock block number when vote ends
   * @param strategy address of the governanceStrategy contract
   * @param ipfsHash IPFS hash of the proposal
   **/
  event ProposalCreated(
    uint256 id,
    address indexed creator,
    IExecutorWithTimelock indexed executor,
    address[] targets,
    uint256[] values,
    string[] signatures,
    bytes[] calldatas,
    bool[] withDelegatecalls,
    uint256 startBlock,
    uint256 endBlock,
    address strategy,
    bytes32 ipfsHash
  );

  /**
   * @dev emitted when a proposal is canceled
   * @param id Id of the proposal
   **/
  event ProposalCanceled(uint256 id);

  /**
   * @dev emitted when a proposal is queued
   * @param id Id of the proposal
   * @param executionTime time when proposal underlying transactions can be executed
   * @param initiatorQueueing address of the initiator of the queuing transaction
   **/
  event ProposalQueued(uint256 id, uint256 executionTime, address indexed initiatorQueueing);
  /**
   * @dev emitted when a proposal is executed
   * @param id Id of the proposal
   * @param initiatorExecution address of the initiator of the execution transaction
   **/
  event ProposalExecuted(uint256 id, address indexed initiatorExecution);
  /**
   * @dev emitted when a vote is registered
   * @param id Id of the proposal
   * @param voter address of the voter
   * @param support boolean, true = vote for, false = vote against
   * @param votingPower Power of the voter/vote
   **/
  event VoteEmitted(uint256 id, address indexed voter, bool support, uint256 votingPower);

  event GovernanceStrategyChanged(address indexed newStrategy, address indexed initiatorChange);

  event VotingDelayChanged(uint256 newVotingDelay, address indexed initiatorChange);

  event ExecutorAuthorized(address executor);

  event ExecutorUnauthorized(address executor);

  /**
   * @dev Creates a Proposal (needs Proposition Power of creator > Threshold)
   * @param executor The ExecutorWithTimelock contract that will execute the proposal
   * @param targets list of contracts called by proposal's associated transactions
   * @param values list of value in wei for each propoposal's associated transaction
   * @param signatures list of function signatures (can be empty) to be used when created the callData
   * @param calldatas list of calldatas: if associated signature empty, calldata ready, else calldata is arguments
   * @param withDelegatecalls if true, transaction delegatecalls the taget, else calls the target
   * @param ipfsHash IPFS hash of the proposal
   **/
  function create(
    IExecutorWithTimelock executor,
    address[] memory targets,
    uint256[] memory values,
    string[] memory signatures,
    bytes[] memory calldatas,
    bool[] memory withDelegatecalls,
    bytes32 ipfsHash
  ) external returns (uint256);

  /**
   * @dev Cancels a Proposal,
   * either at anytime by guardian
   * or when proposal is Pending/Active and threshold no longer reached
   * @param proposalId id of the proposal
   **/
  function cancel(uint256 proposalId) external;

  /**
   * @dev Queue the proposal (If Proposal Succeeded)
   * @param proposalId id of the proposal to queue
   **/
  function queue(uint256 proposalId) external;

  /**
   * @dev Execute the proposal (If Proposal Queued)
   * @param proposalId id of the proposal to execute
   **/
  function execute(uint256 proposalId) external payable;

  /**
   * @dev Function allowing msg.sender to vote for/against a proposal
   * @param proposalId id of the proposal
   * @param support boolean, true = vote for, false = vote against
   **/
  function submitVote(uint256 proposalId, bool support) external;

  /**
   * @dev Function to register the vote of user that has voted offchain via signature
   * @param proposalId id of the proposal
   * @param support boolean, true = vote for, false = vote against
   * @param v v part of the voter signature
   * @param r r part of the voter signature
   * @param s s part of the voter signature
   **/
  function submitVoteBySignature(
    uint256 proposalId,
    bool support,
    uint8 v,
    bytes32 r,
    bytes32 s
  ) external;

  /**
   * @dev Set new GovernanceStrategy
   * Note: owner should be a timelocked executor, so needs to make a proposal
   * @param governanceStrategy new Address of the GovernanceStrategy contract
   **/
  function setGovernanceStrategy(address governanceStrategy) external;

  /**
   * @dev Set new Voting Delay (delay before a newly created proposal can be voted on)
   * Note: owner should be a timelocked executor, so needs to make a proposal
   * @param votingDelay new voting delay in seconds
   **/
  function setVotingDelay(uint256 votingDelay) external;

  /**
   * @dev Add new addresses to the list of authorized executors
   * @param executors list of new addresses to be authorized executors
   **/
  function authorizeExecutors(address[] memory executors) external;

  /**
   * @dev Remove addresses to the list of authorized executors
   * @param executors list of addresses to be removed as authorized executors
   **/
  function unauthorizeExecutors(address[] memory executors) external;

  /**
   * @dev Let the guardian abdicate from its priviledged rights
   **/
  function __abdicate() external;

  /**
   * @dev Getter of the current GovernanceStrategy address
   * @return The address of the current GovernanceStrategy contracts
   **/
  function getGovernanceStrategy() external view returns (address);

  /**
   * @dev Getter of the current Voting Delay (delay before a created proposal can be voted on)
   * Different from the voting duration
   * @return The voting delay in seconds
   **/
  function getVotingDelay() external view returns (uint256);

  /**
   * @dev Returns whether an address is an authorized executor
   * @param executor address to evaluate as authorized executor
   * @return true if authorized
   **/
  function isExecutorAuthorized(address executor) external view returns (bool);

  /**
   * @dev Getter the address of the guardian, that can mainly cancel proposals
   * @return The address of the guardian
   **/
  function getGuardian() external view returns (address);

  /**
   * @dev Getter of the proposal count (the current number of proposals ever created)
   * @return the proposal count
   **/
  function getProposalsCount() external view returns (uint256);

  /**
   * @dev Getter of a proposal by id
   * @param proposalId id of the proposal to get
   * @return the proposal as ProposalWithoutVotes memory object
   **/
  function getProposalById(uint256 proposalId) external view returns (ProposalWithoutVotes memory);

  /**
   * @dev Getter of the Vote of a voter about a proposal
   * Note: Vote is a struct: ({bool support, uint248 votingPower})
   * @param proposalId id of the proposal
   * @param voter address of the voter
   * @return The associated Vote memory object
   **/
  function getVoteOnProposal(uint256 proposalId, address voter) external view returns (Vote memory);

  /**
   * @dev Get the current state of a proposal
   * @param proposalId id of the proposal
   * @return The current state if the proposal
   **/
  function getProposalState(uint256 proposalId) external view returns (ProposalState);
}

/**
 * @title Governance V2 contract
 * @dev Main point of interaction with Aave protocol's governance
 * - Create a Proposal
 * - Cancel a Proposal
 * - Queue a Proposal
 * - Execute a Proposal
 * - Submit Vote to a Proposal
 * Proposal States : Pending => Active => Succeeded(/Failed) => Queued => Executed(/Expired)
 *                   The transition to "Canceled" can appear in multiple states
 * @author Aave
 **/
contract AaveGovernanceV2 is Ownable, IAaveGovernanceV2 {
  using SafeMath for uint256;

  address private _governanceStrategy;
  uint256 private _votingDelay;

  uint256 private _proposalsCount;
  mapping(uint256 => Proposal) private _proposals;
  mapping(address => bool) private _authorizedExecutors;

  address private _guardian;

  bytes32 public constant DOMAIN_TYPEHASH = keccak256(
    'EIP712Domain(string name,uint256 chainId,address verifyingContract)'
  );
  bytes32 public constant VOTE_EMITTED_TYPEHASH = keccak256('VoteEmitted(uint256 id,bool support)');
  string public constant NAME = 'Aave Governance v2';

  modifier onlyGuardian() {
    require(msg.sender == _guardian, 'ONLY_BY_GUARDIAN');
    _;
  }

  constructor(
    address governanceStrategy,
    uint256 votingDelay,
    address guardian,
    address[] memory executors
  ) {
    _setGovernanceStrategy(governanceStrategy);
    _setVotingDelay(votingDelay);
    _guardian = guardian;

    authorizeExecutors(executors);
  }

  struct CreateVars {
    uint256 startBlock;
    uint256 endBlock;
    uint256 previousProposalsCount;
  }

  /**
   * @dev Creates a Proposal (needs to be validated by the Proposal Validator)
   * @param executor The ExecutorWithTimelock contract that will execute the proposal
   * @param targets list of contracts called by proposal's associated transactions
   * @param values list of value in wei for each propoposal's associated transaction
   * @param signatures list of function signatures (can be empty) to be used when created the callData
   * @param calldatas list of calldatas: if associated signature empty, calldata ready, else calldata is arguments
   * @param withDelegatecalls boolean, true = transaction delegatecalls the taget, else calls the target
   * @param ipfsHash IPFS hash of the proposal
   **/
  function create(
    IExecutorWithTimelock executor,
    address[] memory targets,
    uint256[] memory values,
    string[] memory signatures,
    bytes[] memory calldatas,
    bool[] memory withDelegatecalls,
    bytes32 ipfsHash
  ) external override returns (uint256) {
    require(targets.length != 0, 'INVALID_EMPTY_TARGETS');
    require(
      targets.length == values.length &&
        targets.length == signatures.length &&
        targets.length == calldatas.length &&
        targets.length == withDelegatecalls.length,
      'INCONSISTENT_PARAMS_LENGTH'
    );

    require(isExecutorAuthorized(address(executor)), 'EXECUTOR_NOT_AUTHORIZED');

    require(
      IProposalValidator(address(executor)).validateCreatorOfProposal(
        this,
        msg.sender,
        block.number - 1
      ),
      'PROPOSITION_CREATION_INVALID'
    );

    CreateVars memory vars;

    vars.startBlock = block.number.add(_votingDelay);
    vars.endBlock = vars.startBlock.add(IProposalValidator(address(executor)).VOTING_DURATION());

    vars.previousProposalsCount = _proposalsCount;

    Proposal storage newProposal = _proposals[vars.previousProposalsCount];
    newProposal.id = vars.previousProposalsCount;
    newProposal.creator = msg.sender;
    newProposal.executor = executor;
    newProposal.targets = targets;
    newProposal.values = values;
    newProposal.signatures = signatures;
    newProposal.calldatas = calldatas;
    newProposal.withDelegatecalls = withDelegatecalls;
    newProposal.startBlock = vars.startBlock;
    newProposal.endBlock = vars.endBlock;
    newProposal.strategy = _governanceStrategy;
    newProposal.ipfsHash = ipfsHash;
    _proposalsCount++;

    emit ProposalCreated(
      vars.previousProposalsCount,
      msg.sender,
      executor,
      targets,
      values,
      signatures,
      calldatas,
      withDelegatecalls,
      vars.startBlock,
      vars.endBlock,
      _governanceStrategy,
      ipfsHash
    );

    return newProposal.id;
  }

  /**
   * @dev Cancels a Proposal.
   * - Callable by the _guardian with relaxed conditions, or by anybody if the conditions of
   *   cancellation on the executor are fulfilled
   * @param proposalId id of the proposal
   **/
  function cancel(uint256 proposalId) external override {
    ProposalState state = getProposalState(proposalId);
    require(
      state != ProposalState.Executed &&
        state != ProposalState.Canceled &&
        state != ProposalState.Expired,
      'ONLY_BEFORE_EXECUTED'
    );

    Proposal storage proposal = _proposals[proposalId];
    require(
      msg.sender == _guardian ||
        IProposalValidator(address(proposal.executor)).validateProposalCancellation(
          this,
          proposal.creator,
          block.number - 1
        ),
      'PROPOSITION_CANCELLATION_INVALID'
    );
    proposal.canceled = true;
    for (uint256 i = 0; i < proposal.targets.length; i++) {
      proposal.executor.cancelTransaction(
        proposal.targets[i],
        proposal.values[i],
        proposal.signatures[i],
        proposal.calldatas[i],
        proposal.executionTime,
        proposal.withDelegatecalls[i]
      );
    }

    emit ProposalCanceled(proposalId);
  }

  /**
   * @dev Queue the proposal (If Proposal Succeeded)
   * @param proposalId id of the proposal to queue
   **/
  function queue(uint256 proposalId) external override {
    require(getProposalState(proposalId) == ProposalState.Succeeded, 'INVALID_STATE_FOR_QUEUE');
    Proposal storage proposal = _proposals[proposalId];
    uint256 executionTime = block.timestamp.add(proposal.executor.getDelay());
    for (uint256 i = 0; i < proposal.targets.length; i++) {
      _queueOrRevert(
        proposal.executor,
        proposal.targets[i],
        proposal.values[i],
        proposal.signatures[i],
        proposal.calldatas[i],
        executionTime,
        proposal.withDelegatecalls[i]
      );
    }
    proposal.executionTime = executionTime;

    emit ProposalQueued(proposalId, executionTime, msg.sender);
  }

  /**
   * @dev Execute the proposal (If Proposal Queued)
   * @param proposalId id of the proposal to execute
   **/
  function execute(uint256 proposalId) external payable override {
    require(getProposalState(proposalId) == ProposalState.Queued, 'ONLY_QUEUED_PROPOSALS');
    Proposal storage proposal = _proposals[proposalId];
    proposal.executed = true;
    for (uint256 i = 0; i < proposal.targets.length; i++) {
      proposal.executor.executeTransaction{value: proposal.values[i]}(
        proposal.targets[i],
        proposal.values[i],
        proposal.signatures[i],
        proposal.calldatas[i],
        proposal.executionTime,
        proposal.withDelegatecalls[i]
      );
    }
    emit ProposalExecuted(proposalId, msg.sender);
  }

  /**
   * @dev Function allowing msg.sender to vote for/against a proposal
   * @param proposalId id of the proposal
   * @param support boolean, true = vote for, false = vote against
   **/
  function submitVote(uint256 proposalId, bool support) external override {
    return _submitVote(msg.sender, proposalId, support);
  }

  /**
   * @dev Function to register the vote of user that has voted offchain via signature
   * @param proposalId id of the proposal
   * @param support boolean, true = vote for, false = vote against
   * @param v v part of the voter signature
   * @param r r part of the voter signature
   * @param s s part of the voter signature
   **/
  function submitVoteBySignature(
    uint256 proposalId,
    bool support,
    uint8 v,
    bytes32 r,
    bytes32 s
  ) external override {
    bytes32 digest = keccak256(
      abi.encodePacked(
        '\x19\x01',
        keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(NAME)), getChainId(), address(this))),
        keccak256(abi.encode(VOTE_EMITTED_TYPEHASH, proposalId, support))
      )
    );
    address signer = ecrecover(digest, v, r, s);
    require(signer != address(0), 'INVALID_SIGNATURE');
    return _submitVote(signer, proposalId, support);
  }

  /**
   * @dev Set new GovernanceStrategy
   * Note: owner should be a timelocked executor, so needs to make a proposal
   * @param governanceStrategy new Address of the GovernanceStrategy contract
   **/
  function setGovernanceStrategy(address governanceStrategy) external override onlyOwner {
    _setGovernanceStrategy(governanceStrategy);
  }

  /**
   * @dev Set new Voting Delay (delay before a newly created proposal can be voted on)
   * Note: owner should be a timelocked executor, so needs to make a proposal
   * @param votingDelay new voting delay in terms of blocks
   **/
  function setVotingDelay(uint256 votingDelay) external override onlyOwner {
    _setVotingDelay(votingDelay);
  }

  /**
   * @dev Add new addresses to the list of authorized executors
   * @param executors list of new addresses to be authorized executors
   **/
  function authorizeExecutors(address[] memory executors) public override onlyOwner {
    for (uint256 i = 0; i < executors.length; i++) {
      _authorizeExecutor(executors[i]);
    }
  }

  /**
   * @dev Remove addresses to the list of authorized executors
   * @param executors list of addresses to be removed as authorized executors
   **/
  function unauthorizeExecutors(address[] memory executors) public override onlyOwner {
    for (uint256 i = 0; i < executors.length; i++) {
      _unauthorizeExecutor(executors[i]);
    }
  }

  /**
   * @dev Let the guardian abdicate from its priviledged rights
   **/
  function __abdicate() external override onlyGuardian {
    _guardian = address(0);
  }

  /**
   * @dev Getter of the current GovernanceStrategy address
   * @return The address of the current GovernanceStrategy contracts
   **/
  function getGovernanceStrategy() external view override returns (address) {
    return _governanceStrategy;
  }

  /**
   * @dev Getter of the current Voting Delay (delay before a created proposal can be voted on)
   * Different from the voting duration
   * @return The voting delay in number of blocks
   **/
  function getVotingDelay() external view override returns (uint256) {
    return _votingDelay;
  }

  /**
   * @dev Returns whether an address is an authorized executor
   * @param executor address to evaluate as authorized executor
   * @return true if authorized
   **/
  function isExecutorAuthorized(address executor) public view override returns (bool) {
    return _authorizedExecutors[executor];
  }

  /**
   * @dev Getter the address of the guardian, that can mainly cancel proposals
   * @return The address of the guardian
   **/
  function getGuardian() external view override returns (address) {
    return _guardian;
  }

  /**
   * @dev Getter of the proposal count (the current number of proposals ever created)
   * @return the proposal count
   **/
  function getProposalsCount() external view override returns (uint256) {
    return _proposalsCount;
  }

  /**
   * @dev Getter of a proposal by id
   * @param proposalId id of the proposal to get
   * @return the proposal as ProposalWithoutVotes memory object
   **/
  function getProposalById(uint256 proposalId)
    external
    view
    override
    returns (ProposalWithoutVotes memory)
  {
    Proposal storage proposal = _proposals[proposalId];
    ProposalWithoutVotes memory proposalWithoutVotes = ProposalWithoutVotes({
      id: proposal.id,
      creator: proposal.creator,
      executor: proposal.executor,
      targets: proposal.targets,
      values: proposal.values,
      signatures: proposal.signatures,
      calldatas: proposal.calldatas,
      withDelegatecalls: proposal.withDelegatecalls,
      startBlock: proposal.startBlock,
      endBlock: proposal.endBlock,
      executionTime: proposal.executionTime,
      forVotes: proposal.forVotes,
      againstVotes: proposal.againstVotes,
      executed: proposal.executed,
      canceled: proposal.canceled,
      strategy: proposal.strategy,
      ipfsHash: proposal.ipfsHash
    });

    return proposalWithoutVotes;
  }

  /**
   * @dev Getter of the Vote of a voter about a proposal
   * Note: Vote is a struct: ({bool support, uint248 votingPower})
   * @param proposalId id of the proposal
   * @param voter address of the voter
   * @return The associated Vote memory object
   **/
  function getVoteOnProposal(uint256 proposalId, address voter)
    external
    view
    override
    returns (Vote memory)
  {
    return _proposals[proposalId].votes[voter];
  }

  /**
   * @dev Get the current state of a proposal
   * @param proposalId id of the proposal
   * @return The current state if the proposal
   **/
  function getProposalState(uint256 proposalId) public view override returns (ProposalState) {
    require(_proposalsCount >= proposalId, 'INVALID_PROPOSAL_ID');
    Proposal storage proposal = _proposals[proposalId];
    if (proposal.canceled) {
      return ProposalState.Canceled;
    } else if (block.number <= proposal.startBlock) {
      return ProposalState.Pending;
    } else if (block.number <= proposal.endBlock) {
      return ProposalState.Active;
    } else if (!IProposalValidator(address(proposal.executor)).isProposalPassed(this, proposalId)) {
      return ProposalState.Failed;
    } else if (proposal.executionTime == 0) {
      return ProposalState.Succeeded;
    } else if (proposal.executed) {
      return ProposalState.Executed;
    } else if (proposal.executor.isProposalOverGracePeriod(this, proposalId)) {
      return ProposalState.Expired;
    } else {
      return ProposalState.Queued;
    }
  }

  function _queueOrRevert(
    IExecutorWithTimelock executor,
    address target,
    uint256 value,
    string memory signature,
    bytes memory callData,
    uint256 executionTime,
    bool withDelegatecall
  ) internal {
    require(
      !executor.isActionQueued(
        keccak256(abi.encode(target, value, signature, callData, executionTime, withDelegatecall))
      ),
      'DUPLICATED_ACTION'
    );
    executor.queueTransaction(target, value, signature, callData, executionTime, withDelegatecall);
  }

  function _submitVote(
    address voter,
    uint256 proposalId,
    bool support
  ) internal {
    require(getProposalState(proposalId) == ProposalState.Active, 'VOTING_CLOSED');
    Proposal storage proposal = _proposals[proposalId];
    Vote storage vote = proposal.votes[voter];

    require(vote.votingPower == 0, 'VOTE_ALREADY_SUBMITTED');

    uint256 votingPower = IVotingStrategy(proposal.strategy).getVotingPowerAt(
      voter,
      proposal.startBlock
    );

    if (support) {
      proposal.forVotes = proposal.forVotes.add(votingPower);
    } else {
      proposal.againstVotes = proposal.againstVotes.add(votingPower);
    }

    vote.support = support;
    vote.votingPower = uint248(votingPower);

    emit VoteEmitted(proposalId, voter, support, votingPower);
  }

  function _setGovernanceStrategy(address governanceStrategy) internal {
    _governanceStrategy = governanceStrategy;

    emit GovernanceStrategyChanged(governanceStrategy, msg.sender);
  }

  function _setVotingDelay(uint256 votingDelay) internal {
    _votingDelay = votingDelay;

    emit VotingDelayChanged(votingDelay, msg.sender);
  }

  function _authorizeExecutor(address executor) internal {
    _authorizedExecutors[executor] = true;
    emit ExecutorAuthorized(executor);
  }

  function _unauthorizeExecutor(address executor) internal {
    _authorizedExecutors[executor] = false;
    emit ExecutorUnauthorized(executor);
  }
}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"governanceStrategy","internalType":"address"},{"type":"uint256","name":"votingDelay","internalType":"uint256"},{"type":"address","name":"guardian","internalType":"address"},{"type":"address[]","name":"executors","internalType":"address[]"}]},{"type":"event","name":"ExecutorAuthorized","inputs":[{"type":"address","name":"executor","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"ExecutorUnauthorized","inputs":[{"type":"address","name":"executor","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"GovernanceStrategyChanged","inputs":[{"type":"address","name":"newStrategy","internalType":"address","indexed":true},{"type":"address","name":"initiatorChange","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"ProposalCanceled","inputs":[{"type":"uint256","name":"id","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"ProposalCreated","inputs":[{"type":"uint256","name":"id","internalType":"uint256","indexed":false},{"type":"address","name":"creator","internalType":"address","indexed":true},{"type":"address","name":"executor","internalType":"contract IExecutorWithTimelock","indexed":true},{"type":"address[]","name":"targets","internalType":"address[]","indexed":false},{"type":"uint256[]","name":"values","internalType":"uint256[]","indexed":false},{"type":"string[]","name":"signatures","internalType":"string[]","indexed":false},{"type":"bytes[]","name":"calldatas","internalType":"bytes[]","indexed":false},{"type":"bool[]","name":"withDelegatecalls","internalType":"bool[]","indexed":false},{"type":"uint256","name":"startBlock","internalType":"uint256","indexed":false},{"type":"uint256","name":"endBlock","internalType":"uint256","indexed":false},{"type":"address","name":"strategy","internalType":"address","indexed":false},{"type":"bytes32","name":"ipfsHash","internalType":"bytes32","indexed":false}],"anonymous":false},{"type":"event","name":"ProposalExecuted","inputs":[{"type":"uint256","name":"id","internalType":"uint256","indexed":false},{"type":"address","name":"initiatorExecution","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"ProposalQueued","inputs":[{"type":"uint256","name":"id","internalType":"uint256","indexed":false},{"type":"uint256","name":"executionTime","internalType":"uint256","indexed":false},{"type":"address","name":"initiatorQueueing","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"VoteEmitted","inputs":[{"type":"uint256","name":"id","internalType":"uint256","indexed":false},{"type":"address","name":"voter","internalType":"address","indexed":true},{"type":"bool","name":"support","internalType":"bool","indexed":false},{"type":"uint256","name":"votingPower","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"VotingDelayChanged","inputs":[{"type":"uint256","name":"newVotingDelay","internalType":"uint256","indexed":false},{"type":"address","name":"initiatorChange","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"DOMAIN_TYPEHASH","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"NAME","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"VOTE_EMITTED_TYPEHASH","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"__abdicate","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"authorizeExecutors","inputs":[{"type":"address[]","name":"executors","internalType":"address[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cancel","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"create","inputs":[{"type":"address","name":"executor","internalType":"contract IExecutorWithTimelock"},{"type":"address[]","name":"targets","internalType":"address[]"},{"type":"uint256[]","name":"values","internalType":"uint256[]"},{"type":"string[]","name":"signatures","internalType":"string[]"},{"type":"bytes[]","name":"calldatas","internalType":"bytes[]"},{"type":"bool[]","name":"withDelegatecalls","internalType":"bool[]"},{"type":"bytes32","name":"ipfsHash","internalType":"bytes32"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"execute","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getGovernanceStrategy","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getGuardian","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct IAaveGovernanceV2.ProposalWithoutVotes","components":[{"type":"uint256","name":"id","internalType":"uint256"},{"type":"address","name":"creator","internalType":"address"},{"type":"address","name":"executor","internalType":"contract IExecutorWithTimelock"},{"type":"address[]","name":"targets","internalType":"address[]"},{"type":"uint256[]","name":"values","internalType":"uint256[]"},{"type":"string[]","name":"signatures","internalType":"string[]"},{"type":"bytes[]","name":"calldatas","internalType":"bytes[]"},{"type":"bool[]","name":"withDelegatecalls","internalType":"bool[]"},{"type":"uint256","name":"startBlock","internalType":"uint256"},{"type":"uint256","name":"endBlock","internalType":"uint256"},{"type":"uint256","name":"executionTime","internalType":"uint256"},{"type":"uint256","name":"forVotes","internalType":"uint256"},{"type":"uint256","name":"againstVotes","internalType":"uint256"},{"type":"bool","name":"executed","internalType":"bool"},{"type":"bool","name":"canceled","internalType":"bool"},{"type":"address","name":"strategy","internalType":"address"},{"type":"bytes32","name":"ipfsHash","internalType":"bytes32"}]}],"name":"getProposalById","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"enum IAaveGovernanceV2.ProposalState"}],"name":"getProposalState","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getProposalsCount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct IAaveGovernanceV2.Vote","components":[{"type":"bool","name":"support","internalType":"bool"},{"type":"uint248","name":"votingPower","internalType":"uint248"}]}],"name":"getVoteOnProposal","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256"},{"type":"address","name":"voter","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getVotingDelay","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isExecutorAuthorized","inputs":[{"type":"address","name":"executor","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"queue","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setGovernanceStrategy","inputs":[{"type":"address","name":"governanceStrategy","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setVotingDelay","inputs":[{"type":"uint256","name":"votingDelay","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"submitVote","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256"},{"type":"bool","name":"support","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"submitVoteBySignature","inputs":[{"type":"uint256","name":"proposalId","internalType":"uint256"},{"type":"bool","name":"support","internalType":"bool"},{"type":"uint8","name":"v","internalType":"uint8"},{"type":"bytes32","name":"r","internalType":"bytes32"},{"type":"bytes32","name":"s","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unauthorizeExecutors","inputs":[{"type":"address[]","name":"executors","internalType":"address[]"}]}]
              

Contract Creation Code

Verify & Publish
0x60806040523480156200001157600080fd5b506040516200356838038062003568833981016040819052620000349162000264565b600062000040620000d0565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506200009584620000d4565b620000a08362000121565b600680546001600160a01b0319166001600160a01b038416179055620000c68162000165565b50505050620003bc565b3390565b600180546001600160a01b0319166001600160a01b0383169081179091556040513391907f9e8e9f668db69a2cefb172dabe284d0d3aea2b7ee64212a205bd033bd03a3d5590600090a350565b600281905560405133907fc46fc23e244f0720a98ddbac6efb5bb40d212cf15e6478fc4b3017648715289d906200015a9084906200038f565b60405180910390a250565b6200016f620000d0565b6000546001600160a01b03908116911614620001a85760405162461bcd60e51b81526004016200019f906200035a565b60405180910390fd5b60005b8151811015620001e357620001da828281518110620001c657fe5b6020026020010151620001e760201b60201c565b600101620001ab565b5050565b6001600160a01b03811660009081526005602052604090819020805460ff19166001179055517f52762435f58790076157ea2a4914a5a4d0aa0eb421588891377692f7fd3bc082906200023c90839062000346565b60405180910390a150565b80516001600160a01b03811681146200025f57600080fd5b919050565b600080600080608085870312156200027a578384fd5b620002858562000247565b935060208086015193506200029d6040870162000247565b60608701519093506001600160401b0380821115620002ba578384fd5b818801915088601f830112620002ce578384fd5b815181811115620002db57fe5b8381029150620002ed84830162000398565b8181528481019084860184860187018d101562000308578788fd5b8795505b838610156200033557620003208162000247565b8352600195909501949186019186016200030c565b50989b979a50959850505050505050565b6001600160a01b0391909116815260200190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b90815260200190565b6040518181016001600160401b0381118282101715620003b457fe5b604052919050565b61319c80620003cc6000396000f3fe6080604052600436106101665760003560e01c8063760fbc13116100d1578063a3f4df7e1161008a578063ddf0b00911610064578063ddf0b00914610403578063f2fde38b14610423578063f8741a9c14610443578063fe0d94c11461046357610166565b8063a3f4df7e146103ac578063a75b87d2146103ce578063af1e0bd3146103e357610166565b8063760fbc131461030b5780638da5cb5b146103205780639080936f1461033557806398e527d3146103625780639aad6f6a14610377578063a2b170b01461039757610166565b80634185ff83116101235780634185ff831461023c578063548b514e14610269578063612c56fa1461029657806364c786d9146102b657806370b0f660146102d6578063715018a6146102f657610166565b806306be3e8e1461016b5780631a1caf7f1461019657806320606b70146101b857806334b18c26146101da5780633656de21146101ef57806340e58ee51461021c575b600080fd5b34801561017757600080fd5b50610180610476565b60405161018d919061299e565b60405180910390f35b3480156101a257600080fd5b506101b66101b1366004612542565b610485565b005b3480156101c457600080fd5b506101cd6104f7565b60405161018d9190612a63565b3480156101e657600080fd5b506101cd61051b565b3480156101fb57600080fd5b5061020f61020a36600461270a565b61053f565b60405161018d9190612e64565b34801561022857600080fd5b506101b661023736600461270a565b6108f0565b34801561024857600080fd5b5061025c610257366004612722565b610bc2565b60405161018d9190612fbe565b34801561027557600080fd5b50610289610284366004612526565b610c1b565b60405161018d9190612a58565b3480156102a257600080fd5b506101b66102b1366004612751565b610c39565b3480156102c257600080fd5b506101b66102d1366004612542565b610c44565b3480156102e257600080fd5b506101b66102f136600461270a565b610ca9565b34801561030257600080fd5b506101b6610cea565b34801561031757600080fd5b506101b6610d69565b34801561032c57600080fd5b50610180610da5565b34801561034157600080fd5b5061035561035036600461270a565b610db4565b60405161018d9190612aea565b34801561036e57600080fd5b506101cd610f85565b34801561038357600080fd5b506101b6610392366004612526565b610f8b565b3480156103a357600080fd5b506101cd610fc9565b3480156103b857600080fd5b506103c1610fcf565b60405161018d9190612afe565b3480156103da57600080fd5b50610180610ffd565b3480156103ef57600080fd5b506101b66103fe366004612775565b61100c565b34801561040f57600080fd5b506101b661041e36600461270a565b6111ae565b34801561042f57600080fd5b506101b661043e366004612526565b6114aa565b34801561044f57600080fd5b506101cd61045e366004612624565b611560565b6101b661047136600461270a565b6118e9565b6001546001600160a01b031690565b61048d611ae8565b6000546001600160a01b039081169116146104c35760405162461bcd60e51b81526004016104ba90612d39565b60405180910390fd5b60005b81518110156104f3576104eb8282815181106104de57fe5b6020026020010151611aec565b6001016104c6565b5050565b7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b7f4e031542a9553ed1c4e810c54674ab4b984243e335b246aa3de73663bf4c11ee81565b610547611f6e565b600082815260046020526040902061055d611f6e565b60408051610220810182528354815260018401546001600160a01b039081166020808401919091526002860154909116828401526003850180548451818402810184019095528085529293606085019390928301828280156105e857602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116105ca575b505050505081526020018360040180548060200260200160405190810160405280929190818152602001828054801561064057602002820191906000526020600020905b81548152602001906001019080831161062c575b5050505050815260200183600501805480602002602001604051908101604052809291908181526020016000905b828210156107195760008481526020908190208301805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156107055780601f106106da57610100808354040283529160200191610705565b820191906000526020600020905b8154815290600101906020018083116106e857829003601f168201915b50505050508152602001906001019061066e565b50505050815260200183600601805480602002602001604051908101604052809291908181526020016000905b828210156107f15760008481526020908190208301805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156107dd5780601f106107b2576101008083540402835291602001916107dd565b820191906000526020600020905b8154815290600101906020018083116107c057829003601f168201915b505050505081526020019060010190610746565b5050505081526020018360070180548060200260200160405190810160405280929190818152602001828054801561086857602002820191906000526020600020906000905b825461010083900a900460ff1615158152602060019283018181049485019490930390920291018084116108375790505b50505091835250506008840154602082015260098401546040820152600a8401546060820152600b8401546080820152600c84015460a0820152600d84015460ff808216151560c0840152610100808304909116151560e0840152620100009091046001600160a01b031690820152600e90930154610120909301929092525090505b919050565b60006108fb82610db4565b9050600781600781111561090b57fe5b141580156109255750600181600781111561092257fe5b14155b801561093d5750600681600781111561093a57fe5b14155b6109595760405162461bcd60e51b81526004016104ba90612dda565b60008281526004602052604090206006546001600160a01b0316331480610a0c5750600281015460018201546040516331a7bc4160e01b81526001600160a01b03928316926331a7bc41926109bc92309290911690436000190190600401612ac6565b60206040518083038186803b1580156109d457600080fd5b505afa1580156109e8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a0c919061257d565b610a285760405162461bcd60e51b81526004016104ba90612da5565b600d8101805461ff00191661010017905560005b6003820154811015610b855760028201546003830180546001600160a01b0390921691631dc40b51919084908110610a7057fe5b6000918252602090912001546004850180546001600160a01b039092169185908110610a9857fe5b9060005260206000200154856005018581548110610ab257fe5b90600052602060002001866006018681548110610acb57fe5b9060005260206000200187600a0154886007018881548110610ae957fe5b90600052602060002090602091828204019190069054906101000a900460ff166040518763ffffffff1660e01b8152600401610b2a96959493929190612a1f565b602060405180830381600087803b158015610b4457600080fd5b505af1158015610b58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b7c9190612599565b50600101610a3c565b507f789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c83604051610bb59190612a63565b60405180910390a1505050565b610bca612014565b5060008281526004602090815260408083206001600160a01b0385168452600f0182529182902082518084019093525460ff8116151583526001600160f81b03610100909104169082015292915050565b6001600160a01b031660009081526005602052604090205460ff1690565b6104f3338383611b47565b610c4c611ae8565b6000546001600160a01b03908116911614610c795760405162461bcd60e51b81526004016104ba90612d39565b60005b81518110156104f357610ca1828281518110610c9457fe5b6020026020010151611d01565b600101610c7c565b610cb1611ae8565b6000546001600160a01b03908116911614610cde5760405162461bcd60e51b81526004016104ba90612d39565b610ce781611d54565b50565b610cf2611ae8565b6000546001600160a01b03908116911614610d1f5760405162461bcd60e51b81526004016104ba90612d39565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6006546001600160a01b03163314610d935760405162461bcd60e51b81526004016104ba90612d0f565b600680546001600160a01b0319169055565b6000546001600160a01b031690565b6000816003541015610dd85760405162461bcd60e51b81526004016104ba90612e08565b6000828152600460205260409020600d810154610100900460ff1615610e025760019150506108eb565b80600801544311610e175760009150506108eb565b80600901544311610e2c5760029150506108eb565b60028101546040516306fbb3ab60e01b81526001600160a01b03909116906306fbb3ab90610e6090309087906004016129b2565b60206040518083038186803b158015610e7857600080fd5b505afa158015610e8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb0919061257d565b610ebe5760039150506108eb565b600a810154610ed15760049150506108eb565b600d81015460ff1615610ee85760079150506108eb565b600281015460405163f670a5f960e01b81526001600160a01b039091169063f670a5f990610f1c90309087906004016129b2565b60206040518083038186803b158015610f3457600080fd5b505afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c919061257d565b15610f7b5760069150506108eb565b60059150506108eb565b60035490565b610f93611ae8565b6000546001600160a01b03908116911614610fc05760405162461bcd60e51b81526004016104ba90612d39565b610ce781611d96565b60025490565b6040518060400160405280601281526020017120b0bb329023b7bb32b93730b731b2903b1960711b81525081565b6006546001600160a01b031690565b60408051808201909152601281527120b0bb329023b7bb32b93730b731b2903b1960711b60209091015260007f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a8667f4cc6f35bf1a450a8f51b0719ea5910c789b7b914b5c4f0451867c8a5475a4982611082611de3565b306040516020016110969493929190612a6c565b604051602081830303815290604052805190602001207f4e031542a9553ed1c4e810c54674ab4b984243e335b246aa3de73663bf4c11ee87876040516020016110e193929190612a90565b60405160208183030381529060405280519060200120604051602001611108929190612983565b6040516020818303038152906040528051906020012090506000600182868686604051600081526020016040526040516111459493929190612aa8565b6020604051602081039080840390855afa158015611167573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661119a5760405162461bcd60e51b81526004016104ba90612c7d565b6111a5818888611b47565b50505050505050565b60046111b982610db4565b60078111156111c457fe5b146111e15760405162461bcd60e51b81526004016104ba90612bec565b60008181526004602081815260408084206002810154825163675e4d4160e11b81529251919594611278946001600160a01b039092169363cebc9a829381830193929091829003018186803b15801561123957600080fd5b505afa15801561124d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112719190612599565b4290611de7565b905060005b6003830154811015611461576002830154600384018054611459926001600160a01b03169190849081106112ad57fe5b6000918252602090912001546004860180546001600160a01b0390921691859081106112d557fe5b90600052602060002001548660050185815481106112ef57fe5b600091825260209182902001805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801561137d5780601f106113525761010080835404028352916020019161137d565b820191906000526020600020905b81548152906001019060200180831161136057829003601f168201915b505050505087600601868154811061139157fe5b600091825260209182902001805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801561141f5780601f106113f45761010080835404028352916020019161141f565b820191906000526020600020905b81548152906001019060200180831161140257829003601f168201915b50505050508789600701888154811061143457fe5b90600052602060002090602091828204019190069054906101000a900460ff16611e13565b60010161127d565b50600a820181905560405133907f11a0b38e70585e4b09b794bd1d9f9b1a51a802eb8ee2101eeee178d0349e73fe9061149d9086908590613095565b60405180910390a2505050565b6114b2611ae8565b6000546001600160a01b039081169116146114df5760405162461bcd60e51b81526004016104ba90612d39565b6001600160a01b0381166115055760405162461bcd60e51b81526004016104ba90612b11565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60008651600014156115845760405162461bcd60e51b81526004016104ba90612c4e565b85518751148015611596575084518751145b80156115a3575083518751145b80156115b0575082518751145b6115cc5760405162461bcd60e51b81526004016104ba90612d6e565b6115d588610c1b565b6115f15760405162461bcd60e51b81526004016104ba90612cd8565b604051631a1b205360e31b81526001600160a01b0389169063d0d90298906116259030903390600019430190600401612ac6565b60206040518083038186803b15801561163d57600080fd5b505afa158015611651573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611675919061257d565b6116915760405162461bcd60e51b81526004016104ba90612b57565b61169961202b565b6002546116a7904390611de7565b81600001818152505061172c896001600160a01b031663a438d2086040518163ffffffff1660e01b815260040160206040518083038186803b1580156116ec57600080fd5b505afa158015611700573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117249190612599565b825190611de7565b602082810191909152600380546040808501828152600092835260048552912090518155600181018054336001600160a01b0319918216179091556002820180549091166001600160a01b038e161790558a51909261179192840191908c019061204c565b5087516117a790600483019060208b01906120b1565b5086516117bd90600583019060208a01906120ec565b5085516117d39060068301906020890190612145565b5084516117e9906007830190602088019061219e565b508160000151816008018190555081602001518160090181905550600160009054906101000a90046001600160a01b031681600d0160026101000a8154816001600160a01b0302191690836001600160a01b031602179055508381600e0181905550600360008154809291906001019190505550896001600160a01b0316336001600160a01b03167fd272d67d2c8c66de43c1d2515abb064978a5020c173e15903b6a2ab3bf7440ec84604001518c8c8c8c8c8a600001518b60200151600160009054906101000a90046001600160a01b03168f6040516118d39a99989796959493929190612fe0565b60405180910390a3549998505050505050505050565b60056118f482610db4565b60078111156118ff57fe5b1461191c5760405162461bcd60e51b81526004016104ba90612e35565b6000818152600460205260408120600d8101805460ff19166001179055905b6003820154811015611aa25760028201546004830180546001600160a01b0390921691638902ab6591908490811061196f57fe5b906000526020600020015484600301848154811061198957fe5b6000918252602090912001546004860180546001600160a01b0390921691869081106119b157fe5b90600052602060002001548660050186815481106119cb57fe5b906000526020600020018760060187815481106119e457fe5b9060005260206000200188600a0154896007018981548110611a0257fe5b90600052602060002090602091828204019190069054906101000a900460ff166040518863ffffffff1660e01b8152600401611a4396959493929190612a1f565b6000604051808303818588803b158015611a5c57600080fd5b505af1158015611a70573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f19168201604052611a9991908101906125b1565b5060010161193b565b50336001600160a01b03167f9c85b616f29fca57a17eafe71cf9ff82ffef41766e2cf01ea7f8f7878dd3ec2483604051611adc9190612a63565b60405180910390a25050565b3390565b6001600160a01b03811660009081526005602052604090819020805460ff19169055517f5e8105a2af24345971359d2289f43efa80d093f4a7123561b8d63836b98724f490611b3c90839061299e565b60405180910390a150565b6002611b5283610db4565b6007811115611b5d57fe5b14611b7a5760405162461bcd60e51b81526004016104ba90612bc5565b60008281526004602090815260408083206001600160a01b0387168452600f8101909252909120805461010090046001600160f81b031615611bce5760405162461bcd60e51b81526004016104ba90612ca8565b600d820154600883015460405163eaeded5f60e01b81526000926201000090046001600160a01b03169163eaeded5f91611c0c918a916004016129b2565b60206040518083038186803b158015611c2457600080fd5b505afa158015611c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c5c9190612599565b90508315611c7d57600b830154611c739082611de7565b600b840155611c92565b600c830154611c8c9082611de7565b600c8401555b815460ff60ff1990911685151517166101006001600160f81b038316021782556040516001600160a01b038716907f0c611e7b6ae0de26f4772260e1bbdb5f58cbb7c275fe2de14671968d29add8d690611cf19088908890869061307f565b60405180910390a2505050505050565b6001600160a01b03811660009081526005602052604090819020805460ff19166001179055517f52762435f58790076157ea2a4914a5a4d0aa0eb421588891377692f7fd3bc08290611b3c90839061299e565b600281905560405133907fc46fc23e244f0720a98ddbac6efb5bb40d212cf15e6478fc4b3017648715289d90611d8b908490612a63565b60405180910390a250565b600180546001600160a01b0319166001600160a01b0383169081179091556040513391907f9e8e9f668db69a2cefb172dabe284d0d3aea2b7ee64212a205bd033bd03a3d5590600090a350565b4690565b600082820183811015611e0c5760405162461bcd60e51b81526004016104ba90612b8e565b9392505050565b866001600160a01b031663b1fc8796878787878787604051602001611e3d969594939291906129cb565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b8152600401611e6f9190612a63565b60206040518083038186803b158015611e8757600080fd5b505afa158015611e9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ebf919061257d565b15611edc5760405162461bcd60e51b81526004016104ba90612c23565b604051638d8fe2e360e01b81526001600160a01b03881690638d8fe2e390611f12908990899089908990899089906004016129cb565b602060405180830381600087803b158015611f2c57600080fd5b505af1158015611f40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f649190612599565b5050505050505050565b6040518061022001604052806000815260200160006001600160a01b0316815260200160006001600160a01b031681526020016060815260200160608152602001606081526020016060815260200160608152602001600081526020016000815260200160008152602001600081526020016000815260200160001515815260200160001515815260200160006001600160a01b03168152602001600080191681525090565b604080518082019091526000808252602082015290565b60405180606001604052806000815260200160008152602001600081525090565b8280548282559060005260206000209081019282156120a1579160200282015b828111156120a157825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019061206c565b506120ad92915061223a565b5090565b8280548282559060005260206000209081019282156120a1579160200282015b828111156120a15782518255916020019190600101906120d1565b828054828255906000526020600020908101928215612139579160200282015b82811115612139578251805161212991849160209091019061224f565b509160200191906001019061210c565b506120ad9291506122ca565b828054828255906000526020600020908101928215612192579160200282015b82811115612192578251805161218291849160209091019061224f565b5091602001919060010190612165565b506120ad9291506122e7565b82805482825590600052602060002090601f016020900481019282156120a15791602002820160005b8382111561220457835183826101000a81548160ff02191690831515021790555092602001926001016020816000010492830192600103026121c7565b80156122315782816101000a81549060ff0219169055600101602081600001049283019260010302612204565b50506120ad9291505b5b808211156120ad576000815560010161223b565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928261228557600085556120a1565b82601f1061229e57805160ff19168380011785556120a1565b828001600101855582156120a157918201828111156120a15782518255916020019190600101906120d1565b808211156120ad5760006122de8282612304565b506001016122ca565b808211156120ad5760006122fb8282612304565b506001016122e7565b50805460018160011615610100020316600290046000825580601f1061232a5750610ce7565b601f016020900490600052602060002090810190610ce7919061223a565b600082601f830112612358578081fd5b813561236b612366826130c7565b6130a3565b81815291506020808301908481018184028601820187101561238c57600080fd5b60005b848110156123b45781356123a281613143565b8452928201929082019060010161238f565b505050505092915050565b600082601f8301126123cf578081fd5b81356123dd612366826130c7565b8181529150602080830190848101818402860182018710156123fe57600080fd5b60005b848110156123b457813561241481613158565b84529282019290820190600101612401565b600082601f830112612436578081fd5b8135612444612366826130c7565b818152915060208083019084810160005b848110156123b4578135870188603f82011261247057600080fd5b83810135612480612366826130e5565b81815260408b8184860101111561249657600080fd5b82818501888401375060009181018601919091528552509282019290820190600101612455565b600082601f8301126124cd578081fd5b81356124db612366826130c7565b8181529150602080830190848101818402860182018710156124fc57600080fd5b60005b848110156123b4578135845292820192908201906001016124ff565b80356108eb81613143565b600060208284031215612537578081fd5b8135611e0c81613143565b600060208284031215612553578081fd5b813567ffffffffffffffff811115612569578182fd5b61257584828501612348565b949350505050565b60006020828403121561258e578081fd5b8151611e0c81613158565b6000602082840312156125aa578081fd5b5051919050565b6000602082840312156125c2578081fd5b815167ffffffffffffffff8111156125d8578182fd5b8201601f810184136125e8578182fd5b80516125f6612366826130e5565b81815285602083850101111561260a578384fd5b61261b826020830160208601613113565b95945050505050565b600080600080600080600060e0888a03121561263e578283fd5b6126478861251b565b9650602088013567ffffffffffffffff80821115612663578485fd5b61266f8b838c01612348565b975060408a0135915080821115612684578485fd5b6126908b838c016124bd565b965060608a01359150808211156126a5578485fd5b6126b18b838c01612426565b955060808a01359150808211156126c6578485fd5b6126d28b838c01612426565b945060a08a01359150808211156126e7578384fd5b506126f48a828b016123bf565b92505060c0880135905092959891949750929550565b60006020828403121561271b578081fd5b5035919050565b60008060408385031215612734578182fd5b82359150602083013561274681613143565b809150509250929050565b60008060408385031215612763578182fd5b82359150602083013561274681613158565b600080600080600060a0868803121561278c578283fd5b85359450602086013561279e81613158565b9350604086013560ff811681146127b3578384fd5b94979396509394606081013594506080013592915050565b6001600160a01b03169052565b6000815180845260208085019450808401835b838110156128105781516001600160a01b0316875295820195908201906001016127eb565b509495945050505050565b6000815180845260208085019450808401835b8381101561281057815115158752958201959082019060010161282e565b6000815180845260208085018081965082840281019150828601855b858110156128925782840389526128808483516128d4565b98850198935090840190600101612868565b5091979650505050505050565b6000815180845260208085019450808401835b83811015612810578151875295820195908201906001016128b2565b15159052565b600081518084526128ec816020860160208601613113565b601f01601f19169290920160200192915050565b6000815460018082166000811461291e576001811461293c5761297a565b60028304607f16865260ff198316602087015260408601935061297a565b6002830480875261294c86613107565b60005b828110156129705781546020828b010152848201915060208101905061294f565b8801602001955050505b50505092915050565b61190160f01b81526002810192909252602282015260420190565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b600060018060a01b038816825286602083015260c060408301526129f260c08301876128d4565b8281036060840152612a0481876128d4565b6080840195909552505090151560a090910152949350505050565b600060018060a01b038816825286602083015260c06040830152612a4660c0830187612900565b8281036060840152612a048187612900565b901515815260200190565b90815260200190565b938452602084019290925260408301526001600160a01b0316606082015260800190565b92835260208301919091521515604082015260600190565b93845260ff9290921660208401526040830152606082015260800190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6020810160088310612af857fe5b91905290565b600060208252611e0c60208301846128d4565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252601c908201527f50524f504f534954494f4e5f4352454154494f4e5f494e56414c494400000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252600d908201526c1593d5125391d7d0d313d4d151609a1b604082015260600190565b60208082526017908201527f494e56414c49445f53544154455f464f525f5155455545000000000000000000604082015260600190565b602080825260119082015270222aa82624a1a0aa22a22fa0a1aa24a7a760791b604082015260600190565b602080825260159082015274494e56414c49445f454d5054595f5441524745545360581b604082015260600190565b602080825260119082015270494e56414c49445f5349474e415455524560781b604082015260600190565b6020808252601690820152751593d51157d053149150511657d4d55093525515115160521b604082015260600190565b60208082526017908201527f4558454355544f525f4e4f545f415554484f52495a4544000000000000000000604082015260600190565b60208082526010908201526f27a7262cafa12cafa3aaa0a92224a0a760811b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601a908201527f494e434f4e53495354454e545f504152414d535f4c454e475448000000000000604082015260600190565b6020808252818101527f50524f504f534954494f4e5f43414e43454c4c4154494f4e5f494e56414c4944604082015260600190565b60208082526014908201527313d3931657d0915193d49157d1561150d555115160621b604082015260600190565b6020808252601390820152721253959053125117d41493d413d4d05317d251606a1b604082015260600190565b6020808252601590820152744f4e4c595f5155455545445f50524f504f53414c5360581b604082015260600190565b600060208252825160208301526020830151612e8360408401826127cb565b506040830151612e9660608401826127cb565b506060830151610220806080850152612eb36102408501836127d8565b91506080850151601f19808685030160a0870152612ed1848361289f565b935060a08701519150808685030160c0870152612eee848361284c565b935060c08701519150808685030160e0870152612f0b848361284c565b935060e08701519150610100818786030181880152612f2a858461281b565b90880151610120888101919091528801516101408089019190915288015161016080890191909152880151610180808901919091528801516101a08089019190915288015190945091506101c09050612f85818701836128ce565b86015190506101e0612f99868201836128ce565b8601519050610200612fad868201836127cb565b959095015193019290925250919050565b8151151581526020918201516001600160f81b03169181019190915260400190565b60006101408c8352806020840152612ffa8184018d6127d8565b9050828103604084015261300e818c61289f565b90508281036060840152613022818b61284c565b90508281036080840152613036818a61284c565b905082810360a084015261304a818961281b565b60c0840197909752505060e08101939093526001600160a01b0391909116610100830152610120909101529695505050505050565b9283529015156020830152604082015260600190565b918252602082015260400190565b60405181810167ffffffffffffffff811182821017156130bf57fe5b604052919050565b600067ffffffffffffffff8211156130db57fe5b5060209081020190565b600067ffffffffffffffff8211156130f957fe5b50601f01601f191660200190565b60009081526020902090565b60005b8381101561312e578181015183820152602001613116565b8381111561313d576000848401525b50505050565b6001600160a01b0381168114610ce757600080fd5b8015158114610ce757600080fdfea26469706673582212203255f14330cf43fabb4281e87def734f660a2374d36a74dbd177480523c8dfc664736f6c6343000705003300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ca76ebd8617a03126b6fb84f9b1c1a0fb71c263300000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000

Deployed ByteCode

0x6080604052600436106101665760003560e01c8063760fbc13116100d1578063a3f4df7e1161008a578063ddf0b00911610064578063ddf0b00914610403578063f2fde38b14610423578063f8741a9c14610443578063fe0d94c11461046357610166565b8063a3f4df7e146103ac578063a75b87d2146103ce578063af1e0bd3146103e357610166565b8063760fbc131461030b5780638da5cb5b146103205780639080936f1461033557806398e527d3146103625780639aad6f6a14610377578063a2b170b01461039757610166565b80634185ff83116101235780634185ff831461023c578063548b514e14610269578063612c56fa1461029657806364c786d9146102b657806370b0f660146102d6578063715018a6146102f657610166565b806306be3e8e1461016b5780631a1caf7f1461019657806320606b70146101b857806334b18c26146101da5780633656de21146101ef57806340e58ee51461021c575b600080fd5b34801561017757600080fd5b50610180610476565b60405161018d919061299e565b60405180910390f35b3480156101a257600080fd5b506101b66101b1366004612542565b610485565b005b3480156101c457600080fd5b506101cd6104f7565b60405161018d9190612a63565b3480156101e657600080fd5b506101cd61051b565b3480156101fb57600080fd5b5061020f61020a36600461270a565b61053f565b60405161018d9190612e64565b34801561022857600080fd5b506101b661023736600461270a565b6108f0565b34801561024857600080fd5b5061025c610257366004612722565b610bc2565b60405161018d9190612fbe565b34801561027557600080fd5b50610289610284366004612526565b610c1b565b60405161018d9190612a58565b3480156102a257600080fd5b506101b66102b1366004612751565b610c39565b3480156102c257600080fd5b506101b66102d1366004612542565b610c44565b3480156102e257600080fd5b506101b66102f136600461270a565b610ca9565b34801561030257600080fd5b506101b6610cea565b34801561031757600080fd5b506101b6610d69565b34801561032c57600080fd5b50610180610da5565b34801561034157600080fd5b5061035561035036600461270a565b610db4565b60405161018d9190612aea565b34801561036e57600080fd5b506101cd610f85565b34801561038357600080fd5b506101b6610392366004612526565b610f8b565b3480156103a357600080fd5b506101cd610fc9565b3480156103b857600080fd5b506103c1610fcf565b60405161018d9190612afe565b3480156103da57600080fd5b50610180610ffd565b3480156103ef57600080fd5b506101b66103fe366004612775565b61100c565b34801561040f57600080fd5b506101b661041e36600461270a565b6111ae565b34801561042f57600080fd5b506101b661043e366004612526565b6114aa565b34801561044f57600080fd5b506101cd61045e366004612624565b611560565b6101b661047136600461270a565b6118e9565b6001546001600160a01b031690565b61048d611ae8565b6000546001600160a01b039081169116146104c35760405162461bcd60e51b81526004016104ba90612d39565b60405180910390fd5b60005b81518110156104f3576104eb8282815181106104de57fe5b6020026020010151611aec565b6001016104c6565b5050565b7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b7f4e031542a9553ed1c4e810c54674ab4b984243e335b246aa3de73663bf4c11ee81565b610547611f6e565b600082815260046020526040902061055d611f6e565b60408051610220810182528354815260018401546001600160a01b039081166020808401919091526002860154909116828401526003850180548451818402810184019095528085529293606085019390928301828280156105e857602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116105ca575b505050505081526020018360040180548060200260200160405190810160405280929190818152602001828054801561064057602002820191906000526020600020905b81548152602001906001019080831161062c575b5050505050815260200183600501805480602002602001604051908101604052809291908181526020016000905b828210156107195760008481526020908190208301805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156107055780601f106106da57610100808354040283529160200191610705565b820191906000526020600020905b8154815290600101906020018083116106e857829003601f168201915b50505050508152602001906001019061066e565b50505050815260200183600601805480602002602001604051908101604052809291908181526020016000905b828210156107f15760008481526020908190208301805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156107dd5780601f106107b2576101008083540402835291602001916107dd565b820191906000526020600020905b8154815290600101906020018083116107c057829003601f168201915b505050505081526020019060010190610746565b5050505081526020018360070180548060200260200160405190810160405280929190818152602001828054801561086857602002820191906000526020600020906000905b825461010083900a900460ff1615158152602060019283018181049485019490930390920291018084116108375790505b50505091835250506008840154602082015260098401546040820152600a8401546060820152600b8401546080820152600c84015460a0820152600d84015460ff808216151560c0840152610100808304909116151560e0840152620100009091046001600160a01b031690820152600e90930154610120909301929092525090505b919050565b60006108fb82610db4565b9050600781600781111561090b57fe5b141580156109255750600181600781111561092257fe5b14155b801561093d5750600681600781111561093a57fe5b14155b6109595760405162461bcd60e51b81526004016104ba90612dda565b60008281526004602052604090206006546001600160a01b0316331480610a0c5750600281015460018201546040516331a7bc4160e01b81526001600160a01b03928316926331a7bc41926109bc92309290911690436000190190600401612ac6565b60206040518083038186803b1580156109d457600080fd5b505afa1580156109e8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a0c919061257d565b610a285760405162461bcd60e51b81526004016104ba90612da5565b600d8101805461ff00191661010017905560005b6003820154811015610b855760028201546003830180546001600160a01b0390921691631dc40b51919084908110610a7057fe5b6000918252602090912001546004850180546001600160a01b039092169185908110610a9857fe5b9060005260206000200154856005018581548110610ab257fe5b90600052602060002001866006018681548110610acb57fe5b9060005260206000200187600a0154886007018881548110610ae957fe5b90600052602060002090602091828204019190069054906101000a900460ff166040518763ffffffff1660e01b8152600401610b2a96959493929190612a1f565b602060405180830381600087803b158015610b4457600080fd5b505af1158015610b58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b7c9190612599565b50600101610a3c565b507f789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c83604051610bb59190612a63565b60405180910390a1505050565b610bca612014565b5060008281526004602090815260408083206001600160a01b0385168452600f0182529182902082518084019093525460ff8116151583526001600160f81b03610100909104169082015292915050565b6001600160a01b031660009081526005602052604090205460ff1690565b6104f3338383611b47565b610c4c611ae8565b6000546001600160a01b03908116911614610c795760405162461bcd60e51b81526004016104ba90612d39565b60005b81518110156104f357610ca1828281518110610c9457fe5b6020026020010151611d01565b600101610c7c565b610cb1611ae8565b6000546001600160a01b03908116911614610cde5760405162461bcd60e51b81526004016104ba90612d39565b610ce781611d54565b50565b610cf2611ae8565b6000546001600160a01b03908116911614610d1f5760405162461bcd60e51b81526004016104ba90612d39565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6006546001600160a01b03163314610d935760405162461bcd60e51b81526004016104ba90612d0f565b600680546001600160a01b0319169055565b6000546001600160a01b031690565b6000816003541015610dd85760405162461bcd60e51b81526004016104ba90612e08565b6000828152600460205260409020600d810154610100900460ff1615610e025760019150506108eb565b80600801544311610e175760009150506108eb565b80600901544311610e2c5760029150506108eb565b60028101546040516306fbb3ab60e01b81526001600160a01b03909116906306fbb3ab90610e6090309087906004016129b2565b60206040518083038186803b158015610e7857600080fd5b505afa158015610e8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb0919061257d565b610ebe5760039150506108eb565b600a810154610ed15760049150506108eb565b600d81015460ff1615610ee85760079150506108eb565b600281015460405163f670a5f960e01b81526001600160a01b039091169063f670a5f990610f1c90309087906004016129b2565b60206040518083038186803b158015610f3457600080fd5b505afa158015610f48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6c919061257d565b15610f7b5760069150506108eb565b60059150506108eb565b60035490565b610f93611ae8565b6000546001600160a01b03908116911614610fc05760405162461bcd60e51b81526004016104ba90612d39565b610ce781611d96565b60025490565b6040518060400160405280601281526020017120b0bb329023b7bb32b93730b731b2903b1960711b81525081565b6006546001600160a01b031690565b60408051808201909152601281527120b0bb329023b7bb32b93730b731b2903b1960711b60209091015260007f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a8667f4cc6f35bf1a450a8f51b0719ea5910c789b7b914b5c4f0451867c8a5475a4982611082611de3565b306040516020016110969493929190612a6c565b604051602081830303815290604052805190602001207f4e031542a9553ed1c4e810c54674ab4b984243e335b246aa3de73663bf4c11ee87876040516020016110e193929190612a90565b60405160208183030381529060405280519060200120604051602001611108929190612983565b6040516020818303038152906040528051906020012090506000600182868686604051600081526020016040526040516111459493929190612aa8565b6020604051602081039080840390855afa158015611167573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661119a5760405162461bcd60e51b81526004016104ba90612c7d565b6111a5818888611b47565b50505050505050565b60046111b982610db4565b60078111156111c457fe5b146111e15760405162461bcd60e51b81526004016104ba90612bec565b60008181526004602081815260408084206002810154825163675e4d4160e11b81529251919594611278946001600160a01b039092169363cebc9a829381830193929091829003018186803b15801561123957600080fd5b505afa15801561124d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112719190612599565b4290611de7565b905060005b6003830154811015611461576002830154600384018054611459926001600160a01b03169190849081106112ad57fe5b6000918252602090912001546004860180546001600160a01b0390921691859081106112d557fe5b90600052602060002001548660050185815481106112ef57fe5b600091825260209182902001805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801561137d5780601f106113525761010080835404028352916020019161137d565b820191906000526020600020905b81548152906001019060200180831161136057829003601f168201915b505050505087600601868154811061139157fe5b600091825260209182902001805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801561141f5780601f106113f45761010080835404028352916020019161141f565b820191906000526020600020905b81548152906001019060200180831161140257829003601f168201915b50505050508789600701888154811061143457fe5b90600052602060002090602091828204019190069054906101000a900460ff16611e13565b60010161127d565b50600a820181905560405133907f11a0b38e70585e4b09b794bd1d9f9b1a51a802eb8ee2101eeee178d0349e73fe9061149d9086908590613095565b60405180910390a2505050565b6114b2611ae8565b6000546001600160a01b039081169116146114df5760405162461bcd60e51b81526004016104ba90612d39565b6001600160a01b0381166115055760405162461bcd60e51b81526004016104ba90612b11565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60008651600014156115845760405162461bcd60e51b81526004016104ba90612c4e565b85518751148015611596575084518751145b80156115a3575083518751145b80156115b0575082518751145b6115cc5760405162461bcd60e51b81526004016104ba90612d6e565b6115d588610c1b565b6115f15760405162461bcd60e51b81526004016104ba90612cd8565b604051631a1b205360e31b81526001600160a01b0389169063d0d90298906116259030903390600019430190600401612ac6565b60206040518083038186803b15801561163d57600080fd5b505afa158015611651573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611675919061257d565b6116915760405162461bcd60e51b81526004016104ba90612b57565b61169961202b565b6002546116a7904390611de7565b81600001818152505061172c896001600160a01b031663a438d2086040518163ffffffff1660e01b815260040160206040518083038186803b1580156116ec57600080fd5b505afa158015611700573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117249190612599565b825190611de7565b602082810191909152600380546040808501828152600092835260048552912090518155600181018054336001600160a01b0319918216179091556002820180549091166001600160a01b038e161790558a51909261179192840191908c019061204c565b5087516117a790600483019060208b01906120b1565b5086516117bd90600583019060208a01906120ec565b5085516117d39060068301906020890190612145565b5084516117e9906007830190602088019061219e565b508160000151816008018190555081602001518160090181905550600160009054906101000a90046001600160a01b031681600d0160026101000a8154816001600160a01b0302191690836001600160a01b031602179055508381600e0181905550600360008154809291906001019190505550896001600160a01b0316336001600160a01b03167fd272d67d2c8c66de43c1d2515abb064978a5020c173e15903b6a2ab3bf7440ec84604001518c8c8c8c8c8a600001518b60200151600160009054906101000a90046001600160a01b03168f6040516118d39a99989796959493929190612fe0565b60405180910390a3549998505050505050505050565b60056118f482610db4565b60078111156118ff57fe5b1461191c5760405162461bcd60e51b81526004016104ba90612e35565b6000818152600460205260408120600d8101805460ff19166001179055905b6003820154811015611aa25760028201546004830180546001600160a01b0390921691638902ab6591908490811061196f57fe5b906000526020600020015484600301848154811061198957fe5b6000918252602090912001546004860180546001600160a01b0390921691869081106119b157fe5b90600052602060002001548660050186815481106119cb57fe5b906000526020600020018760060187815481106119e457fe5b9060005260206000200188600a0154896007018981548110611a0257fe5b90600052602060002090602091828204019190069054906101000a900460ff166040518863ffffffff1660e01b8152600401611a4396959493929190612a1f565b6000604051808303818588803b158015611a5c57600080fd5b505af1158015611a70573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f19168201604052611a9991908101906125b1565b5060010161193b565b50336001600160a01b03167f9c85b616f29fca57a17eafe71cf9ff82ffef41766e2cf01ea7f8f7878dd3ec2483604051611adc9190612a63565b60405180910390a25050565b3390565b6001600160a01b03811660009081526005602052604090819020805460ff19169055517f5e8105a2af24345971359d2289f43efa80d093f4a7123561b8d63836b98724f490611b3c90839061299e565b60405180910390a150565b6002611b5283610db4565b6007811115611b5d57fe5b14611b7a5760405162461bcd60e51b81526004016104ba90612bc5565b60008281526004602090815260408083206001600160a01b0387168452600f8101909252909120805461010090046001600160f81b031615611bce5760405162461bcd60e51b81526004016104ba90612ca8565b600d820154600883015460405163eaeded5f60e01b81526000926201000090046001600160a01b03169163eaeded5f91611c0c918a916004016129b2565b60206040518083038186803b158015611c2457600080fd5b505afa158015611c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c5c9190612599565b90508315611c7d57600b830154611c739082611de7565b600b840155611c92565b600c830154611c8c9082611de7565b600c8401555b815460ff60ff1990911685151517166101006001600160f81b038316021782556040516001600160a01b038716907f0c611e7b6ae0de26f4772260e1bbdb5f58cbb7c275fe2de14671968d29add8d690611cf19088908890869061307f565b60405180910390a2505050505050565b6001600160a01b03811660009081526005602052604090819020805460ff19166001179055517f52762435f58790076157ea2a4914a5a4d0aa0eb421588891377692f7fd3bc08290611b3c90839061299e565b600281905560405133907fc46fc23e244f0720a98ddbac6efb5bb40d212cf15e6478fc4b3017648715289d90611d8b908490612a63565b60405180910390a250565b600180546001600160a01b0319166001600160a01b0383169081179091556040513391907f9e8e9f668db69a2cefb172dabe284d0d3aea2b7ee64212a205bd033bd03a3d5590600090a350565b4690565b600082820183811015611e0c5760405162461bcd60e51b81526004016104ba90612b8e565b9392505050565b866001600160a01b031663b1fc8796878787878787604051602001611e3d969594939291906129cb565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b8152600401611e6f9190612a63565b60206040518083038186803b158015611e8757600080fd5b505afa158015611e9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ebf919061257d565b15611edc5760405162461bcd60e51b81526004016104ba90612c23565b604051638d8fe2e360e01b81526001600160a01b03881690638d8fe2e390611f12908990899089908990899089906004016129cb565b602060405180830381600087803b158015611f2c57600080fd5b505af1158015611f40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f649190612599565b5050505050505050565b6040518061022001604052806000815260200160006001600160a01b0316815260200160006001600160a01b031681526020016060815260200160608152602001606081526020016060815260200160608152602001600081526020016000815260200160008152602001600081526020016000815260200160001515815260200160001515815260200160006001600160a01b03168152602001600080191681525090565b604080518082019091526000808252602082015290565b60405180606001604052806000815260200160008152602001600081525090565b8280548282559060005260206000209081019282156120a1579160200282015b828111156120a157825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019061206c565b506120ad92915061223a565b5090565b8280548282559060005260206000209081019282156120a1579160200282015b828111156120a15782518255916020019190600101906120d1565b828054828255906000526020600020908101928215612139579160200282015b82811115612139578251805161212991849160209091019061224f565b509160200191906001019061210c565b506120ad9291506122ca565b828054828255906000526020600020908101928215612192579160200282015b82811115612192578251805161218291849160209091019061224f565b5091602001919060010190612165565b506120ad9291506122e7565b82805482825590600052602060002090601f016020900481019282156120a15791602002820160005b8382111561220457835183826101000a81548160ff02191690831515021790555092602001926001016020816000010492830192600103026121c7565b80156122315782816101000a81549060ff0219169055600101602081600001049283019260010302612204565b50506120ad9291505b5b808211156120ad576000815560010161223b565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928261228557600085556120a1565b82601f1061229e57805160ff19168380011785556120a1565b828001600101855582156120a157918201828111156120a15782518255916020019190600101906120d1565b808211156120ad5760006122de8282612304565b506001016122ca565b808211156120ad5760006122fb8282612304565b506001016122e7565b50805460018160011615610100020316600290046000825580601f1061232a5750610ce7565b601f016020900490600052602060002090810190610ce7919061223a565b600082601f830112612358578081fd5b813561236b612366826130c7565b6130a3565b81815291506020808301908481018184028601820187101561238c57600080fd5b60005b848110156123b45781356123a281613143565b8452928201929082019060010161238f565b505050505092915050565b600082601f8301126123cf578081fd5b81356123dd612366826130c7565b8181529150602080830190848101818402860182018710156123fe57600080fd5b60005b848110156123b457813561241481613158565b84529282019290820190600101612401565b600082601f830112612436578081fd5b8135612444612366826130c7565b818152915060208083019084810160005b848110156123b4578135870188603f82011261247057600080fd5b83810135612480612366826130e5565b81815260408b8184860101111561249657600080fd5b82818501888401375060009181018601919091528552509282019290820190600101612455565b600082601f8301126124cd578081fd5b81356124db612366826130c7565b8181529150602080830190848101818402860182018710156124fc57600080fd5b60005b848110156123b4578135845292820192908201906001016124ff565b80356108eb81613143565b600060208284031215612537578081fd5b8135611e0c81613143565b600060208284031215612553578081fd5b813567ffffffffffffffff811115612569578182fd5b61257584828501612348565b949350505050565b60006020828403121561258e578081fd5b8151611e0c81613158565b6000602082840312156125aa578081fd5b5051919050565b6000602082840312156125c2578081fd5b815167ffffffffffffffff8111156125d8578182fd5b8201601f810184136125e8578182fd5b80516125f6612366826130e5565b81815285602083850101111561260a578384fd5b61261b826020830160208601613113565b95945050505050565b600080600080600080600060e0888a03121561263e578283fd5b6126478861251b565b9650602088013567ffffffffffffffff80821115612663578485fd5b61266f8b838c01612348565b975060408a0135915080821115612684578485fd5b6126908b838c016124bd565b965060608a01359150808211156126a5578485fd5b6126b18b838c01612426565b955060808a01359150808211156126c6578485fd5b6126d28b838c01612426565b945060a08a01359150808211156126e7578384fd5b506126f48a828b016123bf565b92505060c0880135905092959891949750929550565b60006020828403121561271b578081fd5b5035919050565b60008060408385031215612734578182fd5b82359150602083013561274681613143565b809150509250929050565b60008060408385031215612763578182fd5b82359150602083013561274681613158565b600080600080600060a0868803121561278c578283fd5b85359450602086013561279e81613158565b9350604086013560ff811681146127b3578384fd5b94979396509394606081013594506080013592915050565b6001600160a01b03169052565b6000815180845260208085019450808401835b838110156128105781516001600160a01b0316875295820195908201906001016127eb565b509495945050505050565b6000815180845260208085019450808401835b8381101561281057815115158752958201959082019060010161282e565b6000815180845260208085018081965082840281019150828601855b858110156128925782840389526128808483516128d4565b98850198935090840190600101612868565b5091979650505050505050565b6000815180845260208085019450808401835b83811015612810578151875295820195908201906001016128b2565b15159052565b600081518084526128ec816020860160208601613113565b601f01601f19169290920160200192915050565b6000815460018082166000811461291e576001811461293c5761297a565b60028304607f16865260ff198316602087015260408601935061297a565b6002830480875261294c86613107565b60005b828110156129705781546020828b010152848201915060208101905061294f565b8801602001955050505b50505092915050565b61190160f01b81526002810192909252602282015260420190565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b600060018060a01b038816825286602083015260c060408301526129f260c08301876128d4565b8281036060840152612a0481876128d4565b6080840195909552505090151560a090910152949350505050565b600060018060a01b038816825286602083015260c06040830152612a4660c0830187612900565b8281036060840152612a048187612900565b901515815260200190565b90815260200190565b938452602084019290925260408301526001600160a01b0316606082015260800190565b92835260208301919091521515604082015260600190565b93845260ff9290921660208401526040830152606082015260800190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6020810160088310612af857fe5b91905290565b600060208252611e0c60208301846128d4565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252601c908201527f50524f504f534954494f4e5f4352454154494f4e5f494e56414c494400000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252600d908201526c1593d5125391d7d0d313d4d151609a1b604082015260600190565b60208082526017908201527f494e56414c49445f53544154455f464f525f5155455545000000000000000000604082015260600190565b602080825260119082015270222aa82624a1a0aa22a22fa0a1aa24a7a760791b604082015260600190565b602080825260159082015274494e56414c49445f454d5054595f5441524745545360581b604082015260600190565b602080825260119082015270494e56414c49445f5349474e415455524560781b604082015260600190565b6020808252601690820152751593d51157d053149150511657d4d55093525515115160521b604082015260600190565b60208082526017908201527f4558454355544f525f4e4f545f415554484f52495a4544000000000000000000604082015260600190565b60208082526010908201526f27a7262cafa12cafa3aaa0a92224a0a760811b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601a908201527f494e434f4e53495354454e545f504152414d535f4c454e475448000000000000604082015260600190565b6020808252818101527f50524f504f534954494f4e5f43414e43454c4c4154494f4e5f494e56414c4944604082015260600190565b60208082526014908201527313d3931657d0915193d49157d1561150d555115160621b604082015260600190565b6020808252601390820152721253959053125117d41493d413d4d05317d251606a1b604082015260600190565b6020808252601590820152744f4e4c595f5155455545445f50524f504f53414c5360581b604082015260600190565b600060208252825160208301526020830151612e8360408401826127cb565b506040830151612e9660608401826127cb565b506060830151610220806080850152612eb36102408501836127d8565b91506080850151601f19808685030160a0870152612ed1848361289f565b935060a08701519150808685030160c0870152612eee848361284c565b935060c08701519150808685030160e0870152612f0b848361284c565b935060e08701519150610100818786030181880152612f2a858461281b565b90880151610120888101919091528801516101408089019190915288015161016080890191909152880151610180808901919091528801516101a08089019190915288015190945091506101c09050612f85818701836128ce565b86015190506101e0612f99868201836128ce565b8601519050610200612fad868201836127cb565b959095015193019290925250919050565b8151151581526020918201516001600160f81b03169181019190915260400190565b60006101408c8352806020840152612ffa8184018d6127d8565b9050828103604084015261300e818c61289f565b90508281036060840152613022818b61284c565b90508281036080840152613036818a61284c565b905082810360a084015261304a818961281b565b60c0840197909752505060e08101939093526001600160a01b0391909116610100830152610120909101529695505050505050565b9283529015156020830152604082015260600190565b918252602082015260400190565b60405181810167ffffffffffffffff811182821017156130bf57fe5b604052919050565b600067ffffffffffffffff8211156130db57fe5b5060209081020190565b600067ffffffffffffffff8211156130f957fe5b50601f01601f191660200190565b60009081526020902090565b60005b8381101561312e578181015183820152602001613116565b8381111561313d576000848401525b50505050565b6001600160a01b0381168114610ce757600080fd5b8015158114610ce757600080fdfea26469706673582212203255f14330cf43fabb4281e87def734f660a2374d36a74dbd177480523c8dfc664736f6c63430007050033