NounsDAOLogicV1
Deploy on AlchemyContract Information
Explore the source code, ABI, and bytecode for the NounsDAOLogicV1 smart contract.
More Info
// SPDX-License-Identifier: BSD-3-Clause
/// @title The Nouns DAO logic version 1
/*********************************
* ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
* ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
* ░░░░░░█████████░░█████████░░░ *
* ░░░░░░██░░░████░░██░░░████░░░ *
* ░░██████░░░████████░░░████░░░ *
* ░░██░░██░░░████░░██░░░████░░░ *
* ░░██░░██░░░████░░██░░░████░░░ *
* ░░░░░░█████████░░█████████░░░ *
* ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
* ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
*********************************/
// LICENSE
// NounsDAOLogicV1.sol is a modified version of Compound Lab's GovernorBravoDelegate.sol:
// https://github.com/compound-finance/compound-protocol/blob/b9b14038612d846b83f8a009a82c38974ff2dcfe/contracts/Governance/GovernorBravoDelegate.sol
//
// GovernorBravoDelegate.sol source code Copyright 2020 Compound Labs, Inc. licensed under the BSD-3-Clause license.
// With modifications by Nounders DAO.
//
// Additional conditions of BSD-3-Clause can be found here: https://opensource.org/licenses/BSD-3-Clause
//
// MODIFICATIONS
// NounsDAOLogicV1 adds:
// - Proposal Threshold basis points instead of fixed number
// due to the Noun token's increasing supply
//
// - Quorum Votes basis points instead of fixed number
// due to the Noun token's increasing supply
//
// - Per proposal storing of fixed `proposalThreshold`
// and `quorumVotes` calculated using the Noun token's total supply
// at the block the proposal was created and the basis point parameters
//
// - `ProposalCreatedWithRequirements` event that emits `ProposalCreated` parameters with
// the addition of `proposalThreshold` and `quorumVotes`
//
// - Votes are counted from the block a proposal is created instead of
// the proposal's voting start block to align with the parameters
// stored with the proposal
//
// - Veto ability which allows `veteor` to halt any proposal at any stage unless
// the proposal is executed.
// The `veto(uint proposalId)` logic is a modified version of `cancel(uint proposalId)`
// A `vetoed` flag was added to the `Proposal` struct to support this.
//
// NounsDAOLogicV1 removes:
// - `initialProposalId` and `_initiate()` due to this being the
// first instance of the governance contract unlike
// GovernorBravo which upgrades GovernorAlpha
//
// - Value passed along using `timelock.executeTransaction{value: proposal.value}`
// in `execute(uint proposalId)`. This contract should not hold funds and does not
// implement `receive()` or `fallback()` functions.
//
pragma solidity ^0.8.6;
import './NounsDAOInterfaces.sol';
contract NounsDAOLogicV1 is NounsDAOStorageV1, NounsDAOEvents {
/// @notice The name of this contract
string public constant name = 'Nouns DAO';
/// @notice The minimum setable proposal threshold
uint256 public constant MIN_PROPOSAL_THRESHOLD_BPS = 1; // 1 basis point or 0.01%
/// @notice The maximum setable proposal threshold
uint256 public constant MAX_PROPOSAL_THRESHOLD_BPS = 1_000; // 1,000 basis points or 10%
/// @notice The minimum setable voting period
uint256 public constant MIN_VOTING_PERIOD = 5_760; // About 24 hours
/// @notice The max setable voting period
uint256 public constant MAX_VOTING_PERIOD = 80_640; // About 2 weeks
/// @notice The min setable voting delay
uint256 public constant MIN_VOTING_DELAY = 1;
/// @notice The max setable voting delay
uint256 public constant MAX_VOTING_DELAY = 40_320; // About 1 week
/// @notice The minimum setable quorum votes basis points
uint256 public constant MIN_QUORUM_VOTES_BPS = 200; // 200 basis points or 2%
/// @notice The maximum setable quorum votes basis points
uint256 public constant MAX_QUORUM_VOTES_BPS = 2_000; // 2,000 basis points or 20%
/// @notice The maximum number of actions that can be included in a proposal
uint256 public constant proposalMaxOperations = 10; // 10 actions
/// @notice The EIP-712 typehash for the contract's domain
bytes32 public constant DOMAIN_TYPEHASH =
keccak256('EIP712Domain(string name,uint256 chainId,address verifyingContract)');
/// @notice The EIP-712 typehash for the ballot struct used by the contract
bytes32 public constant BALLOT_TYPEHASH = keccak256('Ballot(uint256 proposalId,uint8 support)');
/**
* @notice Used to initialize the contract during delegator contructor
* @param timelock_ The address of the NounsDAOExecutor
* @param nouns_ The address of the NOUN tokens
* @param vetoer_ The address allowed to unilaterally veto proposals
* @param votingPeriod_ The initial voting period
* @param votingDelay_ The initial voting delay
* @param proposalThresholdBPS_ The initial proposal threshold in basis points
* * @param quorumVotesBPS_ The initial quorum votes threshold in basis points
*/
function initialize(
address timelock_,
address nouns_,
address vetoer_,
uint256 votingPeriod_,
uint256 votingDelay_,
uint256 proposalThresholdBPS_,
uint256 quorumVotesBPS_
) public virtual {
require(address(timelock) == address(0), 'NounsDAO::initialize: can only initialize once');
require(msg.sender == admin, 'NounsDAO::initialize: admin only');
require(timelock_ != address(0), 'NounsDAO::initialize: invalid timelock address');
require(nouns_ != address(0), 'NounsDAO::initialize: invalid nouns address');
require(
votingPeriod_ >= MIN_VOTING_PERIOD && votingPeriod_ <= MAX_VOTING_PERIOD,
'NounsDAO::initialize: invalid voting period'
);
require(
votingDelay_ >= MIN_VOTING_DELAY && votingDelay_ <= MAX_VOTING_DELAY,
'NounsDAO::initialize: invalid voting delay'
);
require(
proposalThresholdBPS_ >= MIN_PROPOSAL_THRESHOLD_BPS && proposalThresholdBPS_ <= MAX_PROPOSAL_THRESHOLD_BPS,
'NounsDAO::initialize: invalid proposal threshold'
);
require(
quorumVotesBPS_ >= MIN_QUORUM_VOTES_BPS && quorumVotesBPS_ <= MAX_QUORUM_VOTES_BPS,
'NounsDAO::initialize: invalid proposal threshold'
);
emit VotingPeriodSet(votingPeriod, votingPeriod_);
emit VotingDelaySet(votingDelay, votingDelay_);
emit ProposalThresholdBPSSet(proposalThresholdBPS, proposalThresholdBPS_);
emit QuorumVotesBPSSet(quorumVotesBPS, quorumVotesBPS_);
timelock = INounsDAOExecutor(timelock_);
nouns = NounsTokenLike(nouns_);
vetoer = vetoer_;
votingPeriod = votingPeriod_;
votingDelay = votingDelay_;
proposalThresholdBPS = proposalThresholdBPS_;
quorumVotesBPS = quorumVotesBPS_;
}
struct ProposalTemp {
uint256 totalSupply;
uint256 proposalThreshold;
uint256 latestProposalId;
uint256 startBlock;
uint256 endBlock;
}
/**
* @notice Function used to propose a new proposal. Sender must have delegates above the proposal threshold
* @param targets Target addresses for proposal calls
* @param values Eth values for proposal calls
* @param signatures Function signatures for proposal calls
* @param calldatas Calldatas for proposal calls
* @param description String description of the proposal
* @return Proposal id of new proposal
*/
function propose(
address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas,
string memory description
) public returns (uint256) {
ProposalTemp memory temp;
temp.totalSupply = nouns.totalSupply();
temp.proposalThreshold = bps2Uint(proposalThresholdBPS, temp.totalSupply);
require(
nouns.getPriorVotes(msg.sender, block.number - 1) > temp.proposalThreshold,
'NounsDAO::propose: proposer votes below proposal threshold'
);
require(
targets.length == values.length &&
targets.length == signatures.length &&
targets.length == calldatas.length,
'NounsDAO::propose: proposal function information arity mismatch'
);
require(targets.length != 0, 'NounsDAO::propose: must provide actions');
require(targets.length <= proposalMaxOperations, 'NounsDAO::propose: too many actions');
temp.latestProposalId = latestProposalIds[msg.sender];
if (temp.latestProposalId != 0) {
ProposalState proposersLatestProposalState = state(temp.latestProposalId);
require(
proposersLatestProposalState != ProposalState.Active,
'NounsDAO::propose: one live proposal per proposer, found an already active proposal'
);
require(
proposersLatestProposalState != ProposalState.Pending,
'NounsDAO::propose: one live proposal per proposer, found an already pending proposal'
);
}
temp.startBlock = block.number + votingDelay;
temp.endBlock = temp.startBlock + votingPeriod;
proposalCount++;
Proposal storage newProposal = proposals[proposalCount];
newProposal.id = proposalCount;
newProposal.proposer = msg.sender;
newProposal.proposalThreshold = temp.proposalThreshold;
newProposal.quorumVotes = bps2Uint(quorumVotesBPS, temp.totalSupply);
newProposal.eta = 0;
newProposal.targets = targets;
newProposal.values = values;
newProposal.signatures = signatures;
newProposal.calldatas = calldatas;
newProposal.startBlock = temp.startBlock;
newProposal.endBlock = temp.endBlock;
newProposal.forVotes = 0;
newProposal.againstVotes = 0;
newProposal.abstainVotes = 0;
newProposal.canceled = false;
newProposal.executed = false;
newProposal.vetoed = false;
latestProposalIds[newProposal.proposer] = newProposal.id;
/// @notice Maintains backwards compatibility with GovernorBravo events
emit ProposalCreated(
newProposal.id,
msg.sender,
targets,
values,
signatures,
calldatas,
newProposal.startBlock,
newProposal.endBlock,
description
);
/// @notice Updated event with `proposalThreshold` and `quorumVotes`
emit ProposalCreatedWithRequirements(
newProposal.id,
msg.sender,
targets,
values,
signatures,
calldatas,
newProposal.startBlock,
newProposal.endBlock,
newProposal.proposalThreshold,
newProposal.quorumVotes,
description
);
return newProposal.id;
}
/**
* @notice Queues a proposal of state succeeded
* @param proposalId The id of the proposal to queue
*/
function queue(uint256 proposalId) external {
require(
state(proposalId) == ProposalState.Succeeded,
'NounsDAO::queue: proposal can only be queued if it is succeeded'
);
Proposal storage proposal = proposals[proposalId];
uint256 eta = block.timestamp + timelock.delay();
for (uint256 i = 0; i < proposal.targets.length; i++) {
queueOrRevertInternal(
proposal.targets[i],
proposal.values[i],
proposal.signatures[i],
proposal.calldatas[i],
eta
);
}
proposal.eta = eta;
emit ProposalQueued(proposalId, eta);
}
function queueOrRevertInternal(
address target,
uint256 value,
string memory signature,
bytes memory data,
uint256 eta
) internal {
require(
!timelock.queuedTransactions(keccak256(abi.encode(target, value, signature, data, eta))),
'NounsDAO::queueOrRevertInternal: identical proposal action already queued at eta'
);
timelock.queueTransaction(target, value, signature, data, eta);
}
/**
* @notice Executes a queued proposal if eta has passed
* @param proposalId The id of the proposal to execute
*/
function execute(uint256 proposalId) external {
require(
state(proposalId) == ProposalState.Queued,
'NounsDAO::execute: proposal can only be executed if it is queued'
);
Proposal storage proposal = proposals[proposalId];
proposal.executed = true;
for (uint256 i = 0; i < proposal.targets.length; i++) {
timelock.executeTransaction(
proposal.targets[i],
proposal.values[i],
proposal.signatures[i],
proposal.calldatas[i],
proposal.eta
);
}
emit ProposalExecuted(proposalId);
}
/**
* @notice Cancels a proposal only if sender is the proposer, or proposer delegates dropped below proposal threshold
* @param proposalId The id of the proposal to cancel
*/
function cancel(uint256 proposalId) external {
require(state(proposalId) != ProposalState.Executed, 'NounsDAO::cancel: cannot cancel executed proposal');
Proposal storage proposal = proposals[proposalId];
require(
msg.sender == proposal.proposer ||
nouns.getPriorVotes(proposal.proposer, block.number - 1) < proposal.proposalThreshold,
'NounsDAO::cancel: proposer above threshold'
);
proposal.canceled = true;
for (uint256 i = 0; i < proposal.targets.length; i++) {
timelock.cancelTransaction(
proposal.targets[i],
proposal.values[i],
proposal.signatures[i],
proposal.calldatas[i],
proposal.eta
);
}
emit ProposalCanceled(proposalId);
}
/**
* @notice Vetoes a proposal only if sender is the vetoer and the proposal has not been executed.
* @param proposalId The id of the proposal to veto
*/
function veto(uint256 proposalId) external {
require(vetoer != address(0), 'NounsDAO::veto: veto power burned');
require(msg.sender == vetoer, 'NounsDAO::veto: only vetoer');
require(state(proposalId) != ProposalState.Executed, 'NounsDAO::veto: cannot veto executed proposal');
Proposal storage proposal = proposals[proposalId];
proposal.vetoed = true;
for (uint256 i = 0; i < proposal.targets.length; i++) {
timelock.cancelTransaction(
proposal.targets[i],
proposal.values[i],
proposal.signatures[i],
proposal.calldatas[i],
proposal.eta
);
}
emit ProposalVetoed(proposalId);
}
/**
* @notice Gets actions of a proposal
* @param proposalId the id of the proposal
* @return targets
* @return values
* @return signatures
* @return calldatas
*/
function getActions(uint256 proposalId)
external
view
returns (
address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas
)
{
Proposal storage p = proposals[proposalId];
return (p.targets, p.values, p.signatures, p.calldatas);
}
/**
* @notice Gets the receipt for a voter on a given proposal
* @param proposalId the id of proposal
* @param voter The address of the voter
* @return The voting receipt
*/
function getReceipt(uint256 proposalId, address voter) external view returns (Receipt memory) {
return proposals[proposalId].receipts[voter];
}
/**
* @notice Gets the state of a proposal
* @param proposalId The id of the proposal
* @return Proposal state
*/
function state(uint256 proposalId) public view returns (ProposalState) {
require(proposalCount >= proposalId, 'NounsDAO::state: invalid proposal id');
Proposal storage proposal = proposals[proposalId];
if (proposal.vetoed) {
return ProposalState.Vetoed;
} else 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 (proposal.forVotes <= proposal.againstVotes || proposal.forVotes < proposal.quorumVotes) {
return ProposalState.Defeated;
} else if (proposal.eta == 0) {
return ProposalState.Succeeded;
} else if (proposal.executed) {
return ProposalState.Executed;
} else if (block.timestamp >= proposal.eta + timelock.GRACE_PERIOD()) {
return ProposalState.Expired;
} else {
return ProposalState.Queued;
}
}
/**
* @notice Cast a vote for a proposal
* @param proposalId The id of the proposal to vote on
* @param support The support value for the vote. 0=against, 1=for, 2=abstain
*/
function castVote(uint256 proposalId, uint8 support) external {
emit VoteCast(msg.sender, proposalId, support, castVoteInternal(msg.sender, proposalId, support), '');
}
/**
* @notice Cast a vote for a proposal with a reason
* @param proposalId The id of the proposal to vote on
* @param support The support value for the vote. 0=against, 1=for, 2=abstain
* @param reason The reason given for the vote by the voter
*/
function castVoteWithReason(
uint256 proposalId,
uint8 support,
string calldata reason
) external {
emit VoteCast(msg.sender, proposalId, support, castVoteInternal(msg.sender, proposalId, support), reason);
}
/**
* @notice Cast a vote for a proposal by signature
* @dev External function that accepts EIP-712 signatures for voting on proposals.
*/
function castVoteBySig(
uint256 proposalId,
uint8 support,
uint8 v,
bytes32 r,
bytes32 s
) external {
bytes32 domainSeparator = keccak256(
abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainIdInternal(), address(this))
);
bytes32 structHash = keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support));
bytes32 digest = keccak256(abi.encodePacked('\x19\x01', domainSeparator, structHash));
address signatory = ecrecover(digest, v, r, s);
require(signatory != address(0), 'NounsDAO::castVoteBySig: invalid signature');
emit VoteCast(signatory, proposalId, support, castVoteInternal(signatory, proposalId, support), '');
}
/**
* @notice Internal function that caries out voting logic
* @param voter The voter that is casting their vote
* @param proposalId The id of the proposal to vote on
* @param support The support value for the vote. 0=against, 1=for, 2=abstain
* @return The number of votes cast
*/
function castVoteInternal(
address voter,
uint256 proposalId,
uint8 support
) internal returns (uint96) {
require(state(proposalId) == ProposalState.Active, 'NounsDAO::castVoteInternal: voting is closed');
require(support <= 2, 'NounsDAO::castVoteInternal: invalid vote type');
Proposal storage proposal = proposals[proposalId];
Receipt storage receipt = proposal.receipts[voter];
require(receipt.hasVoted == false, 'NounsDAO::castVoteInternal: voter already voted');
/// @notice: Unlike GovernerBravo, votes are considered from the block the proposal was created in order to normalize quorumVotes and proposalThreshold metrics
uint96 votes = nouns.getPriorVotes(voter, proposal.startBlock - votingDelay);
if (support == 0) {
proposal.againstVotes = proposal.againstVotes + votes;
} else if (support == 1) {
proposal.forVotes = proposal.forVotes + votes;
} else if (support == 2) {
proposal.abstainVotes = proposal.abstainVotes + votes;
}
receipt.hasVoted = true;
receipt.support = support;
receipt.votes = votes;
return votes;
}
/**
* @notice Admin function for setting the voting delay
* @param newVotingDelay new voting delay, in blocks
*/
function _setVotingDelay(uint256 newVotingDelay) external {
require(msg.sender == admin, 'NounsDAO::_setVotingDelay: admin only');
require(
newVotingDelay >= MIN_VOTING_DELAY && newVotingDelay <= MAX_VOTING_DELAY,
'NounsDAO::_setVotingDelay: invalid voting delay'
);
uint256 oldVotingDelay = votingDelay;
votingDelay = newVotingDelay;
emit VotingDelaySet(oldVotingDelay, votingDelay);
}
/**
* @notice Admin function for setting the voting period
* @param newVotingPeriod new voting period, in blocks
*/
function _setVotingPeriod(uint256 newVotingPeriod) external {
require(msg.sender == admin, 'NounsDAO::_setVotingPeriod: admin only');
require(
newVotingPeriod >= MIN_VOTING_PERIOD && newVotingPeriod <= MAX_VOTING_PERIOD,
'NounsDAO::_setVotingPeriod: invalid voting period'
);
uint256 oldVotingPeriod = votingPeriod;
votingPeriod = newVotingPeriod;
emit VotingPeriodSet(oldVotingPeriod, votingPeriod);
}
/**
* @notice Admin function for setting the proposal threshold basis points
* @dev newProposalThresholdBPS must be greater than the hardcoded min
* @param newProposalThresholdBPS new proposal threshold
*/
function _setProposalThresholdBPS(uint256 newProposalThresholdBPS) external {
require(msg.sender == admin, 'NounsDAO::_setProposalThresholdBPS: admin only');
require(
newProposalThresholdBPS >= MIN_PROPOSAL_THRESHOLD_BPS &&
newProposalThresholdBPS <= MAX_PROPOSAL_THRESHOLD_BPS,
'NounsDAO::_setProposalThreshold: invalid proposal threshold'
);
uint256 oldProposalThresholdBPS = proposalThresholdBPS;
proposalThresholdBPS = newProposalThresholdBPS;
emit ProposalThresholdBPSSet(oldProposalThresholdBPS, proposalThresholdBPS);
}
/**
* @notice Admin function for setting the quorum votes basis points
* @dev newQuorumVotesBPS must be greater than the hardcoded min
* @param newQuorumVotesBPS new proposal threshold
*/
function _setQuorumVotesBPS(uint256 newQuorumVotesBPS) external {
require(msg.sender == admin, 'NounsDAO::_setQuorumVotesBPS: admin only');
require(
newQuorumVotesBPS >= MIN_QUORUM_VOTES_BPS && newQuorumVotesBPS <= MAX_QUORUM_VOTES_BPS,
'NounsDAO::_setProposalThreshold: invalid proposal threshold'
);
uint256 oldQuorumVotesBPS = quorumVotesBPS;
quorumVotesBPS = newQuorumVotesBPS;
emit QuorumVotesBPSSet(oldQuorumVotesBPS, quorumVotesBPS);
}
/**
* @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.
* @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.
* @param newPendingAdmin New pending admin.
*/
function _setPendingAdmin(address newPendingAdmin) external {
// Check caller = admin
require(msg.sender == admin, 'NounsDAO::_setPendingAdmin: admin only');
// Save current value, if any, for inclusion in log
address oldPendingAdmin = pendingAdmin;
// Store pendingAdmin with value newPendingAdmin
pendingAdmin = newPendingAdmin;
// Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)
emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);
}
/**
* @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin
* @dev Admin function for pending admin to accept role and update admin
*/
function _acceptAdmin() external {
// Check caller is pendingAdmin and pendingAdmin ≠ address(0)
require(msg.sender == pendingAdmin && msg.sender != address(0), 'NounsDAO::_acceptAdmin: pending admin only');
// Save current values for inclusion in log
address oldAdmin = admin;
address oldPendingAdmin = pendingAdmin;
// Store admin with value pendingAdmin
admin = pendingAdmin;
// Clear the pending value
pendingAdmin = address(0);
emit NewAdmin(oldAdmin, admin);
emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);
}
/**
* @notice Changes vetoer address
* @dev Vetoer function for updating vetoer address
*/
function _setVetoer(address newVetoer) public {
require(msg.sender == vetoer, 'NounsDAO::_setVetoer: vetoer only');
emit NewVetoer(vetoer, newVetoer);
vetoer = newVetoer;
}
/**
* @notice Burns veto priviledges
* @dev Vetoer function destroying veto power forever
*/
function _burnVetoPower() public {
// Check caller is pendingAdmin and pendingAdmin ≠ address(0)
require(msg.sender == vetoer, 'NounsDAO::_burnVetoPower: vetoer only');
_setVetoer(address(0));
}
/**
* @notice Current proposal threshold using Noun Total Supply
* Differs from `GovernerBravo` which uses fixed amount
*/
function proposalThreshold() public view returns (uint256) {
return bps2Uint(proposalThresholdBPS, nouns.totalSupply());
}
/**
* @notice Current quorum votes using Noun Total Supply
* Differs from `GovernerBravo` which uses fixed amount
*/
function quorumVotes() public view returns (uint256) {
return bps2Uint(quorumVotesBPS, nouns.totalSupply());
}
function bps2Uint(uint256 bps, uint256 number) internal pure returns (uint256) {
return (number * bps) / 10000;
}
function getChainIdInternal() internal view returns (uint256) {
uint256 chainId;
assembly {
chainId := chainid()
}
return chainId;
}
}
// SPDX-License-Identifier: BSD-3-Clause
/// @title Nouns DAO Logic interfaces and events
/*********************************
* ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
* ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
* ░░░░░░█████████░░█████████░░░ *
* ░░░░░░██░░░████░░██░░░████░░░ *
* ░░██████░░░████████░░░████░░░ *
* ░░██░░██░░░████░░██░░░████░░░ *
* ░░██░░██░░░████░░██░░░████░░░ *
* ░░░░░░█████████░░█████████░░░ *
* ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
* ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
*********************************/
// LICENSE
// NounsDAOInterfaces.sol is a modified version of Compound Lab's GovernorBravoInterfaces.sol:
// https://github.com/compound-finance/compound-protocol/blob/b9b14038612d846b83f8a009a82c38974ff2dcfe/contracts/Governance/GovernorBravoInterfaces.sol
//
// GovernorBravoInterfaces.sol source code Copyright 2020 Compound Labs, Inc. licensed under the BSD-3-Clause license.
// With modifications by Nounders DAO.
//
// Additional conditions of BSD-3-Clause can be found here: https://opensource.org/licenses/BSD-3-Clause
//
// MODIFICATIONS
// NounsDAOEvents, NounsDAOProxyStorage, NounsDAOStorageV1 adds support for changes made by Nouns DAO to GovernorBravo.sol
// See NounsDAOLogicV1.sol for more details.
pragma solidity ^0.8.6;
contract NounsDAOEvents {
/// @notice An event emitted when a new proposal is created
event ProposalCreated(
uint256 id,
address proposer,
address[] targets,
uint256[] values,
string[] signatures,
bytes[] calldatas,
uint256 startBlock,
uint256 endBlock,
string description
);
event ProposalCreatedWithRequirements(
uint256 id,
address proposer,
address[] targets,
uint256[] values,
string[] signatures,
bytes[] calldatas,
uint256 startBlock,
uint256 endBlock,
uint256 proposalThreshold,
uint256 quorumVotes,
string description
);
/// @notice An event emitted when a vote has been cast on a proposal
/// @param voter The address which casted a vote
/// @param proposalId The proposal id which was voted on
/// @param support Support value for the vote. 0=against, 1=for, 2=abstain
/// @param votes Number of votes which were cast by the voter
/// @param reason The reason given for the vote by the voter
event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 votes, string reason);
/// @notice An event emitted when a proposal has been canceled
event ProposalCanceled(uint256 id);
/// @notice An event emitted when a proposal has been queued in the NounsDAOExecutor
event ProposalQueued(uint256 id, uint256 eta);
/// @notice An event emitted when a proposal has been executed in the NounsDAOExecutor
event ProposalExecuted(uint256 id);
/// @notice An event emitted when a proposal has been vetoed by vetoAddress
event ProposalVetoed(uint256 id);
/// @notice An event emitted when the voting delay is set
event VotingDelaySet(uint256 oldVotingDelay, uint256 newVotingDelay);
/// @notice An event emitted when the voting period is set
event VotingPeriodSet(uint256 oldVotingPeriod, uint256 newVotingPeriod);
/// @notice Emitted when implementation is changed
event NewImplementation(address oldImplementation, address newImplementation);
/// @notice Emitted when proposal threshold basis points is set
event ProposalThresholdBPSSet(uint256 oldProposalThresholdBPS, uint256 newProposalThresholdBPS);
/// @notice Emitted when quorum votes basis points is set
event QuorumVotesBPSSet(uint256 oldQuorumVotesBPS, uint256 newQuorumVotesBPS);
/// @notice Emitted when pendingAdmin is changed
event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);
/// @notice Emitted when pendingAdmin is accepted, which means admin is updated
event NewAdmin(address oldAdmin, address newAdmin);
/// @notice Emitted when vetoer is changed
event NewVetoer(address oldVetoer, address newVetoer);
}
contract NounsDAOProxyStorage {
/// @notice Administrator for this contract
address public admin;
/// @notice Pending administrator for this contract
address public pendingAdmin;
/// @notice Active brains of Governor
address public implementation;
}
/**
* @title Storage for Governor Bravo Delegate
* @notice For future upgrades, do not change NounsDAOStorageV1. Create a new
* contract which implements NounsDAOStorageV1 and following the naming convention
* NounsDAOStorageVX.
*/
contract NounsDAOStorageV1 is NounsDAOProxyStorage {
/// @notice Vetoer who has the ability to veto any proposal
address public vetoer;
/// @notice The delay before voting on a proposal may take place, once proposed, in blocks
uint256 public votingDelay;
/// @notice The duration of voting on a proposal, in blocks
uint256 public votingPeriod;
/// @notice The basis point number of votes required in order for a voter to become a proposer. *DIFFERS from GovernerBravo
uint256 public proposalThresholdBPS;
/// @notice The basis point number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed. *DIFFERS from GovernerBravo
uint256 public quorumVotesBPS;
/// @notice The total number of proposals
uint256 public proposalCount;
/// @notice The address of the Nouns DAO Executor NounsDAOExecutor
INounsDAOExecutor public timelock;
/// @notice The address of the Nouns tokens
NounsTokenLike public nouns;
/// @notice The official record of all proposals ever proposed
mapping(uint256 => Proposal) public proposals;
/// @notice The latest proposal for each proposer
mapping(address => uint256) public latestProposalIds;
struct Proposal {
/// @notice Unique id for looking up a proposal
uint256 id;
/// @notice Creator of the proposal
address proposer;
/// @notice The number of votes needed to create a proposal at the time of proposal creation. *DIFFERS from GovernerBravo
uint256 proposalThreshold;
/// @notice The number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed at the time of proposal creation. *DIFFERS from GovernerBravo
uint256 quorumVotes;
/// @notice The timestamp that the proposal will be available for execution, set once the vote succeeds
uint256 eta;
/// @notice the ordered list of target addresses for calls to be made
address[] targets;
/// @notice The ordered list of values (i.e. msg.value) to be passed to the calls to be made
uint256[] values;
/// @notice The ordered list of function signatures to be called
string[] signatures;
/// @notice The ordered list of calldata to be passed to each call
bytes[] calldatas;
/// @notice The block at which voting begins: holders must delegate their votes prior to this block
uint256 startBlock;
/// @notice The block at which voting ends: votes must be cast prior to this block
uint256 endBlock;
/// @notice Current number of votes in favor of this proposal
uint256 forVotes;
/// @notice Current number of votes in opposition to this proposal
uint256 againstVotes;
/// @notice Current number of votes for abstaining for this proposal
uint256 abstainVotes;
/// @notice Flag marking whether the proposal has been canceled
bool canceled;
/// @notice Flag marking whether the proposal has been vetoed
bool vetoed;
/// @notice Flag marking whether the proposal has been executed
bool executed;
/// @notice Receipts of ballots for the entire set of voters
mapping(address => Receipt) receipts;
}
/// @notice Ballot receipt record for a voter
struct Receipt {
/// @notice Whether or not a vote has been cast
bool hasVoted;
/// @notice Whether or not the voter supports the proposal or abstains
uint8 support;
/// @notice The number of votes the voter had, which were cast
uint96 votes;
}
/// @notice Possible states that a proposal may be in
enum ProposalState {
Pending,
Active,
Canceled,
Defeated,
Succeeded,
Queued,
Expired,
Executed,
Vetoed
}
}
interface INounsDAOExecutor {
function delay() external view returns (uint256);
function GRACE_PERIOD() external view returns (uint256);
function acceptAdmin() external;
function queuedTransactions(bytes32 hash) external view returns (bool);
function queueTransaction(
address target,
uint256 value,
string calldata signature,
bytes calldata data,
uint256 eta
) external returns (bytes32);
function cancelTransaction(
address target,
uint256 value,
string calldata signature,
bytes calldata data,
uint256 eta
) external;
function executeTransaction(
address target,
uint256 value,
string calldata signature,
bytes calldata data,
uint256 eta
) external payable returns (bytes memory);
}
interface NounsTokenLike {
function getPriorVotes(address account, uint256 blockNumber) external view returns (uint96);
function totalSupply() external view returns (uint96);
}
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"NewAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldImplementation","type":"address"},{"indexed":false,"internalType":"address","name":"newImplementation","type":"address"}],"name":"NewImplementation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldPendingAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newPendingAdmin","type":"address"}],"name":"NewPendingAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldVetoer","type":"address"},{"indexed":false,"internalType":"address","name":"newVetoer","type":"address"}],"name":"NewVetoer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"ProposalCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"address","name":"proposer","type":"address"},{"indexed":false,"internalType":"address[]","name":"targets","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"},{"indexed":false,"internalType":"string[]","name":"signatures","type":"string[]"},{"indexed":false,"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"indexed":false,"internalType":"uint256","name":"startBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endBlock","type":"uint256"},{"indexed":false,"internalType":"string","name":"description","type":"string"}],"name":"ProposalCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"address","name":"proposer","type":"address"},{"indexed":false,"internalType":"address[]","name":"targets","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"},{"indexed":false,"internalType":"string[]","name":"signatures","type":"string[]"},{"indexed":false,"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"indexed":false,"internalType":"uint256","name":"startBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"proposalThreshold","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"quorumVotes","type":"uint256"},{"indexed":false,"internalType":"string","name":"description","type":"string"}],"name":"ProposalCreatedWithRequirements","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"ProposalExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"eta","type":"uint256"}],"name":"ProposalQueued","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldProposalThresholdBPS","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newProposalThresholdBPS","type":"uint256"}],"name":"ProposalThresholdBPSSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"ProposalVetoed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldQuorumVotesBPS","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newQuorumVotesBPS","type":"uint256"}],"name":"QuorumVotesBPSSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"support","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"votes","type":"uint256"},{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"VoteCast","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldVotingDelay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newVotingDelay","type":"uint256"}],"name":"VotingDelaySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldVotingPeriod","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newVotingPeriod","type":"uint256"}],"name":"VotingPeriodSet","type":"event"},{"inputs":[],"name":"BALLOT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PROPOSAL_THRESHOLD_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_QUORUM_VOTES_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_VOTING_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_VOTING_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_PROPOSAL_THRESHOLD_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_QUORUM_VOTES_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_VOTING_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_VOTING_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_acceptAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"_burnVetoPower","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPendingAdmin","type":"address"}],"name":"_setPendingAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newProposalThresholdBPS","type":"uint256"}],"name":"_setProposalThresholdBPS","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newQuorumVotesBPS","type":"uint256"}],"name":"_setQuorumVotesBPS","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newVetoer","type":"address"}],"name":"_setVetoer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newVotingDelay","type":"uint256"}],"name":"_setVotingDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newVotingPeriod","type":"uint256"}],"name":"_setVotingPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"cancel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"}],"name":"castVote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"castVoteBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"string","name":"reason","type":"string"}],"name":"castVoteWithReason","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"execute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"getActions","outputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"string[]","name":"signatures","type":"string[]"},{"internalType":"bytes[]","name":"calldatas","type":"bytes[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"address","name":"voter","type":"address"}],"name":"getReceipt","outputs":[{"components":[{"internalType":"bool","name":"hasVoted","type":"bool"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"uint96","name":"votes","type":"uint96"}],"internalType":"struct NounsDAOStorageV1.Receipt","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"timelock_","type":"address"},{"internalType":"address","name":"nouns_","type":"address"},{"internalType":"address","name":"vetoer_","type":"address"},{"internalType":"uint256","name":"votingPeriod_","type":"uint256"},{"internalType":"uint256","name":"votingDelay_","type":"uint256"},{"internalType":"uint256","name":"proposalThresholdBPS_","type":"uint256"},{"internalType":"uint256","name":"quorumVotesBPS_","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"latestProposalIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nouns","outputs":[{"internalType":"contract NounsTokenLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposalCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposalMaxOperations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposalThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposalThresholdBPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proposals","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint256","name":"proposalThreshold","type":"uint256"},{"internalType":"uint256","name":"quorumVotes","type":"uint256"},{"internalType":"uint256","name":"eta","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"internalType":"uint256","name":"forVotes","type":"uint256"},{"internalType":"uint256","name":"againstVotes","type":"uint256"},{"internalType":"uint256","name":"abstainVotes","type":"uint256"},{"internalType":"bool","name":"canceled","type":"bool"},{"internalType":"bool","name":"vetoed","type":"bool"},{"internalType":"bool","name":"executed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"string[]","name":"signatures","type":"string[]"},{"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"internalType":"string","name":"description","type":"string"}],"name":"propose","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"queue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"quorumVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quorumVotesBPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"state","outputs":[{"internalType":"enum NounsDAOStorageV1.ProposalState","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timelock","outputs":[{"internalType":"contract INounsDAOExecutor","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"veto","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vetoer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"NewAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldImplementation","type":"address"},{"indexed":false,"internalType":"address","name":"newImplementation","type":"address"}],"name":"NewImplementation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldPendingAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newPendingAdmin","type":"address"}],"name":"NewPendingAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldVetoer","type":"address"},{"indexed":false,"internalType":"address","name":"newVetoer","type":"address"}],"name":"NewVetoer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"ProposalCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"address","name":"proposer","type":"address"},{"indexed":false,"internalType":"address[]","name":"targets","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"},{"indexed":false,"internalType":"string[]","name":"signatures","type":"string[]"},{"indexed":false,"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"indexed":false,"internalType":"uint256","name":"startBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endBlock","type":"uint256"},{"indexed":false,"internalType":"string","name":"description","type":"string"}],"name":"ProposalCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"address","name":"proposer","type":"address"},{"indexed":false,"internalType":"address[]","name":"targets","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"},{"indexed":false,"internalType":"string[]","name":"signatures","type":"string[]"},{"indexed":false,"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"indexed":false,"internalType":"uint256","name":"startBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"proposalThreshold","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"quorumVotes","type":"uint256"},{"indexed":false,"internalType":"string","name":"description","type":"string"}],"name":"ProposalCreatedWithRequirements","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"ProposalExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"eta","type":"uint256"}],"name":"ProposalQueued","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldProposalThresholdBPS","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newProposalThresholdBPS","type":"uint256"}],"name":"ProposalThresholdBPSSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"ProposalVetoed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldQuorumVotesBPS","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newQuorumVotesBPS","type":"uint256"}],"name":"QuorumVotesBPSSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"support","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"votes","type":"uint256"},{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"VoteCast","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldVotingDelay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newVotingDelay","type":"uint256"}],"name":"VotingDelaySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldVotingPeriod","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newVotingPeriod","type":"uint256"}],"name":"VotingPeriodSet","type":"event"},{"inputs":[],"name":"BALLOT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PROPOSAL_THRESHOLD_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_QUORUM_VOTES_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_VOTING_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_VOTING_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_PROPOSAL_THRESHOLD_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_QUORUM_VOTES_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_VOTING_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_VOTING_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_acceptAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"_burnVetoPower","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPendingAdmin","type":"address"}],"name":"_setPendingAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newProposalThresholdBPS","type":"uint256"}],"name":"_setProposalThresholdBPS","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newQuorumVotesBPS","type":"uint256"}],"name":"_setQuorumVotesBPS","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newVetoer","type":"address"}],"name":"_setVetoer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newVotingDelay","type":"uint256"}],"name":"_setVotingDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newVotingPeriod","type":"uint256"}],"name":"_setVotingPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"cancel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"}],"name":"castVote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"castVoteBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"string","name":"reason","type":"string"}],"name":"castVoteWithReason","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"execute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"getActions","outputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"string[]","name":"signatures","type":"string[]"},{"internalType":"bytes[]","name":"calldatas","type":"bytes[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"address","name":"voter","type":"address"}],"name":"getReceipt","outputs":[{"components":[{"internalType":"bool","name":"hasVoted","type":"bool"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"uint96","name":"votes","type":"uint96"}],"internalType":"struct NounsDAOStorageV1.Receipt","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"timelock_","type":"address"},{"internalType":"address","name":"nouns_","type":"address"},{"internalType":"address","name":"vetoer_","type":"address"},{"internalType":"uint256","name":"votingPeriod_","type":"uint256"},{"internalType":"uint256","name":"votingDelay_","type":"uint256"},{"internalType":"uint256","name":"proposalThresholdBPS_","type":"uint256"},{"internalType":"uint256","name":"quorumVotesBPS_","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"latestProposalIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nouns","outputs":[{"internalType":"contract NounsTokenLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposalCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposalMaxOperations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposalThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposalThresholdBPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proposals","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint256","name":"proposalThreshold","type":"uint256"},{"internalType":"uint256","name":"quorumVotes","type":"uint256"},{"internalType":"uint256","name":"eta","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"internalType":"uint256","name":"forVotes","type":"uint256"},{"internalType":"uint256","name":"againstVotes","type":"uint256"},{"internalType":"uint256","name":"abstainVotes","type":"uint256"},{"internalType":"bool","name":"canceled","type":"bool"},{"internalType":"bool","name":"vetoed","type":"bool"},{"internalType":"bool","name":"executed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"string[]","name":"signatures","type":"string[]"},{"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"internalType":"string","name":"description","type":"string"}],"name":"propose","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"queue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"quorumVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quorumVotesBPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"state","outputs":[{"internalType":"enum NounsDAOStorageV1.ProposalState","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timelock","outputs":[{"internalType":"contract INounsDAOExecutor","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"veto","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vetoer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
608060405234801561001057600080fd5b506147b3806100206000396000f3fe608060405234801561001057600080fd5b50600436106103155760003560e01c80636f3eff28116101a7578063c82fbd08116100ee578063deaaa7cc11610097578063e9c714f211610071578063e9c714f2146107f2578063f851a440146107fa578063fe0d94c11461080d57600080fd5b8063deaaa7cc14610704578063e23a9a521461072b578063e48083fe146106a757600080fd5b8063da35c664116100c8578063da35c664146106d5578063da95691a146106de578063ddf0b009146106f157600080fd5b8063c82fbd08146106a7578063d33219b4146106af578063d8bff440146106c257600080fd5b8063a64e024a11610150578063b71d1a0c1161012a578063b71d1a0c14610683578063bb67758214610696578063bf7a29631461069f57600080fd5b8063a64e024a14610668578063b112626314610672578063b58131b01461067b57600080fd5b806383cce0e11161018157806383cce0e11461063957806396300b7d1461064257806397d048e51461065557600080fd5b80636f3eff281461060b5780637b3c71d31461061e5780637bdbe4d01461063157600080fd5b80632230e1551161026b5780633932abb11161021457806340e58ee5116101ee57806340e58ee5146105d257806356781388146105e55780635c60da1b146105f857600080fd5b80633932abb1146105965780633bccf4fd1461059f5780633e4f49e6146105b257600080fd5b80632b4656c8116102455780632b4656c81461054d5780632de45f1814610560578063328dd9821461057357600080fd5b80632230e1551461051257806324bc1a641461051a578063267822471461052257600080fd5b806317977c61116102cd5780631e7b5d3a116102a75780631e7b5d3a146104d957806320606b70146104e2578063215809ca1461050957600080fd5b806317977c61146104935780631d28dec7146104b35780631dfb1b5a146104c657600080fd5b806306fdde03116102fe57806306fdde031461042c5780630ea2d98c1461047557806314a67ea41461048a57600080fd5b8063013cf08b1461031a57806302a251a314610415575b600080fd5b6103a0610328366004613eea565b600b602081905260009182526040909120805460018201546002830154600384015460048501546009860154600a87015497870154600c880154600d890154600e9099015497996001600160a01b039097169895979496939592949192909160ff80821691610100810482169162010000909104168d565b604080519d8e526001600160a01b03909c1660208e01529a8c019990995260608b019790975260808a019590955260a089019390935260c088019190915260e08701526101008601526101208501521515610140840152151561016083015215156101808201526101a0015b60405180910390f35b61041e60055481565b60405190815260200161040c565b6104686040518060400160405280600981526020017f4e6f756e732044414f000000000000000000000000000000000000000000000081525081565b60405161040c9190614342565b610488610483366004613eea565b610820565b005b61041e60065481565b61041e6104a1366004613ce3565b600c6020526000908152604090205481565b6104886104c1366004613eea565b610972565b6104886104d4366004613eea565b610c62565b61041e6103e881565b61041e7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b61041e61168081565b61041e60c881565b61041e610da5565b600154610535906001600160a01b031681565b6040516001600160a01b03909116815260200161040c565b61048861055b366004613cfe565b610e4b565b600a54610535906001600160a01b031681565b610586610581366004613eea565b61138c565b60405161040c94939291906142a9565b61041e60045481565b6104886105ad366004613fd9565b61161d565b6105c56105c0366004613eea565b6118ce565b60405161040c9190614301565b6104886105e0366004613eea565b611abb565b6104886105f3366004613f2f565b611e2c565b600254610535906001600160a01b031681565b610488610619366004613eea565b611e9c565b61048861062c366004613f52565b611fdf565b61041e600a81565b61041e60075481565b610488610650366004613ce3565b61202f565b610488610663366004613eea565b612130565b61041e62013b0081565b61041e619d8081565b61041e612273565b610488610691366004613ce3565b6122c9565b61041e6107d081565b6104886123bb565b61041e600181565b600954610535906001600160a01b031681565b600354610535906001600160a01b031681565b61041e60085481565b61041e6106ec366004613d66565b612447565b6104886106ff366004613eea565b612b87565b61041e7f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f81565b6107bd610739366004613f03565b6040805160608101825260008082526020820181905291810191909152506000918252600b602090815260408084206001600160a01b03939093168452600f9092018152918190208151606081018352905460ff8082161515835261010082041693820193909352620100009092046bffffffffffffffffffffffff169082015290565b6040805182511515815260208084015160ff1690820152918101516bffffffffffffffffffffffff169082015260600161040c565b610488612ed3565b600054610535906001600160a01b031681565b61048861081b366004613eea565b613024565b6000546001600160a01b031633146108a55760405162461bcd60e51b815260206004820152602660248201527f4e6f756e7344414f3a3a5f736574566f74696e67506572696f643a2061646d6960448201527f6e206f6e6c79000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61168081101580156108ba575062013b008111155b61092c5760405162461bcd60e51b815260206004820152603160248201527f4e6f756e7344414f3a3a5f736574566f74696e67506572696f643a20696e766160448201527f6c696420766f74696e6720706572696f64000000000000000000000000000000606482015260840161089c565b600580549082905560408051828152602081018490527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e882891015b60405180910390a15050565b6003546001600160a01b03166109f05760405162461bcd60e51b815260206004820152602160248201527f4e6f756e7344414f3a3a7665746f3a207665746f20706f776572206275726e6560448201527f6400000000000000000000000000000000000000000000000000000000000000606482015260840161089c565b6003546001600160a01b03163314610a4a5760405162461bcd60e51b815260206004820152601b60248201527f4e6f756e7344414f3a3a7665746f3a206f6e6c79207665746f65720000000000604482015260640161089c565b6007610a55826118ce565b6008811115610a6657610a666146f0565b1415610ada5760405162461bcd60e51b815260206004820152602d60248201527f4e6f756e7344414f3a3a7665746f3a2063616e6e6f74207665746f206578656360448201527f757465642070726f706f73616c00000000000000000000000000000000000000606482015260840161089c565b6000818152600b60205260408120600e810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055905b6005820154811015610c31576009546005830180546001600160a01b039092169163591fcdfe919084908110610b5057610b5061471f565b6000918252602090912001546006850180546001600160a01b039092169185908110610b7e57610b7e61471f565b9060005260206000200154856007018581548110610b9e57610b9e61471f565b90600052602060002001866008018681548110610bbd57610bbd61471f565b9060005260206000200187600401546040518663ffffffff1660e01b8152600401610bec95949392919061426f565b600060405180830381600087803b158015610c0657600080fd5b505af1158015610c1a573d6000803e3d6000fd5b505050508080610c2990614688565b915050610b18565b506040518281527fde0cea2a3a0097cc3d981d40c375407760e85bc9c5e69aea449ac3885f8615c690602001610966565b6000546001600160a01b03163314610ce25760405162461bcd60e51b815260206004820152602560248201527f4e6f756e7344414f3a3a5f736574566f74696e6744656c61793a2061646d696e60448201527f206f6e6c79000000000000000000000000000000000000000000000000000000606482015260840161089c565b60018110158015610cf55750619d808111155b610d675760405162461bcd60e51b815260206004820152602f60248201527f4e6f756e7344414f3a3a5f736574566f74696e6744656c61793a20696e76616c60448201527f696420766f74696e672064656c61790000000000000000000000000000000000606482015260840161089c565b600480549082905560408051828152602081018490527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a939101610966565b6000610e46600754600a60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dfb57600080fd5b505afa158015610e0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e339190614027565b6bffffffffffffffffffffffff16613262565b905090565b6009546001600160a01b031615610eca5760405162461bcd60e51b815260206004820152602e60248201527f4e6f756e7344414f3a3a696e697469616c697a653a2063616e206f6e6c79206960448201527f6e697469616c697a65206f6e6365000000000000000000000000000000000000606482015260840161089c565b6000546001600160a01b03163314610f245760405162461bcd60e51b815260206004820181905260248201527f4e6f756e7344414f3a3a696e697469616c697a653a2061646d696e206f6e6c79604482015260640161089c565b6001600160a01b038716610fa05760405162461bcd60e51b815260206004820152602e60248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c696420746960448201527f6d656c6f636b2061646472657373000000000000000000000000000000000000606482015260840161089c565b6001600160a01b03861661101c5760405162461bcd60e51b815260206004820152602b60248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c6964206e6f60448201527f756e732061646472657373000000000000000000000000000000000000000000606482015260840161089c565b6116808410158015611031575062013b008411155b6110a35760405162461bcd60e51b815260206004820152602b60248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c696420766f60448201527f74696e6720706572696f64000000000000000000000000000000000000000000606482015260840161089c565b600183101580156110b65750619d808311155b6111285760405162461bcd60e51b815260206004820152602a60248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c696420766f60448201527f74696e672064656c617900000000000000000000000000000000000000000000606482015260840161089c565b6001821015801561113b57506103e88211155b6111ad5760405162461bcd60e51b815260206004820152603060248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c696420707260448201527f6f706f73616c207468726573686f6c6400000000000000000000000000000000606482015260840161089c565b60c881101580156111c057506107d08111155b6112325760405162461bcd60e51b815260206004820152603060248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c696420707260448201527f6f706f73616c207468726573686f6c6400000000000000000000000000000000606482015260840161089c565b60055460408051918252602082018690527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e8828910160405180910390a160045460408051918252602082018590527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a93910160405180910390a160065460408051918252602082018490527ffc216faa269bf440fb06aa490693f409461bde9cdcb949c7b9f2cb79589e7a58910160405180910390a160075460408051918252602082018390527fd73ab1b53ca7a080713bcecd1a0acb2066a6a6c3d2fd6d78b67ae5005e652d9b910160405180910390a1600980547fffffffffffffffffffffffff00000000000000000000000000000000000000009081166001600160a01b03998a1617909155600a8054821697891697909717909655600380549096169490961693909317909355600555600491909155600655600755565b6060806060806000600b60008781526020019081526020016000209050806005018160060182600701836008018380548060200260200160405190810160405280929190818152602001828054801561140e57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116113f0575b505050505093508280548060200260200160405190810160405280929190818152602001828054801561146057602002820191906000526020600020905b81548152602001906001019080831161144c575b5050505050925081805480602002602001604051908101604052809291908181526020016000905b828210156115345783829060005260206000200180546114a79061463a565b80601f01602080910402602001604051908101604052809291908181526020018280546114d39061463a565b80156115205780601f106114f557610100808354040283529160200191611520565b820191906000526020600020905b81548152906001019060200180831161150357829003601f168201915b505050505081526020019060010190611488565b50505050915080805480602002602001604051908101604052809291908181526020016000905b8282101561160757838290600052602060002001805461157a9061463a565b80601f01602080910402602001604051908101604052809291908181526020018280546115a69061463a565b80156115f35780601f106115c8576101008083540402835291602001916115f3565b820191906000526020600020905b8154815290600101906020018083116115d657829003601f168201915b50505050508152602001906001019061155b565b5050505090509450945094509450509193509193565b604080518082018252600981527f4e6f756e732044414f000000000000000000000000000000000000000000000060209182015281517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866818301527fe1dd93b3612547b4bb7c3d429f3df8508d84f5a4f63b5e2e44340b94698e6b3b81840152466060820152306080808301919091528351808303909101815260a0820184528051908301207f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f60c083015260e0820189905260ff881661010080840191909152845180840390910181526101208301909452835193909201929092207f19010000000000000000000000000000000000000000000000000000000000006101408401526101428301829052610162830181905290916000906101820160408051601f198184030181528282528051602091820120600080855291840180845281905260ff8a169284019290925260608301889052608083018790529092509060019060a0016020604051602081039080840390855afa1580156117c5573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661184e5760405162461bcd60e51b815260206004820152602a60248201527f4e6f756e7344414f3a3a63617374566f746542795369673a20696e76616c696460448201527f207369676e617475726500000000000000000000000000000000000000000000606482015260840161089c565b806001600160a01b03167fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda48a8a611886858e8e613282565b6040805193845260ff90921660208401526bffffffffffffffffffffffff169082015260806060820181905260009082015260a00160405180910390a2505050505050505050565b60008160085410156119475760405162461bcd60e51b8152602060048201526024808201527f4e6f756e7344414f3a3a73746174653a20696e76616c69642070726f706f736160448201527f6c20696400000000000000000000000000000000000000000000000000000000606482015260840161089c565b6000828152600b60205260409020600e810154610100900460ff16156119705750600892915050565b600e81015460ff16156119865750600292915050565b8060090154431161199a5750600092915050565b80600a015443116119ae5750600192915050565b80600c015481600b01541115806119cc5750806003015481600b0154105b156119da5750600392915050565b60048101546119ec5750600492915050565b600e81015462010000900460ff1615611a085750600792915050565b600960009054906101000a90046001600160a01b03166001600160a01b031663c1a287e26040518163ffffffff1660e01b815260040160206040518083038186803b158015611a5657600080fd5b505afa158015611a6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8e9190613e5a565b8160040154611a9d9190614563565b4210611aac5750600692915050565b50600592915050565b50919050565b6007611ac6826118ce565b6008811115611ad757611ad76146f0565b1415611b4b5760405162461bcd60e51b815260206004820152603160248201527f4e6f756e7344414f3a3a63616e63656c3a2063616e6e6f742063616e63656c2060448201527f65786563757465642070726f706f73616c000000000000000000000000000000606482015260840161089c565b6000818152600b6020526040902060018101546001600160a01b0316331480611c4057506002810154600a546001808401546001600160a01b039283169263782d6fe192911690611b9c90436145f3565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b039092166004830152602482015260440160206040518083038186803b158015611bf857600080fd5b505afa158015611c0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c309190614027565b6bffffffffffffffffffffffff16105b611cb25760405162461bcd60e51b815260206004820152602a60248201527f4e6f756e7344414f3a3a63616e63656c3a2070726f706f7365722061626f766560448201527f207468726573686f6c6400000000000000000000000000000000000000000000606482015260840161089c565b600e810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905560005b6005820154811015611dfb576009546005830180546001600160a01b039092169163591fcdfe919084908110611d1a57611d1a61471f565b6000918252602090912001546006850180546001600160a01b039092169185908110611d4857611d4861471f565b9060005260206000200154856007018581548110611d6857611d6861471f565b90600052602060002001866008018681548110611d8757611d8761471f565b9060005260206000200187600401546040518663ffffffff1660e01b8152600401611db695949392919061426f565b600060405180830381600087803b158015611dd057600080fd5b505af1158015611de4573d6000803e3d6000fd5b505050508080611df390614688565b915050611ce2565b506040518281527f789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c90602001610966565b337fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda48383611e5b848383613282565b6040805193845260ff90921660208401526bffffffffffffffffffffffff169082015260806060820181905260009082015260a00160405180910390a25050565b6000546001600160a01b03163314611f1c5760405162461bcd60e51b815260206004820152602860248201527f4e6f756e7344414f3a3a5f73657451756f72756d566f7465734250533a20616460448201527f6d696e206f6e6c79000000000000000000000000000000000000000000000000606482015260840161089c565b60c88110158015611f2f57506107d08111155b611fa15760405162461bcd60e51b815260206004820152603b60248201527f4e6f756e7344414f3a3a5f73657450726f706f73616c5468726573686f6c643a60448201527f20696e76616c69642070726f706f73616c207468726573686f6c640000000000606482015260840161089c565b600780549082905560408051828152602081018490527fd73ab1b53ca7a080713bcecd1a0acb2066a6a6c3d2fd6d78b67ae5005e652d9b9101610966565b337fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda4858561200e848383613282565b8686604051612021959493929190614491565b60405180910390a250505050565b6003546001600160a01b031633146120af5760405162461bcd60e51b815260206004820152602160248201527f4e6f756e7344414f3a3a5f7365745665746f65723a207665746f6572206f6e6c60448201527f7900000000000000000000000000000000000000000000000000000000000000606482015260840161089c565b600354604080516001600160a01b03928316815291831660208301527fc5644f3588a066b15dcf6b636b74aadca57cfaccf608d9de7d8786364b7a8d02910160405180910390a1600380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6000546001600160a01b031633146121b05760405162461bcd60e51b815260206004820152602e60248201527f4e6f756e7344414f3a3a5f73657450726f706f73616c5468726573686f6c644260448201527f50533a2061646d696e206f6e6c79000000000000000000000000000000000000606482015260840161089c565b600181101580156121c357506103e88111155b6122355760405162461bcd60e51b815260206004820152603b60248201527f4e6f756e7344414f3a3a5f73657450726f706f73616c5468726573686f6c643a60448201527f20696e76616c69642070726f706f73616c207468726573686f6c640000000000606482015260840161089c565b600680549082905560408051828152602081018490527ffc216faa269bf440fb06aa490693f409461bde9cdcb949c7b9f2cb79589e7a589101610966565b6000610e46600654600a60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dfb57600080fd5b6000546001600160a01b031633146123495760405162461bcd60e51b815260206004820152602660248201527f4e6f756e7344414f3a3a5f73657450656e64696e6741646d696e3a2061646d6960448201527f6e206f6e6c790000000000000000000000000000000000000000000000000000606482015260840161089c565b600180546001600160a01b038381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a99101610966565b6003546001600160a01b0316331461243b5760405162461bcd60e51b815260206004820152602560248201527f4e6f756e7344414f3a3a5f6275726e5665746f506f7765723a207665746f657260448201527f206f6e6c79000000000000000000000000000000000000000000000000000000606482015260840161089c565b612445600061202f565b565b600061247b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b600a60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156124c957600080fd5b505afa1580156124dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125019190614027565b6bffffffffffffffffffffffff1680825260065461251e91613262565b60208201819052600a546001600160a01b031663782d6fe1336125426001436145f3565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b039092166004830152602482015260440160206040518083038186803b15801561259e57600080fd5b505afa1580156125b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d69190614027565b6bffffffffffffffffffffffff16116126575760405162461bcd60e51b815260206004820152603a60248201527f4e6f756e7344414f3a3a70726f706f73653a2070726f706f73657220766f746560448201527f732062656c6f772070726f706f73616c207468726573686f6c64000000000000606482015260840161089c565b85518751148015612669575084518751145b8015612676575083518751145b6126e85760405162461bcd60e51b815260206004820152603f60248201527f4e6f756e7344414f3a3a70726f706f73653a2070726f706f73616c2066756e6360448201527f74696f6e20696e666f726d6174696f6e206172697479206d69736d6174636800606482015260840161089c565b865161275c5760405162461bcd60e51b815260206004820152602760248201527f4e6f756e7344414f3a3a70726f706f73653a206d7573742070726f766964652060448201527f616374696f6e7300000000000000000000000000000000000000000000000000606482015260840161089c565b600a875111156127d45760405162461bcd60e51b815260206004820152602360248201527f4e6f756e7344414f3a3a70726f706f73653a20746f6f206d616e79206163746960448201527f6f6e730000000000000000000000000000000000000000000000000000000000606482015260840161089c565b336000908152600c602052604090819020549082018190521561296057600061280082604001516118ce565b90506001816008811115612816576128166146f0565b14156128b05760405162461bcd60e51b815260206004820152605360248201527f4e6f756e7344414f3a3a70726f706f73653a206f6e65206c6976652070726f7060448201527f6f73616c207065722070726f706f7365722c20666f756e6420616e20616c726560648201527f616479206163746976652070726f706f73616c00000000000000000000000000608482015260a40161089c565b60008160088111156128c4576128c46146f0565b141561295e5760405162461bcd60e51b815260206004820152605460248201527f4e6f756e7344414f3a3a70726f706f73653a206f6e65206c6976652070726f7060448201527f6f73616c207065722070726f706f7365722c20666f756e6420616e20616c726560648201527f6164792070656e64696e672070726f706f73616c000000000000000000000000608482015260a40161089c565b505b60045461296d9043614563565b6060820181905260055461298091614563565b60808201526008805490600061299583614688565b90915550506008546000818152600b602090815260409091209182556001820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001633179055820151600282015560075482516129f49190613262565b6003820155600060048201558751612a1590600583019060208b01906137f1565b508651612a2b90600683019060208a019061386e565b508551612a4190600783019060208901906138a9565b508451612a579060088301906020880190613902565b506060820151600982019081556080830151600a83019081556000600b8401819055600c808501829055600d8501829055600e850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000169055845460018601546001600160a01b031683526020919091526040918290208190559254915490517f7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e093612b1493909233928e928e928e928e9291908e90614355565b60405180910390a17f6af0134faa0f9290c1d686d55012aca80302d31d5c856e4bc7954f7613dc7f878160000154338a8a8a8a876009015488600a015489600201548a600301548e604051612b739b9a999897969594939291906143eb565b60405180910390a154979650505050505050565b6004612b92826118ce565b6008811115612ba357612ba36146f0565b14612c165760405162461bcd60e51b815260206004820152603f60248201527f4e6f756e7344414f3a3a71756575653a2070726f706f73616c2063616e206f6e60448201527f6c79206265207175657565642069662069742069732073756363656564656400606482015260840161089c565b6000818152600b6020908152604080832060095482517f6a42b8f800000000000000000000000000000000000000000000000000000000815292519194936001600160a01b0390911692636a42b8f89260048083019392829003018186803b158015612c8157600080fd5b505afa158015612c95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb99190613e5a565b612cc39042614563565b905060005b6005830154811015612e8d57612e7b836005018281548110612cec57612cec61471f565b6000918252602090912001546006850180546001600160a01b039092169184908110612d1a57612d1a61471f565b9060005260206000200154856007018481548110612d3a57612d3a61471f565b906000526020600020018054612d4f9061463a565b80601f0160208091040260200160405190810160405280929190818152602001828054612d7b9061463a565b8015612dc85780601f10612d9d57610100808354040283529160200191612dc8565b820191906000526020600020905b815481529060010190602001808311612dab57829003601f168201915b5050505050866008018581548110612de257612de261471f565b906000526020600020018054612df79061463a565b80601f0160208091040260200160405190810160405280929190818152602001828054612e239061463a565b8015612e705780601f10612e4557610100808354040283529160200191612e70565b820191906000526020600020905b815481529060010190602001808311612e5357829003601f168201915b5050505050866135fb565b80612e8581614688565b915050612cc8565b506004820181905560408051848152602081018390527f9a2e42fd6722813d69113e7d0079d3d940171428df7373df9c7f7617cfda2892910160405180910390a1505050565b6001546001600160a01b031633148015612eec57503315155b612f5e5760405162461bcd60e51b815260206004820152602a60248201527f4e6f756e7344414f3a3a5f61636365707441646d696e3a2070656e64696e672060448201527f61646d696e206f6e6c7900000000000000000000000000000000000000000000606482015260840161089c565b60008054600180546001600160a01b038082167fffffffffffffffffffffffff000000000000000000000000000000000000000080861682179096559490911690915560408051919092168082526020820184905292917ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc910160405180910390a1600154604080516001600160a01b03808516825290921660208301527fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a99101610966565b600561302f826118ce565b6008811115613040576130406146f0565b146130b5576040805162461bcd60e51b81526020600482015260248101919091527f4e6f756e7344414f3a3a657865637574653a2070726f706f73616c2063616e2060448201527f6f6e6c7920626520657865637574656420696620697420697320717565756564606482015260840161089c565b6000818152600b60205260408120600e810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff1662010000179055905b6005820154811015613231576009546005830180546001600160a01b0390921691630825f38f91908490811061312c5761312c61471f565b6000918252602090912001546006850180546001600160a01b03909216918590811061315a5761315a61471f565b906000526020600020015485600701858154811061317a5761317a61471f565b906000526020600020018660080186815481106131995761319961471f565b9060005260206000200187600401546040518663ffffffff1660e01b81526004016131c895949392919061426f565b600060405180830381600087803b1580156131e257600080fd5b505af11580156131f6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261321e9190810190613e73565b508061322981614688565b9150506130f4565b506040518281527f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f90602001610966565b600061271061327184846145b6565b61327b919061457b565b9392505050565b6000600161328f846118ce565b60088111156132a0576132a06146f0565b146133135760405162461bcd60e51b815260206004820152602c60248201527f4e6f756e7344414f3a3a63617374566f7465496e7465726e616c3a20766f746960448201527f6e6720697320636c6f7365640000000000000000000000000000000000000000606482015260840161089c565b60028260ff16111561338d5760405162461bcd60e51b815260206004820152602d60248201527f4e6f756e7344414f3a3a63617374566f7465496e7465726e616c3a20696e766160448201527f6c696420766f7465207479706500000000000000000000000000000000000000606482015260840161089c565b6000838152600b602090815260408083206001600160a01b0388168452600f8101909252909120805460ff161561342c5760405162461bcd60e51b815260206004820152602f60248201527f4e6f756e7344414f3a3a63617374566f7465496e7465726e616c3a20766f746560448201527f7220616c726561647920766f7465640000000000000000000000000000000000606482015260840161089c565b600a5460045460098401546000926001600160a01b03169163782d6fe1918a91613455916145f3565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b039092166004830152602482015260440160206040518083038186803b1580156134b157600080fd5b505afa1580156134c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134e99190614027565b905060ff851661351b57806bffffffffffffffffffffffff1683600c01546135119190614563565b600c84015561357f565b8460ff166001141561354f57806bffffffffffffffffffffffff1683600b01546135459190614563565b600b84015561357f565b8460ff166002141561357f57806bffffffffffffffffffffffff1683600d01546135799190614563565b600d8401555b81546bffffffffffffffffffffffff821662010000027fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff60ff8816610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009093169290921760011791909116179091559150509392505050565b6009546040516001600160a01b039091169063f2b06537906136299088908890889088908890602001614222565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b815260040161365d91815260200190565b60206040518083038186803b15801561367557600080fd5b505afa158015613689573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136ad9190613e38565b156137465760405162461bcd60e51b815260206004820152605060248201527f4e6f756e7344414f3a3a71756575654f72526576657274496e7465726e616c3a60448201527f206964656e746963616c2070726f706f73616c20616374696f6e20616c72656160648201527f6479207175657565642061742065746100000000000000000000000000000000608482015260a40161089c565b6009546040517f3a66f9010000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690633a66f901906137979088908890889088908890600401614222565b602060405180830381600087803b1580156137b157600080fd5b505af11580156137c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137e99190613e5a565b505050505050565b82805482825590600052602060002090810192821561385e579160200282015b8281111561385e57825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909116178255602090920191600190910190613811565b5061386a92915061395b565b5090565b82805482825590600052602060002090810192821561385e579160200282015b8281111561385e57825182559160200191906001019061388e565b8280548282559060005260206000209081019282156138f6579160200282015b828111156138f657825180516138e6918491602090910190613970565b50916020019190600101906138c9565b5061386a9291506139e3565b82805482825590600052602060002090810192821561394f579160200282015b8281111561394f578251805161393f918491602090910190613970565b5091602001919060010190613922565b5061386a929150613a00565b5b8082111561386a576000815560010161395c565b82805461397c9061463a565b90600052602060002090601f01602090048101928261399e576000855561385e565b82601f106139b757805160ff191683800117855561385e565b8280016001018555821561385e579182018281111561385e57825182559160200191906001019061388e565b8082111561386a5760006139f78282613a1d565b506001016139e3565b8082111561386a576000613a148282613a1d565b50600101613a00565b508054613a299061463a565b6000825580601f10613a39575050565b601f016020900490600052602060002090810190613a57919061395b565b50565b6000613a6d613a688461453b565b6144e6565b9050828152838383011115613a8157600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b0381168114613aaf57600080fd5b919050565b600082601f830112613ac557600080fd5b81356020613ad5613a6883614517565b80838252828201915082860187848660051b8901011115613af557600080fd5b60005b85811015613b1b57613b0982613a98565b84529284019290840190600101613af8565b5090979650505050505050565b600082601f830112613b3957600080fd5b81356020613b49613a6883614517565b80838252828201915082860187848660051b8901011115613b6957600080fd5b60005b85811015613b1b57813567ffffffffffffffff811115613b8b57600080fd5b8801603f81018a13613b9c57600080fd5b613bad8a8783013560408401613a5a565b8552509284019290840190600101613b6c565b600082601f830112613bd157600080fd5b81356020613be1613a6883614517565b80838252828201915082860187848660051b8901011115613c0157600080fd5b6000805b86811015613c4457823567ffffffffffffffff811115613c23578283fd5b613c318b88838d0101613cb2565b8652509385019391850191600101613c05565b509198975050505050505050565b600082601f830112613c6357600080fd5b81356020613c73613a6883614517565b80838252828201915082860187848660051b8901011115613c9357600080fd5b60005b85811015613b1b57813584529284019290840190600101613c96565b600082601f830112613cc357600080fd5b61327b83833560208501613a5a565b803560ff81168114613aaf57600080fd5b600060208284031215613cf557600080fd5b61327b82613a98565b600080600080600080600060e0888a031215613d1957600080fd5b613d2288613a98565b9650613d3060208901613a98565b9550613d3e60408901613a98565b969995985095966060810135965060808101359560a0820135955060c0909101359350915050565b600080600080600060a08688031215613d7e57600080fd5b853567ffffffffffffffff80821115613d9657600080fd5b613da289838a01613ab4565b96506020880135915080821115613db857600080fd5b613dc489838a01613c52565b95506040880135915080821115613dda57600080fd5b613de689838a01613bc0565b94506060880135915080821115613dfc57600080fd5b613e0889838a01613b28565b93506080880135915080821115613e1e57600080fd5b50613e2b88828901613cb2565b9150509295509295909350565b600060208284031215613e4a57600080fd5b8151801515811461327b57600080fd5b600060208284031215613e6c57600080fd5b5051919050565b600060208284031215613e8557600080fd5b815167ffffffffffffffff811115613e9c57600080fd5b8201601f81018413613ead57600080fd5b8051613ebb613a688261453b565b818152856020838501011115613ed057600080fd5b613ee182602083016020860161460a565b95945050505050565b600060208284031215613efc57600080fd5b5035919050565b60008060408385031215613f1657600080fd5b82359150613f2660208401613a98565b90509250929050565b60008060408385031215613f4257600080fd5b82359150613f2660208401613cd2565b60008060008060608587031215613f6857600080fd5b84359350613f7860208601613cd2565b9250604085013567ffffffffffffffff80821115613f9557600080fd5b818701915087601f830112613fa957600080fd5b813581811115613fb857600080fd5b886020828501011115613fca57600080fd5b95989497505060200194505050565b600080600080600060a08688031215613ff157600080fd5b8535945061400160208701613cd2565b935061400f60408701613cd2565b94979396509394606081013594506080013592915050565b60006020828403121561403957600080fd5b81516bffffffffffffffffffffffff8116811461327b57600080fd5b600081518084526020808501945080840160005b8381101561408e5781516001600160a01b031687529582019590820190600101614069565b509495945050505050565b600081518084526020808501808196508360051b8101915082860160005b858110156140e15782840389526140cf84835161411e565b988501989350908401906001016140b7565b5091979650505050505050565b600081518084526020808501945080840160005b8381101561408e57815187529582019590820190600101614102565b6000815180845261413681602086016020860161460a565b601f01601f19169290920160200192915050565b8054600090600181811c908083168061416457607f831692505b602080841082141561419f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b8388528180156141b657600181146141e857614216565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008616828a0152604089019650614216565b876000528160002060005b8681101561420e5781548b82018501529085019083016141f3565b8a0183019750505b50505050505092915050565b6001600160a01b038616815284602082015260a06040820152600061424a60a083018661411e565b828103606084015261425c818661411e565b9150508260808301529695505050505050565b6001600160a01b038616815284602082015260a06040820152600061429760a083018661414a565b828103606084015261425c818661414a565b6080815260006142bc6080830187614055565b82810360208401526142ce81876140ee565b905082810360408401526142e28186614099565b905082810360608401526142f68185614099565b979650505050505050565b602081016009831061433c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60208152600061327b602083018461411e565b60006101208b83526001600160a01b038b16602084015280604084015261437e8184018b614055565b90508281036060840152614392818a6140ee565b905082810360808401526143a68189614099565b905082810360a08401526143ba8188614099565b90508560c08401528460e08401528281036101008401526143db818561411e565b9c9b505050505050505050505050565b60006101608d83526001600160a01b038d1660208401528060408401526144148184018d614055565b90508281036060840152614428818c6140ee565b9050828103608084015261443c818b614099565b905082810360a0840152614450818a614099565b90508760c08401528660e0840152856101008401528461012084015282810361014084015261447f818561411e565b9e9d5050505050505050505050505050565b85815260ff851660208201526bffffffffffffffffffffffff8416604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b604051601f8201601f1916810167ffffffffffffffff8111828210171561450f5761450f61474e565b604052919050565b600067ffffffffffffffff8211156145315761453161474e565b5060051b60200190565b600067ffffffffffffffff8211156145555761455561474e565b50601f01601f191660200190565b60008219821115614576576145766146c1565b500190565b6000826145b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156145ee576145ee6146c1565b500290565b600082821015614605576146056146c1565b500390565b60005b8381101561462557818101518382015260200161460d565b83811115614634576000848401525b50505050565b600181811c9082168061464e57607f821691505b60208210811415611ab5577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156146ba576146ba6146c1565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea26469706673582212202d219bbd5982bc04b4820b819396c18d235e46dcc014201d58710c7b14362c2364736f6c63430008060033
608060405234801561001057600080fd5b506147b3806100206000396000f3fe608060405234801561001057600080fd5b50600436106103155760003560e01c80636f3eff28116101a7578063c82fbd08116100ee578063deaaa7cc11610097578063e9c714f211610071578063e9c714f2146107f2578063f851a440146107fa578063fe0d94c11461080d57600080fd5b8063deaaa7cc14610704578063e23a9a521461072b578063e48083fe146106a757600080fd5b8063da35c664116100c8578063da35c664146106d5578063da95691a146106de578063ddf0b009146106f157600080fd5b8063c82fbd08146106a7578063d33219b4146106af578063d8bff440146106c257600080fd5b8063a64e024a11610150578063b71d1a0c1161012a578063b71d1a0c14610683578063bb67758214610696578063bf7a29631461069f57600080fd5b8063a64e024a14610668578063b112626314610672578063b58131b01461067b57600080fd5b806383cce0e11161018157806383cce0e11461063957806396300b7d1461064257806397d048e51461065557600080fd5b80636f3eff281461060b5780637b3c71d31461061e5780637bdbe4d01461063157600080fd5b80632230e1551161026b5780633932abb11161021457806340e58ee5116101ee57806340e58ee5146105d257806356781388146105e55780635c60da1b146105f857600080fd5b80633932abb1146105965780633bccf4fd1461059f5780633e4f49e6146105b257600080fd5b80632b4656c8116102455780632b4656c81461054d5780632de45f1814610560578063328dd9821461057357600080fd5b80632230e1551461051257806324bc1a641461051a578063267822471461052257600080fd5b806317977c61116102cd5780631e7b5d3a116102a75780631e7b5d3a146104d957806320606b70146104e2578063215809ca1461050957600080fd5b806317977c61146104935780631d28dec7146104b35780631dfb1b5a146104c657600080fd5b806306fdde03116102fe57806306fdde031461042c5780630ea2d98c1461047557806314a67ea41461048a57600080fd5b8063013cf08b1461031a57806302a251a314610415575b600080fd5b6103a0610328366004613eea565b600b602081905260009182526040909120805460018201546002830154600384015460048501546009860154600a87015497870154600c880154600d890154600e9099015497996001600160a01b039097169895979496939592949192909160ff80821691610100810482169162010000909104168d565b604080519d8e526001600160a01b03909c1660208e01529a8c019990995260608b019790975260808a019590955260a089019390935260c088019190915260e08701526101008601526101208501521515610140840152151561016083015215156101808201526101a0015b60405180910390f35b61041e60055481565b60405190815260200161040c565b6104686040518060400160405280600981526020017f4e6f756e732044414f000000000000000000000000000000000000000000000081525081565b60405161040c9190614342565b610488610483366004613eea565b610820565b005b61041e60065481565b61041e6104a1366004613ce3565b600c6020526000908152604090205481565b6104886104c1366004613eea565b610972565b6104886104d4366004613eea565b610c62565b61041e6103e881565b61041e7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b61041e61168081565b61041e60c881565b61041e610da5565b600154610535906001600160a01b031681565b6040516001600160a01b03909116815260200161040c565b61048861055b366004613cfe565b610e4b565b600a54610535906001600160a01b031681565b610586610581366004613eea565b61138c565b60405161040c94939291906142a9565b61041e60045481565b6104886105ad366004613fd9565b61161d565b6105c56105c0366004613eea565b6118ce565b60405161040c9190614301565b6104886105e0366004613eea565b611abb565b6104886105f3366004613f2f565b611e2c565b600254610535906001600160a01b031681565b610488610619366004613eea565b611e9c565b61048861062c366004613f52565b611fdf565b61041e600a81565b61041e60075481565b610488610650366004613ce3565b61202f565b610488610663366004613eea565b612130565b61041e62013b0081565b61041e619d8081565b61041e612273565b610488610691366004613ce3565b6122c9565b61041e6107d081565b6104886123bb565b61041e600181565b600954610535906001600160a01b031681565b600354610535906001600160a01b031681565b61041e60085481565b61041e6106ec366004613d66565b612447565b6104886106ff366004613eea565b612b87565b61041e7f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f81565b6107bd610739366004613f03565b6040805160608101825260008082526020820181905291810191909152506000918252600b602090815260408084206001600160a01b03939093168452600f9092018152918190208151606081018352905460ff8082161515835261010082041693820193909352620100009092046bffffffffffffffffffffffff169082015290565b6040805182511515815260208084015160ff1690820152918101516bffffffffffffffffffffffff169082015260600161040c565b610488612ed3565b600054610535906001600160a01b031681565b61048861081b366004613eea565b613024565b6000546001600160a01b031633146108a55760405162461bcd60e51b815260206004820152602660248201527f4e6f756e7344414f3a3a5f736574566f74696e67506572696f643a2061646d6960448201527f6e206f6e6c79000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61168081101580156108ba575062013b008111155b61092c5760405162461bcd60e51b815260206004820152603160248201527f4e6f756e7344414f3a3a5f736574566f74696e67506572696f643a20696e766160448201527f6c696420766f74696e6720706572696f64000000000000000000000000000000606482015260840161089c565b600580549082905560408051828152602081018490527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e882891015b60405180910390a15050565b6003546001600160a01b03166109f05760405162461bcd60e51b815260206004820152602160248201527f4e6f756e7344414f3a3a7665746f3a207665746f20706f776572206275726e6560448201527f6400000000000000000000000000000000000000000000000000000000000000606482015260840161089c565b6003546001600160a01b03163314610a4a5760405162461bcd60e51b815260206004820152601b60248201527f4e6f756e7344414f3a3a7665746f3a206f6e6c79207665746f65720000000000604482015260640161089c565b6007610a55826118ce565b6008811115610a6657610a666146f0565b1415610ada5760405162461bcd60e51b815260206004820152602d60248201527f4e6f756e7344414f3a3a7665746f3a2063616e6e6f74207665746f206578656360448201527f757465642070726f706f73616c00000000000000000000000000000000000000606482015260840161089c565b6000818152600b60205260408120600e810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055905b6005820154811015610c31576009546005830180546001600160a01b039092169163591fcdfe919084908110610b5057610b5061471f565b6000918252602090912001546006850180546001600160a01b039092169185908110610b7e57610b7e61471f565b9060005260206000200154856007018581548110610b9e57610b9e61471f565b90600052602060002001866008018681548110610bbd57610bbd61471f565b9060005260206000200187600401546040518663ffffffff1660e01b8152600401610bec95949392919061426f565b600060405180830381600087803b158015610c0657600080fd5b505af1158015610c1a573d6000803e3d6000fd5b505050508080610c2990614688565b915050610b18565b506040518281527fde0cea2a3a0097cc3d981d40c375407760e85bc9c5e69aea449ac3885f8615c690602001610966565b6000546001600160a01b03163314610ce25760405162461bcd60e51b815260206004820152602560248201527f4e6f756e7344414f3a3a5f736574566f74696e6744656c61793a2061646d696e60448201527f206f6e6c79000000000000000000000000000000000000000000000000000000606482015260840161089c565b60018110158015610cf55750619d808111155b610d675760405162461bcd60e51b815260206004820152602f60248201527f4e6f756e7344414f3a3a5f736574566f74696e6744656c61793a20696e76616c60448201527f696420766f74696e672064656c61790000000000000000000000000000000000606482015260840161089c565b600480549082905560408051828152602081018490527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a939101610966565b6000610e46600754600a60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dfb57600080fd5b505afa158015610e0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e339190614027565b6bffffffffffffffffffffffff16613262565b905090565b6009546001600160a01b031615610eca5760405162461bcd60e51b815260206004820152602e60248201527f4e6f756e7344414f3a3a696e697469616c697a653a2063616e206f6e6c79206960448201527f6e697469616c697a65206f6e6365000000000000000000000000000000000000606482015260840161089c565b6000546001600160a01b03163314610f245760405162461bcd60e51b815260206004820181905260248201527f4e6f756e7344414f3a3a696e697469616c697a653a2061646d696e206f6e6c79604482015260640161089c565b6001600160a01b038716610fa05760405162461bcd60e51b815260206004820152602e60248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c696420746960448201527f6d656c6f636b2061646472657373000000000000000000000000000000000000606482015260840161089c565b6001600160a01b03861661101c5760405162461bcd60e51b815260206004820152602b60248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c6964206e6f60448201527f756e732061646472657373000000000000000000000000000000000000000000606482015260840161089c565b6116808410158015611031575062013b008411155b6110a35760405162461bcd60e51b815260206004820152602b60248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c696420766f60448201527f74696e6720706572696f64000000000000000000000000000000000000000000606482015260840161089c565b600183101580156110b65750619d808311155b6111285760405162461bcd60e51b815260206004820152602a60248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c696420766f60448201527f74696e672064656c617900000000000000000000000000000000000000000000606482015260840161089c565b6001821015801561113b57506103e88211155b6111ad5760405162461bcd60e51b815260206004820152603060248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c696420707260448201527f6f706f73616c207468726573686f6c6400000000000000000000000000000000606482015260840161089c565b60c881101580156111c057506107d08111155b6112325760405162461bcd60e51b815260206004820152603060248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c696420707260448201527f6f706f73616c207468726573686f6c6400000000000000000000000000000000606482015260840161089c565b60055460408051918252602082018690527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e8828910160405180910390a160045460408051918252602082018590527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a93910160405180910390a160065460408051918252602082018490527ffc216faa269bf440fb06aa490693f409461bde9cdcb949c7b9f2cb79589e7a58910160405180910390a160075460408051918252602082018390527fd73ab1b53ca7a080713bcecd1a0acb2066a6a6c3d2fd6d78b67ae5005e652d9b910160405180910390a1600980547fffffffffffffffffffffffff00000000000000000000000000000000000000009081166001600160a01b03998a1617909155600a8054821697891697909717909655600380549096169490961693909317909355600555600491909155600655600755565b6060806060806000600b60008781526020019081526020016000209050806005018160060182600701836008018380548060200260200160405190810160405280929190818152602001828054801561140e57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116113f0575b505050505093508280548060200260200160405190810160405280929190818152602001828054801561146057602002820191906000526020600020905b81548152602001906001019080831161144c575b5050505050925081805480602002602001604051908101604052809291908181526020016000905b828210156115345783829060005260206000200180546114a79061463a565b80601f01602080910402602001604051908101604052809291908181526020018280546114d39061463a565b80156115205780601f106114f557610100808354040283529160200191611520565b820191906000526020600020905b81548152906001019060200180831161150357829003601f168201915b505050505081526020019060010190611488565b50505050915080805480602002602001604051908101604052809291908181526020016000905b8282101561160757838290600052602060002001805461157a9061463a565b80601f01602080910402602001604051908101604052809291908181526020018280546115a69061463a565b80156115f35780601f106115c8576101008083540402835291602001916115f3565b820191906000526020600020905b8154815290600101906020018083116115d657829003601f168201915b50505050508152602001906001019061155b565b5050505090509450945094509450509193509193565b604080518082018252600981527f4e6f756e732044414f000000000000000000000000000000000000000000000060209182015281517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866818301527fe1dd93b3612547b4bb7c3d429f3df8508d84f5a4f63b5e2e44340b94698e6b3b81840152466060820152306080808301919091528351808303909101815260a0820184528051908301207f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f60c083015260e0820189905260ff881661010080840191909152845180840390910181526101208301909452835193909201929092207f19010000000000000000000000000000000000000000000000000000000000006101408401526101428301829052610162830181905290916000906101820160408051601f198184030181528282528051602091820120600080855291840180845281905260ff8a169284019290925260608301889052608083018790529092509060019060a0016020604051602081039080840390855afa1580156117c5573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661184e5760405162461bcd60e51b815260206004820152602a60248201527f4e6f756e7344414f3a3a63617374566f746542795369673a20696e76616c696460448201527f207369676e617475726500000000000000000000000000000000000000000000606482015260840161089c565b806001600160a01b03167fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda48a8a611886858e8e613282565b6040805193845260ff90921660208401526bffffffffffffffffffffffff169082015260806060820181905260009082015260a00160405180910390a2505050505050505050565b60008160085410156119475760405162461bcd60e51b8152602060048201526024808201527f4e6f756e7344414f3a3a73746174653a20696e76616c69642070726f706f736160448201527f6c20696400000000000000000000000000000000000000000000000000000000606482015260840161089c565b6000828152600b60205260409020600e810154610100900460ff16156119705750600892915050565b600e81015460ff16156119865750600292915050565b8060090154431161199a5750600092915050565b80600a015443116119ae5750600192915050565b80600c015481600b01541115806119cc5750806003015481600b0154105b156119da5750600392915050565b60048101546119ec5750600492915050565b600e81015462010000900460ff1615611a085750600792915050565b600960009054906101000a90046001600160a01b03166001600160a01b031663c1a287e26040518163ffffffff1660e01b815260040160206040518083038186803b158015611a5657600080fd5b505afa158015611a6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8e9190613e5a565b8160040154611a9d9190614563565b4210611aac5750600692915050565b50600592915050565b50919050565b6007611ac6826118ce565b6008811115611ad757611ad76146f0565b1415611b4b5760405162461bcd60e51b815260206004820152603160248201527f4e6f756e7344414f3a3a63616e63656c3a2063616e6e6f742063616e63656c2060448201527f65786563757465642070726f706f73616c000000000000000000000000000000606482015260840161089c565b6000818152600b6020526040902060018101546001600160a01b0316331480611c4057506002810154600a546001808401546001600160a01b039283169263782d6fe192911690611b9c90436145f3565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b039092166004830152602482015260440160206040518083038186803b158015611bf857600080fd5b505afa158015611c0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c309190614027565b6bffffffffffffffffffffffff16105b611cb25760405162461bcd60e51b815260206004820152602a60248201527f4e6f756e7344414f3a3a63616e63656c3a2070726f706f7365722061626f766560448201527f207468726573686f6c6400000000000000000000000000000000000000000000606482015260840161089c565b600e810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905560005b6005820154811015611dfb576009546005830180546001600160a01b039092169163591fcdfe919084908110611d1a57611d1a61471f565b6000918252602090912001546006850180546001600160a01b039092169185908110611d4857611d4861471f565b9060005260206000200154856007018581548110611d6857611d6861471f565b90600052602060002001866008018681548110611d8757611d8761471f565b9060005260206000200187600401546040518663ffffffff1660e01b8152600401611db695949392919061426f565b600060405180830381600087803b158015611dd057600080fd5b505af1158015611de4573d6000803e3d6000fd5b505050508080611df390614688565b915050611ce2565b506040518281527f789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c90602001610966565b337fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda48383611e5b848383613282565b6040805193845260ff90921660208401526bffffffffffffffffffffffff169082015260806060820181905260009082015260a00160405180910390a25050565b6000546001600160a01b03163314611f1c5760405162461bcd60e51b815260206004820152602860248201527f4e6f756e7344414f3a3a5f73657451756f72756d566f7465734250533a20616460448201527f6d696e206f6e6c79000000000000000000000000000000000000000000000000606482015260840161089c565b60c88110158015611f2f57506107d08111155b611fa15760405162461bcd60e51b815260206004820152603b60248201527f4e6f756e7344414f3a3a5f73657450726f706f73616c5468726573686f6c643a60448201527f20696e76616c69642070726f706f73616c207468726573686f6c640000000000606482015260840161089c565b600780549082905560408051828152602081018490527fd73ab1b53ca7a080713bcecd1a0acb2066a6a6c3d2fd6d78b67ae5005e652d9b9101610966565b337fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda4858561200e848383613282565b8686604051612021959493929190614491565b60405180910390a250505050565b6003546001600160a01b031633146120af5760405162461bcd60e51b815260206004820152602160248201527f4e6f756e7344414f3a3a5f7365745665746f65723a207665746f6572206f6e6c60448201527f7900000000000000000000000000000000000000000000000000000000000000606482015260840161089c565b600354604080516001600160a01b03928316815291831660208301527fc5644f3588a066b15dcf6b636b74aadca57cfaccf608d9de7d8786364b7a8d02910160405180910390a1600380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6000546001600160a01b031633146121b05760405162461bcd60e51b815260206004820152602e60248201527f4e6f756e7344414f3a3a5f73657450726f706f73616c5468726573686f6c644260448201527f50533a2061646d696e206f6e6c79000000000000000000000000000000000000606482015260840161089c565b600181101580156121c357506103e88111155b6122355760405162461bcd60e51b815260206004820152603b60248201527f4e6f756e7344414f3a3a5f73657450726f706f73616c5468726573686f6c643a60448201527f20696e76616c69642070726f706f73616c207468726573686f6c640000000000606482015260840161089c565b600680549082905560408051828152602081018490527ffc216faa269bf440fb06aa490693f409461bde9cdcb949c7b9f2cb79589e7a589101610966565b6000610e46600654600a60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dfb57600080fd5b6000546001600160a01b031633146123495760405162461bcd60e51b815260206004820152602660248201527f4e6f756e7344414f3a3a5f73657450656e64696e6741646d696e3a2061646d6960448201527f6e206f6e6c790000000000000000000000000000000000000000000000000000606482015260840161089c565b600180546001600160a01b038381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a99101610966565b6003546001600160a01b0316331461243b5760405162461bcd60e51b815260206004820152602560248201527f4e6f756e7344414f3a3a5f6275726e5665746f506f7765723a207665746f657260448201527f206f6e6c79000000000000000000000000000000000000000000000000000000606482015260840161089c565b612445600061202f565b565b600061247b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b600a60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156124c957600080fd5b505afa1580156124dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125019190614027565b6bffffffffffffffffffffffff1680825260065461251e91613262565b60208201819052600a546001600160a01b031663782d6fe1336125426001436145f3565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b039092166004830152602482015260440160206040518083038186803b15801561259e57600080fd5b505afa1580156125b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d69190614027565b6bffffffffffffffffffffffff16116126575760405162461bcd60e51b815260206004820152603a60248201527f4e6f756e7344414f3a3a70726f706f73653a2070726f706f73657220766f746560448201527f732062656c6f772070726f706f73616c207468726573686f6c64000000000000606482015260840161089c565b85518751148015612669575084518751145b8015612676575083518751145b6126e85760405162461bcd60e51b815260206004820152603f60248201527f4e6f756e7344414f3a3a70726f706f73653a2070726f706f73616c2066756e6360448201527f74696f6e20696e666f726d6174696f6e206172697479206d69736d6174636800606482015260840161089c565b865161275c5760405162461bcd60e51b815260206004820152602760248201527f4e6f756e7344414f3a3a70726f706f73653a206d7573742070726f766964652060448201527f616374696f6e7300000000000000000000000000000000000000000000000000606482015260840161089c565b600a875111156127d45760405162461bcd60e51b815260206004820152602360248201527f4e6f756e7344414f3a3a70726f706f73653a20746f6f206d616e79206163746960448201527f6f6e730000000000000000000000000000000000000000000000000000000000606482015260840161089c565b336000908152600c602052604090819020549082018190521561296057600061280082604001516118ce565b90506001816008811115612816576128166146f0565b14156128b05760405162461bcd60e51b815260206004820152605360248201527f4e6f756e7344414f3a3a70726f706f73653a206f6e65206c6976652070726f7060448201527f6f73616c207065722070726f706f7365722c20666f756e6420616e20616c726560648201527f616479206163746976652070726f706f73616c00000000000000000000000000608482015260a40161089c565b60008160088111156128c4576128c46146f0565b141561295e5760405162461bcd60e51b815260206004820152605460248201527f4e6f756e7344414f3a3a70726f706f73653a206f6e65206c6976652070726f7060448201527f6f73616c207065722070726f706f7365722c20666f756e6420616e20616c726560648201527f6164792070656e64696e672070726f706f73616c000000000000000000000000608482015260a40161089c565b505b60045461296d9043614563565b6060820181905260055461298091614563565b60808201526008805490600061299583614688565b90915550506008546000818152600b602090815260409091209182556001820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001633179055820151600282015560075482516129f49190613262565b6003820155600060048201558751612a1590600583019060208b01906137f1565b508651612a2b90600683019060208a019061386e565b508551612a4190600783019060208901906138a9565b508451612a579060088301906020880190613902565b506060820151600982019081556080830151600a83019081556000600b8401819055600c808501829055600d8501829055600e850180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000169055845460018601546001600160a01b031683526020919091526040918290208190559254915490517f7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e093612b1493909233928e928e928e928e9291908e90614355565b60405180910390a17f6af0134faa0f9290c1d686d55012aca80302d31d5c856e4bc7954f7613dc7f878160000154338a8a8a8a876009015488600a015489600201548a600301548e604051612b739b9a999897969594939291906143eb565b60405180910390a154979650505050505050565b6004612b92826118ce565b6008811115612ba357612ba36146f0565b14612c165760405162461bcd60e51b815260206004820152603f60248201527f4e6f756e7344414f3a3a71756575653a2070726f706f73616c2063616e206f6e60448201527f6c79206265207175657565642069662069742069732073756363656564656400606482015260840161089c565b6000818152600b6020908152604080832060095482517f6a42b8f800000000000000000000000000000000000000000000000000000000815292519194936001600160a01b0390911692636a42b8f89260048083019392829003018186803b158015612c8157600080fd5b505afa158015612c95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb99190613e5a565b612cc39042614563565b905060005b6005830154811015612e8d57612e7b836005018281548110612cec57612cec61471f565b6000918252602090912001546006850180546001600160a01b039092169184908110612d1a57612d1a61471f565b9060005260206000200154856007018481548110612d3a57612d3a61471f565b906000526020600020018054612d4f9061463a565b80601f0160208091040260200160405190810160405280929190818152602001828054612d7b9061463a565b8015612dc85780601f10612d9d57610100808354040283529160200191612dc8565b820191906000526020600020905b815481529060010190602001808311612dab57829003601f168201915b5050505050866008018581548110612de257612de261471f565b906000526020600020018054612df79061463a565b80601f0160208091040260200160405190810160405280929190818152602001828054612e239061463a565b8015612e705780601f10612e4557610100808354040283529160200191612e70565b820191906000526020600020905b815481529060010190602001808311612e5357829003601f168201915b5050505050866135fb565b80612e8581614688565b915050612cc8565b506004820181905560408051848152602081018390527f9a2e42fd6722813d69113e7d0079d3d940171428df7373df9c7f7617cfda2892910160405180910390a1505050565b6001546001600160a01b031633148015612eec57503315155b612f5e5760405162461bcd60e51b815260206004820152602a60248201527f4e6f756e7344414f3a3a5f61636365707441646d696e3a2070656e64696e672060448201527f61646d696e206f6e6c7900000000000000000000000000000000000000000000606482015260840161089c565b60008054600180546001600160a01b038082167fffffffffffffffffffffffff000000000000000000000000000000000000000080861682179096559490911690915560408051919092168082526020820184905292917ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc910160405180910390a1600154604080516001600160a01b03808516825290921660208301527fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a99101610966565b600561302f826118ce565b6008811115613040576130406146f0565b146130b5576040805162461bcd60e51b81526020600482015260248101919091527f4e6f756e7344414f3a3a657865637574653a2070726f706f73616c2063616e2060448201527f6f6e6c7920626520657865637574656420696620697420697320717565756564606482015260840161089c565b6000818152600b60205260408120600e810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff1662010000179055905b6005820154811015613231576009546005830180546001600160a01b0390921691630825f38f91908490811061312c5761312c61471f565b6000918252602090912001546006850180546001600160a01b03909216918590811061315a5761315a61471f565b906000526020600020015485600701858154811061317a5761317a61471f565b906000526020600020018660080186815481106131995761319961471f565b9060005260206000200187600401546040518663ffffffff1660e01b81526004016131c895949392919061426f565b600060405180830381600087803b1580156131e257600080fd5b505af11580156131f6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261321e9190810190613e73565b508061322981614688565b9150506130f4565b506040518281527f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f90602001610966565b600061271061327184846145b6565b61327b919061457b565b9392505050565b6000600161328f846118ce565b60088111156132a0576132a06146f0565b146133135760405162461bcd60e51b815260206004820152602c60248201527f4e6f756e7344414f3a3a63617374566f7465496e7465726e616c3a20766f746960448201527f6e6720697320636c6f7365640000000000000000000000000000000000000000606482015260840161089c565b60028260ff16111561338d5760405162461bcd60e51b815260206004820152602d60248201527f4e6f756e7344414f3a3a63617374566f7465496e7465726e616c3a20696e766160448201527f6c696420766f7465207479706500000000000000000000000000000000000000606482015260840161089c565b6000838152600b602090815260408083206001600160a01b0388168452600f8101909252909120805460ff161561342c5760405162461bcd60e51b815260206004820152602f60248201527f4e6f756e7344414f3a3a63617374566f7465496e7465726e616c3a20766f746560448201527f7220616c726561647920766f7465640000000000000000000000000000000000606482015260840161089c565b600a5460045460098401546000926001600160a01b03169163782d6fe1918a91613455916145f3565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b039092166004830152602482015260440160206040518083038186803b1580156134b157600080fd5b505afa1580156134c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134e99190614027565b905060ff851661351b57806bffffffffffffffffffffffff1683600c01546135119190614563565b600c84015561357f565b8460ff166001141561354f57806bffffffffffffffffffffffff1683600b01546135459190614563565b600b84015561357f565b8460ff166002141561357f57806bffffffffffffffffffffffff1683600d01546135799190614563565b600d8401555b81546bffffffffffffffffffffffff821662010000027fffffffffffffffffffffffffffffffffffff000000000000000000000000ffff60ff8816610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009093169290921760011791909116179091559150509392505050565b6009546040516001600160a01b039091169063f2b06537906136299088908890889088908890602001614222565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b815260040161365d91815260200190565b60206040518083038186803b15801561367557600080fd5b505afa158015613689573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136ad9190613e38565b156137465760405162461bcd60e51b815260206004820152605060248201527f4e6f756e7344414f3a3a71756575654f72526576657274496e7465726e616c3a60448201527f206964656e746963616c2070726f706f73616c20616374696f6e20616c72656160648201527f6479207175657565642061742065746100000000000000000000000000000000608482015260a40161089c565b6009546040517f3a66f9010000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690633a66f901906137979088908890889088908890600401614222565b602060405180830381600087803b1580156137b157600080fd5b505af11580156137c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137e99190613e5a565b505050505050565b82805482825590600052602060002090810192821561385e579160200282015b8281111561385e57825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909116178255602090920191600190910190613811565b5061386a92915061395b565b5090565b82805482825590600052602060002090810192821561385e579160200282015b8281111561385e57825182559160200191906001019061388e565b8280548282559060005260206000209081019282156138f6579160200282015b828111156138f657825180516138e6918491602090910190613970565b50916020019190600101906138c9565b5061386a9291506139e3565b82805482825590600052602060002090810192821561394f579160200282015b8281111561394f578251805161393f918491602090910190613970565b5091602001919060010190613922565b5061386a929150613a00565b5b8082111561386a576000815560010161395c565b82805461397c9061463a565b90600052602060002090601f01602090048101928261399e576000855561385e565b82601f106139b757805160ff191683800117855561385e565b8280016001018555821561385e579182018281111561385e57825182559160200191906001019061388e565b8082111561386a5760006139f78282613a1d565b506001016139e3565b8082111561386a576000613a148282613a1d565b50600101613a00565b508054613a299061463a565b6000825580601f10613a39575050565b601f016020900490600052602060002090810190613a57919061395b565b50565b6000613a6d613a688461453b565b6144e6565b9050828152838383011115613a8157600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b0381168114613aaf57600080fd5b919050565b600082601f830112613ac557600080fd5b81356020613ad5613a6883614517565b80838252828201915082860187848660051b8901011115613af557600080fd5b60005b85811015613b1b57613b0982613a98565b84529284019290840190600101613af8565b5090979650505050505050565b600082601f830112613b3957600080fd5b81356020613b49613a6883614517565b80838252828201915082860187848660051b8901011115613b6957600080fd5b60005b85811015613b1b57813567ffffffffffffffff811115613b8b57600080fd5b8801603f81018a13613b9c57600080fd5b613bad8a8783013560408401613a5a565b8552509284019290840190600101613b6c565b600082601f830112613bd157600080fd5b81356020613be1613a6883614517565b80838252828201915082860187848660051b8901011115613c0157600080fd5b6000805b86811015613c4457823567ffffffffffffffff811115613c23578283fd5b613c318b88838d0101613cb2565b8652509385019391850191600101613c05565b509198975050505050505050565b600082601f830112613c6357600080fd5b81356020613c73613a6883614517565b80838252828201915082860187848660051b8901011115613c9357600080fd5b60005b85811015613b1b57813584529284019290840190600101613c96565b600082601f830112613cc357600080fd5b61327b83833560208501613a5a565b803560ff81168114613aaf57600080fd5b600060208284031215613cf557600080fd5b61327b82613a98565b600080600080600080600060e0888a031215613d1957600080fd5b613d2288613a98565b9650613d3060208901613a98565b9550613d3e60408901613a98565b969995985095966060810135965060808101359560a0820135955060c0909101359350915050565b600080600080600060a08688031215613d7e57600080fd5b853567ffffffffffffffff80821115613d9657600080fd5b613da289838a01613ab4565b96506020880135915080821115613db857600080fd5b613dc489838a01613c52565b95506040880135915080821115613dda57600080fd5b613de689838a01613bc0565b94506060880135915080821115613dfc57600080fd5b613e0889838a01613b28565b93506080880135915080821115613e1e57600080fd5b50613e2b88828901613cb2565b9150509295509295909350565b600060208284031215613e4a57600080fd5b8151801515811461327b57600080fd5b600060208284031215613e6c57600080fd5b5051919050565b600060208284031215613e8557600080fd5b815167ffffffffffffffff811115613e9c57600080fd5b8201601f81018413613ead57600080fd5b8051613ebb613a688261453b565b818152856020838501011115613ed057600080fd5b613ee182602083016020860161460a565b95945050505050565b600060208284031215613efc57600080fd5b5035919050565b60008060408385031215613f1657600080fd5b82359150613f2660208401613a98565b90509250929050565b60008060408385031215613f4257600080fd5b82359150613f2660208401613cd2565b60008060008060608587031215613f6857600080fd5b84359350613f7860208601613cd2565b9250604085013567ffffffffffffffff80821115613f9557600080fd5b818701915087601f830112613fa957600080fd5b813581811115613fb857600080fd5b886020828501011115613fca57600080fd5b95989497505060200194505050565b600080600080600060a08688031215613ff157600080fd5b8535945061400160208701613cd2565b935061400f60408701613cd2565b94979396509394606081013594506080013592915050565b60006020828403121561403957600080fd5b81516bffffffffffffffffffffffff8116811461327b57600080fd5b600081518084526020808501945080840160005b8381101561408e5781516001600160a01b031687529582019590820190600101614069565b509495945050505050565b600081518084526020808501808196508360051b8101915082860160005b858110156140e15782840389526140cf84835161411e565b988501989350908401906001016140b7565b5091979650505050505050565b600081518084526020808501945080840160005b8381101561408e57815187529582019590820190600101614102565b6000815180845261413681602086016020860161460a565b601f01601f19169290920160200192915050565b8054600090600181811c908083168061416457607f831692505b602080841082141561419f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b8388528180156141b657600181146141e857614216565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008616828a0152604089019650614216565b876000528160002060005b8681101561420e5781548b82018501529085019083016141f3565b8a0183019750505b50505050505092915050565b6001600160a01b038616815284602082015260a06040820152600061424a60a083018661411e565b828103606084015261425c818661411e565b9150508260808301529695505050505050565b6001600160a01b038616815284602082015260a06040820152600061429760a083018661414a565b828103606084015261425c818661414a565b6080815260006142bc6080830187614055565b82810360208401526142ce81876140ee565b905082810360408401526142e28186614099565b905082810360608401526142f68185614099565b979650505050505050565b602081016009831061433c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60208152600061327b602083018461411e565b60006101208b83526001600160a01b038b16602084015280604084015261437e8184018b614055565b90508281036060840152614392818a6140ee565b905082810360808401526143a68189614099565b905082810360a08401526143ba8188614099565b90508560c08401528460e08401528281036101008401526143db818561411e565b9c9b505050505050505050505050565b60006101608d83526001600160a01b038d1660208401528060408401526144148184018d614055565b90508281036060840152614428818c6140ee565b9050828103608084015261443c818b614099565b905082810360a0840152614450818a614099565b90508760c08401528660e0840152856101008401528461012084015282810361014084015261447f818561411e565b9e9d5050505050505050505050505050565b85815260ff851660208201526bffffffffffffffffffffffff8416604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b604051601f8201601f1916810167ffffffffffffffff8111828210171561450f5761450f61474e565b604052919050565b600067ffffffffffffffff8211156145315761453161474e565b5060051b60200190565b600067ffffffffffffffff8211156145555761455561474e565b50601f01601f191660200190565b60008219821115614576576145766146c1565b500190565b6000826145b1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156145ee576145ee6146c1565b500290565b600082821015614605576146056146c1565b500390565b60005b8381101561462557818101518382015260200161460d565b83811115614634576000848401525b50505050565b600181811c9082168061464e57607f821691505b60208210811415611ab5577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156146ba576146ba6146c1565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea26469706673582212202d219bbd5982bc04b4820b819396c18d235e46dcc014201d58710c7b14362c2364736f6c63430008060033