Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
NounsDAOLogicV1Fork
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BSD-3-Clause /// @title The Nouns DAO logic version 1 /********************************* * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░█████████░░█████████░░░ * * ░░░░░░██░░░████░░██░░░████░░░ * * ░░██████░░░████████░░░████░░░ * * ░░██░░██░░░████░░██░░░████░░░ * * ░░██░░██░░░████░░██░░░████░░░ * * ░░░░░░█████████░░█████████░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * *********************************/ // LICENSE // NounsDAOLogicV1Fork.sol is a modified version of NounsDAOLogicV1.sol. // 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 // NounsDAOLogicV1Fork adds: // - `quit(tokenIds)`, a function that allows token holders to quit the DAO, taking their pro rata funds, // and sending their tokens to the DAO treasury. // // - `adjustedTotalSupply`, the total supply calculation used in DAO functions like quorum and proposal threshold, in // which the DAO exludes tokens held by the treasury, such that tokens used to quit the DAO are not counted. // // - A function for the DAO to set which ERC20s are transferred pro rata in the `quit` function. // // - A new proposals getter function, since adding new fields to Proposal results in the default getter hitting a // `Stack too deep` error. // // - A new Proposal field: `creationBlock`, used to resolve the `votingDelay` bug, in which editing `votingDelay` would // change the votes snapshot block for proposals in-progress. // // NounsDAOLogicV1Fork modifies: // - The proxy pattern from Compound's old Transparent-like proxy, to OpenZeppelin's recommended UUPS pattern. // // - `propose` // - uses `adjustedTotalSupply` // - includes a new 'delayed governance' feature which gives forkers from the original DAO time to claim their tokens // with this new DAO; proposals are not allowed until all tokens are claimed, or until the delay expiration // timestamp is reached. // // - `cancel` bugfix, allowing proposals to be canceled by anyone if the proposer's vote balance is equal to proposal // threshold. // // - Removes the vetoer role and logic related to it. The quit function provides minority protection instead of the // vetoer, and fork DAOs can upgrade their governor to include the vetoer feature if it's needed. // // - Modified MIN_VOTING_PERIOD, MAX_VOTING_PERIOD to correct block numbers assuming 12 second blocks // - Modified MAX_VOTING_DELAY to be 2 weeks // // 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 `vetoer` 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.19; import { UUPSUpgradeable } from '@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol'; import { NounsDAOEventsFork } from './NounsDAOEventsFork.sol'; import { NounsDAOStorageV1Fork } from './NounsDAOStorageV1Fork.sol'; import { NounsDAOExecutorV2 } from '../../../NounsDAOExecutorV2.sol'; import { INounsTokenForkLike } from './INounsTokenForkLike.sol'; import { IERC20 } from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import { ReentrancyGuardUpgradeable } from '@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol'; contract NounsDAOLogicV1Fork is UUPSUpgradeable, ReentrancyGuardUpgradeable, NounsDAOStorageV1Fork, NounsDAOEventsFork { error AdminOnly(); error WaitingForTokensToClaimOrExpiration(); error TokensMustBeASubsetOfWhitelistedTokens(); error GovernanceBlockedDuringForkingPeriod(); error DuplicateTokenAddress(); event ERC20TokensToIncludeInQuitSet(address[] oldErc20Tokens, address[] newErc20tokens); event Quit(address indexed msgSender, uint256[] tokenIds); /// @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 = 7_200; // 24 hours /// @notice The max setable voting period uint256 public constant MAX_VOTING_PERIOD = 100_800; // 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 = 100_800; // 2 weeks /// @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)'); constructor() initializer {} /** * @notice Used to initialize the contract during delegator contructor * @dev Not asserting that param values are within the hard-coded bounds in order to make it easier to run * manual tests; seems a safe decision since we assume fork DAOs are initialized by `ForkDAODeployer` * @param timelock_ The address of the NounsDAOExecutor * @param nouns_ The address of the NOUN tokens * @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 * @param erc20TokensToIncludeInQuit_ The initial list of ERC20 tokens to include when quitting * @param delayedGovernanceExpirationTimestamp_ The delayed governance expiration timestamp */ function initialize( address timelock_, address nouns_, uint256 votingPeriod_, uint256 votingDelay_, uint256 proposalThresholdBPS_, uint256 quorumVotesBPS_, address[] memory erc20TokensToIncludeInQuit_, uint256 delayedGovernanceExpirationTimestamp_ ) public virtual { __ReentrancyGuard_init_unchained(); require(address(timelock) == address(0), 'NounsDAO::initialize: can only initialize once'); require(timelock_ != address(0), 'NounsDAO::initialize: invalid timelock address'); require(nouns_ != address(0), 'NounsDAO::initialize: invalid nouns address'); emit VotingPeriodSet(votingPeriod, votingPeriod_); emit VotingDelaySet(votingDelay, votingDelay_); emit ProposalThresholdBPSSet(proposalThresholdBPS, proposalThresholdBPS_); emit QuorumVotesBPSSet(quorumVotesBPS, quorumVotesBPS_); admin = timelock_; timelock = NounsDAOExecutorV2(payable(timelock_)); nouns = INounsTokenForkLike(nouns_); votingPeriod = votingPeriod_; votingDelay = votingDelay_; proposalThresholdBPS = proposalThresholdBPS_; quorumVotesBPS = quorumVotesBPS_; erc20TokensToIncludeInQuit = erc20TokensToIncludeInQuit_; delayedGovernanceExpirationTimestamp = delayedGovernanceExpirationTimestamp_; } /** * @notice A function that allows token holders to quit the DAO, taking their pro rata funds, * and sending their tokens to the DAO treasury. * Will revert as long as not all tokens were claimed, and as long as the delayed governance has not expired. * @param tokenIds The token ids to quit with */ function quit(uint256[] calldata tokenIds) external nonReentrant { quitInternal(tokenIds, erc20TokensToIncludeInQuit); } function quit(uint256[] calldata tokenIds, address[] calldata erc20TokensToInclude) external nonReentrant { checkForDuplicates(erc20TokensToInclude); // check that erc20TokensToInclude is a subset of `erc20TokensToIncludeInQuit` address[] memory erc20TokensToIncludeInQuit_ = erc20TokensToIncludeInQuit; for (uint256 i = 0; i < erc20TokensToInclude.length; i++) { if (!isAddressIn(erc20TokensToInclude[i], erc20TokensToIncludeInQuit_)) { revert TokensMustBeASubsetOfWhitelistedTokens(); } } quitInternal(tokenIds, erc20TokensToInclude); } function quitInternal(uint256[] calldata tokenIds, address[] memory erc20TokensToInclude) internal { checkGovernanceActive(); uint256 totalSupply = adjustedTotalSupply(); for (uint256 i = 0; i < tokenIds.length; i++) { nouns.transferFrom(msg.sender, address(timelock), tokenIds[i]); } uint256[] memory balancesToSend = new uint256[](erc20TokensToInclude.length); // Capture balances to send before actually sending them, to avoid the risk of external calls changing balances. uint256 ethToSend = (address(timelock).balance * tokenIds.length) / totalSupply; for (uint256 i = 0; i < erc20TokensToInclude.length; i++) { IERC20 erc20token = IERC20(erc20TokensToInclude[i]); balancesToSend[i] = (erc20token.balanceOf(address(timelock)) * tokenIds.length) / totalSupply; } // Send ETH and ERC20 tokens timelock.sendETH(payable(msg.sender), ethToSend); for (uint256 i = 0; i < erc20TokensToInclude.length; i++) { if (balancesToSend[i] > 0) { timelock.sendERC20(msg.sender, erc20TokensToInclude[i], balancesToSend[i]); } } emit Quit(msg.sender, tokenIds); } function isAddressIn(address a, address[] memory addresses) internal pure returns (bool) { for (uint256 i = 0; i < addresses.length; i++) { if (addresses[i] == a) return true; } return false; } 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 * Will revert as long as not all tokens were claimed, and as long as the delayed governance has not expired. * @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) { checkGovernanceActive(); ProposalTemp memory temp; temp.totalSupply = adjustedTotalSupply(); 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.creationBlock = block.number; 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 Internal function that reverts if the governance is not active yet. Governance becomes active as soon as * the forking period ended and one of these conditions is met: * 1. All tokens are claimed * 2. The delayed governance expiration timestamp is reached */ function checkGovernanceActive() internal view { if (block.timestamp < nouns.forkingPeriodEndTimestamp()) { revert GovernanceBlockedDuringForkingPeriod(); } if (block.timestamp < delayedGovernanceExpirationTimestamp && nouns.remainingTokensToClaim() > 0) { revert WaitingForTokensToClaimOrExpiration(); } } /** * @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 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.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 Returns the proposal details given a proposal id. * @dev this explicit getter solves the `Stack too deep` problem that arose after * adding a new field to the Proposal struct. * @param proposalId the proposal id to get the data for * @return A `ProposalCondensed` struct with the proposal data */ function proposals(uint256 proposalId) external view returns (ProposalCondensed memory) { Proposal storage proposal = _proposals[proposalId]; return ProposalCondensed({ id: proposal.id, proposer: proposal.proposer, proposalThreshold: proposal.proposalThreshold, quorumVotes: proposal.quorumVotes, eta: proposal.eta, startBlock: proposal.startBlock, endBlock: proposal.endBlock, forVotes: proposal.forVotes, againstVotes: proposal.againstVotes, abstainVotes: proposal.abstainVotes, canceled: proposal.canceled, executed: proposal.executed, creationBlock: proposal.creationBlock }); } /** * @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)), block.chainid, 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.creationBlock); 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, newVotingDelay); } /** * @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, newVotingPeriod); } /** * @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, newProposalThresholdBPS); } /** * @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::_setQuorumVotesBPS: invalid quorum votes basis points' ); uint256 oldQuorumVotesBPS = quorumVotesBPS; quorumVotesBPS = newQuorumVotesBPS; emit QuorumVotesBPSSet(oldQuorumVotesBPS, newQuorumVotesBPS); } /** * @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 Admin function for setting the list of ERC20 tokens to transfer on `quit`. */ function _setErc20TokensToIncludeInQuit(address[] calldata erc20tokens) external { if (msg.sender != admin) revert AdminOnly(); checkForDuplicates(erc20tokens); emit ERC20TokensToIncludeInQuitSet(erc20TokensToIncludeInQuit, erc20tokens); erc20TokensToIncludeInQuit = erc20tokens; } /** * @notice Current proposal threshold using Noun Total Supply * Differs from `GovernerBravo` which uses fixed amount */ function proposalThreshold() public view returns (uint256) { return bps2Uint(proposalThresholdBPS, adjustedTotalSupply()); } /** * @notice Current quorum votes using Noun Total Supply * Differs from `GovernerBravo` which uses fixed amount */ function quorumVotes() public view returns (uint256) { return bps2Uint(quorumVotesBPS, adjustedTotalSupply()); } function adjustedTotalSupply() public view returns (uint256) { return nouns.totalSupply() - nouns.balanceOf(address(timelock)) + nouns.remainingTokensToClaim(); } function erc20TokensToIncludeInQuitArray() public view returns (address[] memory) { return erc20TokensToIncludeInQuit; } function bps2Uint(uint256 bps, uint256 number) internal pure returns (uint256) { return (number * bps) / 10000; } function _authorizeUpgrade(address) internal view override { require(msg.sender == admin, 'NounsDAO::_authorizeUpgrade: admin only'); } function checkForDuplicates(address[] calldata erc20tokens) internal pure { if (erc20tokens.length == 0) return; for (uint256 i = 0; i < erc20tokens.length - 1; i++) { for (uint256 j = i + 1; j < erc20tokens.length; j++) { if (erc20tokens[i] == erc20tokens[j]) revert DuplicateTokenAddress(); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; import "../ERC1967/ERC1967Upgrade.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is ERC1967Upgrade { /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeTo(address newImplementation) external virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallSecure(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallSecure(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; }
// SPDX-License-Identifier: BSD-3-Clause pragma solidity ^0.8.19; contract NounsDAOEventsFork { /// @notice An event emitted when a new proposal is created event ProposalCreated( uint256 indexed id, address indexed proposer, address[] targets, uint256[] values, string[] signatures, bytes[] calldatas, uint256 startBlock, uint256 endBlock, string description ); /// @notice An event emitted when a new proposal is created, which includes additional information event ProposalCreatedWithRequirements( uint256 indexed id, address indexed 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 indexed proposalId, uint8 support, uint256 votes, string reason); /// @notice An event emitted when a proposal has been canceled event ProposalCanceled(uint256 indexed id); /// @notice An event emitted when a proposal has been queued in the NounsDAOExecutor event ProposalQueued(uint256 indexed id, uint256 eta); /// @notice An event emitted when a proposal has been executed in the NounsDAOExecutor event ProposalExecuted(uint256 indexed 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 indexed oldPendingAdmin, address indexed newPendingAdmin); /// @notice Emitted when pendingAdmin is accepted, which means admin is updated event NewAdmin(address indexed oldAdmin, address indexed newAdmin); }
// SPDX-License-Identifier: BSD-3-Clause pragma solidity ^0.8.19; import { NounsDAOExecutorV2 } from '../../../NounsDAOExecutorV2.sol'; import { INounsTokenForkLike } from './INounsTokenForkLike.sol'; /** * @title Storage for `NounsDAOLogicV1Fork`. * @dev Based on NounsDAOStorageV1, with the following changes: * - vetoer is removed. * - Vetoed proposal state removed. * - implementation is removed, instead it's stored in the ERC-1967 storage slot. * - proposals renamed to _proposals to enable the explicit getter, which solves the stack too deep issue with the * default getter. * - creationBlock added to Proposal struct, similar to V2, to solve the votingDelay editing bug. * @notice For future upgrades, do not change NounsDAOStorageV1Fork. Create a new * contract which implements NounsDAOStorageV1Fork. */ contract NounsDAOStorageV1Fork { /// @notice Administrator for this contract address public admin; /// @notice Pending administrator for this contract address public pendingAdmin; /// @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 to exceed 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 NounsDAOExecutorV2 public timelock; /// @notice The address of the Nouns tokens INounsTokenForkLike 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; uint256 public delayedGovernanceExpirationTimestamp; address[] public erc20TokensToIncludeInQuit; 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 executed bool executed; /// @notice Receipts of ballots for the entire set of voters mapping(address => Receipt) receipts; /// @notice The block at which this proposal was created uint256 creationBlock; } /// @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 } struct ProposalCondensed { /// @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 minimum 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 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 executed bool executed; /// @notice The block at which this proposal was created uint256 creationBlock; } }
// SPDX-License-Identifier: BSD-3-Clause /// @title The Nouns DAO executor and treasury, supporting DAO fork /********************************* * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░█████████░░█████████░░░ * * ░░░░░░██░░░████░░██░░░████░░░ * * ░░██████░░░████████░░░████░░░ * * ░░██░░██░░░████░░██░░░████░░░ * * ░░██░░██░░░████░░██░░░████░░░ * * ░░░░░░█████████░░█████████░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ * *********************************/ // LICENSE // NounsDAOExecutor2.sol is a modified version of Compound Lab's Timelock.sol: // https://github.com/compound-finance/compound-protocol/blob/20abad28055a2f91df48a90f8bb6009279a4cb35/contracts/Timelock.sol // // Timelock.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 // NounsDAOExecutor2.sol is a modified version of NounsDAOExecutor.sol // // NounsDAOExecutor.sol modifications: // NounsDAOExecutor.sol modifies Timelock to use Solidity 0.8.x receive(), fallback(), and built-in over/underflow protection // This contract acts as executor of Nouns DAO governance and its treasury, so it has been modified to accept ETH. // // // NounsDAOExecutor2.sol modifications: // - `sendETH` and `sendERC20` functions used for DAO forks // - is upgradable via UUPSUpgradeable. uses intializer instead of constructor. // - `GRACE_PERIOD` has been increased from 14 days to 21 days to allow more time in case of a forking period pragma solidity ^0.8.19; import { IERC20 } from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import { SafeERC20 } from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; import { Initializable } from '@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol'; import { UUPSUpgradeable } from '@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol'; import { Address } from '@openzeppelin/contracts/utils/Address.sol'; contract NounsDAOExecutorV2 is UUPSUpgradeable, Initializable { using SafeERC20 for IERC20; using Address for address payable; event NewAdmin(address indexed newAdmin); event NewPendingAdmin(address indexed newPendingAdmin); event NewDelay(uint256 indexed newDelay); event CancelTransaction( bytes32 indexed txHash, address indexed target, uint256 value, string signature, bytes data, uint256 eta ); event ExecuteTransaction( bytes32 indexed txHash, address indexed target, uint256 value, string signature, bytes data, uint256 eta ); event QueueTransaction( bytes32 indexed txHash, address indexed target, uint256 value, string signature, bytes data, uint256 eta ); event ETHSent(address indexed to, uint256 amount); event ERC20Sent(address indexed to, address indexed erc20Token, uint256 amount); string public constant NAME = 'NounsDAOExecutorV2'; /// @dev increased grace period from 14 days to 21 days to allow more time in case of a forking period uint256 public constant GRACE_PERIOD = 21 days; uint256 public constant MINIMUM_DELAY = 2 days; uint256 public constant MAXIMUM_DELAY = 30 days; address public admin; address public pendingAdmin; uint256 public delay; mapping(bytes32 => bool) public queuedTransactions; constructor() initializer {} function initialize(address admin_, uint256 delay_) public virtual initializer { require(delay_ >= MINIMUM_DELAY, 'NounsDAOExecutor::constructor: Delay must exceed minimum delay.'); require(delay_ <= MAXIMUM_DELAY, 'NounsDAOExecutor::setDelay: Delay must not exceed maximum delay.'); admin = admin_; delay = delay_; } function setDelay(uint256 delay_) public { require(msg.sender == address(this), 'NounsDAOExecutor::setDelay: Call must come from NounsDAOExecutor.'); require(delay_ >= MINIMUM_DELAY, 'NounsDAOExecutor::setDelay: Delay must exceed minimum delay.'); require(delay_ <= MAXIMUM_DELAY, 'NounsDAOExecutor::setDelay: Delay must not exceed maximum delay.'); delay = delay_; emit NewDelay(delay_); } function acceptAdmin() public { require(msg.sender == pendingAdmin, 'NounsDAOExecutor::acceptAdmin: Call must come from pendingAdmin.'); admin = msg.sender; pendingAdmin = address(0); emit NewAdmin(msg.sender); } function setPendingAdmin(address pendingAdmin_) public { require( msg.sender == address(this), 'NounsDAOExecutor::setPendingAdmin: Call must come from NounsDAOExecutor.' ); pendingAdmin = pendingAdmin_; emit NewPendingAdmin(pendingAdmin_); } function queueTransaction( address target, uint256 value, string memory signature, bytes memory data, uint256 eta ) public returns (bytes32) { require(msg.sender == admin, 'NounsDAOExecutor::queueTransaction: Call must come from admin.'); require( eta >= getBlockTimestamp() + delay, 'NounsDAOExecutor::queueTransaction: Estimated execution block must satisfy delay.' ); bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta)); queuedTransactions[txHash] = true; emit QueueTransaction(txHash, target, value, signature, data, eta); return txHash; } function cancelTransaction( address target, uint256 value, string memory signature, bytes memory data, uint256 eta ) public { require(msg.sender == admin, 'NounsDAOExecutor::cancelTransaction: Call must come from admin.'); bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta)); queuedTransactions[txHash] = false; emit CancelTransaction(txHash, target, value, signature, data, eta); } function executeTransaction( address target, uint256 value, string memory signature, bytes memory data, uint256 eta ) public returns (bytes memory) { require(msg.sender == admin, 'NounsDAOExecutor::executeTransaction: Call must come from admin.'); bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta)); require(queuedTransactions[txHash], "NounsDAOExecutor::executeTransaction: Transaction hasn't been queued."); require( getBlockTimestamp() >= eta, "NounsDAOExecutor::executeTransaction: Transaction hasn't surpassed time lock." ); require( getBlockTimestamp() <= eta + GRACE_PERIOD, 'NounsDAOExecutor::executeTransaction: Transaction is stale.' ); queuedTransactions[txHash] = false; bytes memory callData; if (bytes(signature).length == 0) { callData = data; } else { callData = abi.encodePacked(bytes4(keccak256(bytes(signature))), data); } // solium-disable-next-line security/no-call-value (bool success, bytes memory returnData) = target.call{ value: value }(callData); require(success, 'NounsDAOExecutor::executeTransaction: Transaction execution reverted.'); emit ExecuteTransaction(txHash, target, value, signature, data, eta); return returnData; } function getBlockTimestamp() internal view returns (uint256) { // solium-disable-next-line security/no-block-members return block.timestamp; } receive() external payable {} fallback() external payable {} function sendETH(address payable recipient, uint256 ethToSend) external { require(msg.sender == admin, 'NounsDAOExecutor::sendETH: Call must come from admin.'); recipient.sendValue(ethToSend); emit ETHSent(recipient, ethToSend); } function sendERC20( address recipient, address erc20Token, uint256 tokensToSend ) external { require(msg.sender == admin, 'NounsDAOExecutor::sendERC20: Call must come from admin.'); IERC20(erc20Token).safeTransfer(recipient, tokensToSend); emit ERC20Sent(recipient, erc20Token, tokensToSend); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address) internal view override { require( msg.sender == address(this), 'NounsDAOExecutor::_authorizeUpgrade: Call must come from NounsDAOExecutor.' ); } }
// SPDX-License-Identifier: BSD-3-Clause pragma solidity ^0.8.19; interface INounsTokenForkLike { function getPriorVotes(address account, uint256 blockNumber) external view returns (uint96); function totalSupply() external view returns (uint256); function transferFrom( address from, address to, uint256 tokenId ) external; function balanceOf(address owner) external view returns (uint256 balance); function ownerOf(uint256 tokenId) external view returns (address owner); function remainingTokensToClaim() external view returns (uint256); function forkingPeriodEndTimestamp() external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal initializer { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal initializer { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeacon.sol"; import "../../utils/Address.sol"; import "../../utils/StorageSlot.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967Upgrade { // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { Address.functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallSecure( address newImplementation, bytes memory data, bool forceCall ) internal { address oldImplementation = _getImplementation(); // Initial upgrade and setup call _setImplementation(newImplementation); if (data.length > 0 || forceCall) { Address.functionDelegateCall(newImplementation, data); } // Perform rollback test if not already in progress StorageSlot.BooleanSlot storage rollbackTesting = StorageSlot.getBooleanSlot(_ROLLBACK_SLOT); if (!rollbackTesting.value) { // Trigger rollback using upgradeTo from the new implementation rollbackTesting.value = true; Address.functionDelegateCall( newImplementation, abi.encodeWithSignature("upgradeTo(address)", oldImplementation) ); rollbackTesting.value = false; // Check rollback was effective require(oldImplementation == _getImplementation(), "ERC1967Upgrade: upgrade breaks further upgrades"); // Finally reset to the new implementation and log the upgrade _upgradeTo(newImplementation); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlot.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlot.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( Address.isContract(IBeacon(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (proxy/utils/Initializable.sol) pragma solidity ^0.8.0; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() initializer {} * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require(_initializing || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/Address.sol) pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeacon { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/StorageSlot.sol) pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ``` * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { assembly { r.slot := slot } } }
{ "remappings": [ "@ensdomains/=/Users/david/projects/crypto/nouns/dao-logic-v3/nouns-monorepo/node_modules/@ensdomains/", "@graphprotocol/=/Users/david/projects/crypto/nouns/dao-logic-v3/nouns-monorepo/node_modules/@graphprotocol/", "@nouns/=/Users/david/projects/crypto/nouns/dao-logic-v3/nouns-monorepo/node_modules/@nouns/", "@openzeppelin/=/Users/david/projects/crypto/nouns/dao-logic-v3/nouns-monorepo/node_modules/@openzeppelin/", "base64-sol/=/Users/david/projects/crypto/nouns/dao-logic-v3/nouns-monorepo/node_modules/base64-sol/", "ds-test/=lib/forge-std/lib/ds-test/src/", "eth-gas-reporter/=/Users/david/projects/crypto/nouns/dao-logic-v3/nouns-monorepo/node_modules/eth-gas-reporter/", "forge-std/=lib/forge-std/src/", "hardhat/=/Users/david/projects/crypto/nouns/dao-logic-v3/nouns-monorepo/node_modules/hardhat/", "truffle/=/Users/david/projects/crypto/nouns/dao-logic-v3/nouns-monorepo/node_modules/@graphprotocol/graph-cli/examples/basic-event-handlers/node_modules/truffle/", "lib/forge-std:ds-test/=lib/forge-std/lib/ds-test/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "libraries": { "contracts/governance/NounsDAOV3Admin.sol": { "NounsDAOV3Admin": "0x3021e4a38e506546dc5dcf3bdb68cc5c049cd592" }, "contracts/governance/NounsDAOV3DynamicQuorum.sol": { "NounsDAOV3DynamicQuorum": "0x7e348c4288c7eaa1b0e63e1d0c055bfac04babbf" }, "contracts/governance/NounsDAOV3Proposals.sol": { "NounsDAOV3Proposals": "0x92b9adb33886f6cfcc0a763505a1bdf8708b96ed" }, "contracts/governance/NounsDAOV3Votes.sol": { "NounsDAOV3Votes": "0xe5bdc2badaf03a716c8559c8ef274c82df29d0f5" }, "contracts/governance/fork/NounsDAOV3Fork.sol": { "NounsDAOV3Fork": "0x34761eb1bda821ed7b30b51d7fbabbe18fd7574b" } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AdminOnly","type":"error"},{"inputs":[],"name":"DuplicateTokenAddress","type":"error"},{"inputs":[],"name":"GovernanceBlockedDuringForkingPeriod","type":"error"},{"inputs":[],"name":"TokensMustBeASubsetOfWhitelistedTokens","type":"error"},{"inputs":[],"name":"WaitingForTokensToClaimOrExpiration","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"oldErc20Tokens","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"newErc20tokens","type":"address[]"}],"name":"ERC20TokensToIncludeInQuitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldAdmin","type":"address"},{"indexed":true,"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":true,"internalType":"address","name":"oldPendingAdmin","type":"address"},{"indexed":true,"internalType":"address","name":"newPendingAdmin","type":"address"}],"name":"NewPendingAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"ProposalCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"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":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"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":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"ProposalExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"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":true,"internalType":"address","name":"msgSender","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"Quit","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":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":true,"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":[{"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":"executed","type":"bool"},{"internalType":"uint256","name":"creationBlock","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"erc20tokens","type":"address[]"}],"name":"_setErc20TokensToIncludeInQuit","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":"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":"adjustedTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":[],"name":"delayedGovernanceExpirationTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"erc20TokensToIncludeInQuit","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"erc20TokensToIncludeInQuitArray","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","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 NounsDAOStorageV1Fork.Receipt","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"timelock_","type":"address"},{"internalType":"address","name":"nouns_","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"},{"internalType":"address[]","name":"erc20TokensToIncludeInQuit_","type":"address[]"},{"internalType":"uint256","name":"delayedGovernanceExpirationTimestamp_","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 INounsTokenForkLike","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":"proposalId","type":"uint256"}],"name":"proposals","outputs":[{"components":[{"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":"executed","type":"bool"},{"internalType":"uint256","name":"creationBlock","type":"uint256"}],"internalType":"struct NounsDAOStorageV1Fork.ProposalCondensed","name":"","type":"tuple"}],"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":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"address[]","name":"erc20TokensToInclude","type":"address[]"}],"name":"quit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"quit","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 NounsDAOStorageV1Fork.ProposalState","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timelock","outputs":[{"internalType":"contract NounsDAOExecutorV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","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"}]
Contract Creation Code
60a0604052306080523480156200001557600080fd5b50600054610100900460ff168062000030575060005460ff16155b620000985760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b600054610100900460ff16158015620000bb576000805461ffff19166101011790555b8015620000ce576000805461ff00191690555b5060805161531e62000100600039600081816110a8015281816110e8015281816118eb015261192b015261531e6000f3fe6080604052600436106102ff5760003560e01c80636f3eff2811610190578063d23c2953116100dc578063e23a9a5211610095578063f56ac09c1161006f578063f56ac09c146109ca578063f58e26cb146109ea578063f851a44014610a0a578063fe0d94c114610a2a57600080fd5b8063e23a9a5214610965578063e48083fe14610886578063e9c714f2146109b557600080fd5b8063d23c29531461089b578063d33219b4146108bb578063da35c664146108db578063da95691a146108f1578063ddf0b00914610911578063deaaa7cc1461093157600080fd5b806397d048e511610149578063b58131b011610123578063b58131b01461083b578063b71d1a0c14610850578063bb67758214610870578063c82fbd081461088657600080fd5b806397d048e514610804578063a64e024a14610824578063b11262631461082457600080fd5b80636f3eff281461076e5780637b3c71d31461078e5780637bdbe4d0146107ae5780637f9262fd146107c357806383cce0e1146107d95780638f1314b6146107ef57600080fd5b806324bc1a641161024f5780633bccf4fd1161020857806340e58ee5116101e257806340e58ee5146106fb5780634f1ef2861461071b578063567813881461072e57806368e981a71461074e57600080fd5b80633bccf4fd1461068c5780633e3dad99146106ac5780633e4f49e6146106ce57600080fd5b806324bc1a64146105d157806326782247146105e65780632de45f1814610606578063328dd982146106265780633659cfe6146106565780633932abb11461067657600080fd5b806314a67ea4116102bc5780631e7b5d3a116102965780631e7b5d3a1461055c57806320606b7014610572578063215809ca146105a65780632230e155146105bc57600080fd5b806314a67ea4146104f957806317977c611461050f5780631dfb1b5a1461053c57600080fd5b8063013cf08b1461030457806302a251a31461033a57806306fdde031461035e5780630a494840146103a05780630a7473b81461049f5780630ea2d98c146104d7575b600080fd5b34801561031057600080fd5b5061032461031f3660046142de565b610a4a565b60405161033191906142f7565b60405180910390f35b34801561034657600080fd5b5061035060365481565b604051908152602001610331565b34801561036a57600080fd5b50610393604051806040016040528060098152602001684e6f756e732044414f60b81b81525081565b60405161033191906143f5565b3480156103ac57600080fd5b506104316103bb3660046142de565b603c602052600090815260409020805460018201546002830154600384015460048501546009860154600a870154600b880154600c890154600d8a0154600e8b01546010909b0154999a6001600160a01b03909916999798969795969495939492939192909160ff80831692610100900416908d565b604080519d8e526001600160a01b03909c1660208e01529a8c019990995260608b019790975260808a019590955260a089019390935260c088019190915260e0870152610100860152610120850152151561014084015215156101608301526101808201526101a001610331565b3480156104ab57600080fd5b506104bf6104ba3660046142de565b610b7c565b6040516001600160a01b039091168152602001610331565b3480156104e357600080fd5b506104f76104f23660046142de565b610ba6565b005b34801561050557600080fd5b5061035060375481565b34801561051b57600080fd5b5061035061052a366004614424565b603d6020526000908152604090205481565b34801561054857600080fd5b506104f76105573660046142de565b610cd5565b34801561056857600080fd5b506103506103e881565b34801561057e57600080fd5b506103507f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b3480156105b257600080fd5b50610350611c2081565b3480156105c857600080fd5b5061035060c881565b3480156105dd57600080fd5b50610350610df3565b3480156105f257600080fd5b506034546104bf906001600160a01b031681565b34801561061257600080fd5b50603b546104bf906001600160a01b031681565b34801561063257600080fd5b506106466106413660046142de565b610e0d565b6040516103319493929190614508565b34801561066257600080fd5b506104f7610671366004614424565b61109e565b34801561068257600080fd5b5061035060355481565b34801561069857600080fd5b506104f76106a7366004614571565b611166565b3480156106b857600080fd5b506106c16113cc565b60405161033191906145bf565b3480156106da57600080fd5b506106ee6106e93660046142de565b61142e565b60405161033191906145e8565b34801561070757600080fd5b506104f76107163660046142de565b6115da565b6104f76107293660046146d3565b6118e1565b34801561073a57600080fd5b506104f7610749366004614720565b61199a565b34801561075a57600080fd5b506104f7610769366004614797565b611a01565b34801561077a57600080fd5b506104f76107893660046142de565b611b75565b34801561079a57600080fd5b506104f76107a9366004614802565b611ca3565b3480156107ba57600080fd5b50610350600a81565b3480156107cf57600080fd5b50610350603e5481565b3480156107e557600080fd5b5061035060385481565b3480156107fb57600080fd5b50610350611cf2565b34801561081057600080fd5b506104f761081f3660046142de565b611e5b565b34801561083057600080fd5b50610350620189c081565b34801561084757600080fd5b50610350611f8f565b34801561085c57600080fd5b506104f761086b366004614424565b611f9f565b34801561087c57600080fd5b506103506107d081565b34801561089257600080fd5b50610350600181565b3480156108a757600080fd5b506104f76108b6366004614888565b61205a565b3480156108c757600080fd5b50603a546104bf906001600160a01b031681565b3480156108e757600080fd5b5061035060395481565b3480156108fd57600080fd5b5061035061090c366004614ab2565b61211b565b34801561091d57600080fd5b506104f761092c3660046142de565b61273e565b34801561093d57600080fd5b506103507f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f81565b34801561097157600080fd5b50610985610980366004614b83565b612a5e565b6040805182511515815260208084015160ff1690820152918101516001600160601b031690820152606001610331565b3480156109c157600080fd5b506104f7612ad6565b3480156109d657600080fd5b506104f76109e5366004614ba6565b612be9565b3480156109f657600080fd5b506104f7610a05366004614888565b612e98565b348015610a1657600080fd5b506033546104bf906001600160a01b031681565b348015610a3657600080fd5b506104f7610a453660046142de565b612f1a565b610ac2604051806101a001604052806000815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600015158152602001600015158152602001600081525090565b506000908152603c602090815260409182902082516101a0810184528154815260018201546001600160a01b0316928101929092526002810154928201929092526003820154606082015260048201546080820152600982015460a0820152600a82015460c0820152600b82015460e0820152600c82015461010080830191909152600d830154610120830152600e83015460ff808216151561014085015291900416151561016082015260109091015461018082015290565b603f8181548110610b8c57600080fd5b6000918252602090912001546001600160a01b0316905081565b6033546001600160a01b03163314610c145760405162461bcd60e51b815260206004820152602660248201527f4e6f756e7344414f3a3a5f736574566f74696e67506572696f643a2061646d696044820152656e206f6e6c7960d01b60648201526084015b60405180910390fd5b611c208110158015610c295750620189c08111155b610c8f5760405162461bcd60e51b815260206004820152603160248201527f4e6f756e7344414f3a3a5f736574566f74696e67506572696f643a20696e76616044820152701b1a59081d9bdd1a5b99c81c195c9a5bd9607a1b6064820152608401610c0b565b603680549082905560408051828152602081018490527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e882891015b60405180910390a15050565b6033546001600160a01b03163314610d3d5760405162461bcd60e51b815260206004820152602560248201527f4e6f756e7344414f3a3a5f736574566f74696e6744656c61793a2061646d696e604482015264206f6e6c7960d81b6064820152608401610c0b565b60018110158015610d515750620189c08111155b610db55760405162461bcd60e51b815260206004820152602f60248201527f4e6f756e7344414f3a3a5f736574566f74696e6744656c61793a20696e76616c60448201526e696420766f74696e672064656c617960881b6064820152608401610c0b565b603580549082905560408051828152602081018490527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a939101610cc9565b6000610e08603854610e03611cf2565b61312a565b905090565b6060806060806000603c600087815260200190815260200160002090508060050181600601826007018360080183805480602002602001604051908101604052809291908181526020018280548015610e8f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e71575b5050505050935082805480602002602001604051908101604052809291908181526020018280548015610ee157602002820191906000526020600020905b815481526020019060010190808311610ecd575b5050505050925081805480602002602001604051908101604052809291908181526020016000905b82821015610fb5578382906000526020600020018054610f2890614c34565b80601f0160208091040260200160405190810160405280929190818152602001828054610f5490614c34565b8015610fa15780601f10610f7657610100808354040283529160200191610fa1565b820191906000526020600020905b815481529060010190602001808311610f8457829003601f168201915b505050505081526020019060010190610f09565b50505050915080805480602002602001604051908101604052809291908181526020016000905b82821015611088578382906000526020600020018054610ffb90614c34565b80601f016020809104026020016040519081016040528092919081815260200182805461102790614c34565b80156110745780601f1061104957610100808354040283529160200191611074565b820191906000526020600020905b81548152906001019060200180831161105757829003601f168201915b505050505081526020019060010190610fdc565b5050505090509450945094509450509193509193565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036110e65760405162461bcd60e51b8152600401610c0b90614c68565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661111861314a565b6001600160a01b03161461113e5760405162461bcd60e51b8152600401610c0b90614cb4565b61114781613178565b60408051600080825260208201909252611163918391906131e2565b50565b60408051808201825260098152684e6f756e732044414f60b81b60209182015281517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866818301527fe1dd93b3612547b4bb7c3d429f3df8508d84f5a4f63b5e2e44340b94698e6b3b81840152466060820152306080808301919091528351808303909101815260a0820184528051908301207f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f60c083015260e0820189905260ff8816610100808401919091528451808403909101815261012083019094528351939092019290922061190160f01b6101408401526101428301829052610162830181905290916000906101820160408051601f198184030181528282528051602091820120600080855291840180845281905260ff8a169284019290925260608301889052608083018790529092509060019060a0016020604051602081039080840390855afa1580156112df573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166113555760405162461bcd60e51b815260206004820152602a60248201527f4e6f756e7344414f3a3a63617374566f746542795369673a20696e76616c6964604482015269207369676e617475726560b01b6064820152608401610c0b565b88816001600160a01b03167fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda48a61138d858e8e61332d565b6040805160ff90931683526001600160601b039091166020830152606090820181905260009082015260800160405180910390a3505050505050505050565b6060603f80548060200260200160405190810160405280929190818152602001828054801561142457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611406575b5050505050905090565b600081603954101561148e5760405162461bcd60e51b8152602060048201526024808201527f4e6f756e7344414f3a3a73746174653a20696e76616c69642070726f706f73616044820152631b081a5960e21b6064820152608401610c0b565b6000828152603c60205260409020600e81015460ff16156114b25750600292915050565b806009015443116114c65750600092915050565b80600a015443116114da5750600192915050565b80600c015481600b01541115806114f85750806003015481600b0154105b156115065750600392915050565b806004015460000361151b5750600492915050565b600e810154610100900460ff16156115365750600792915050565b603a60009054906101000a90046001600160a01b03166001600160a01b031663c1a287e26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611589573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ad9190614d00565b81600401546115bc9190614d2f565b42106115cb5750600692915050565b50600592915050565b50919050565b60076115e58261142e565b60078111156115f6576115f66145d2565b0361165d5760405162461bcd60e51b815260206004820152603160248201527f4e6f756e7344414f3a3a63616e63656c3a2063616e6e6f742063616e63656c20604482015270195e1958dd5d1959081c1c9bdc1bdcd85b607a1b6064820152608401610c0b565b6000818152603c6020526040902060018101546001600160a01b031633148061172757506002810154603b546001808401546001600160a01b039283169263782d6fe1929116906116ae9043614d42565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa1580156116f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171b9190614d55565b6001600160601b031611155b6117865760405162461bcd60e51b815260206004820152602a60248201527f4e6f756e7344414f3a3a63616e63656c3a2070726f706f7365722061626f7665604482015269081d1a1c995cda1bdb1960b21b6064820152608401610c0b565b600e8101805460ff1916600117905560005b60058201548110156118b157603a546005830180546001600160a01b039092169163591fcdfe9190849081106117d0576117d0614d7e565b6000918252602090912001546006850180546001600160a01b0390921691859081106117fe576117fe614d7e565b906000526020600020015485600701858154811061181e5761181e614d7e565b9060005260206000200186600801868154811061183d5761183d614d7e565b9060005260206000200187600401546040518663ffffffff1660e01b815260040161186c959493929190614e11565b600060405180830381600087803b15801561188657600080fd5b505af115801561189a573d6000803e3d6000fd5b5050505080806118a990614e5d565b915050611798565b5060405182907f789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c90600090a25050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036119295760405162461bcd60e51b8152600401610c0b90614c68565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661195b61314a565b6001600160a01b0316146119815760405162461bcd60e51b8152600401610c0b90614cb4565b61198a82613178565b611996828260016131e2565b5050565b81337fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda4836119c983858361332d565b6040805160ff90931683526001600160601b039091166020830152606090820181905260009082015260800160405180910390a35050565b600260015403611a535760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610c0b565b6002600155611a6282826135fe565b6000603f805480602002602001604051908101604052809291908181526020018280548015611aba57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611a9c575b5050505050905060005b82811015611b2b57611afc848483818110611ae157611ae1614d7e565b9050602002016020810190611af69190614424565b836136db565b611b195760405163915de2bb60e01b815260040160405180910390fd5b80611b2381614e5d565b915050611ac4565b50611b6a858585858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061374092505050565b505060018055505050565b6033546001600160a01b03163314611be05760405162461bcd60e51b815260206004820152602860248201527f4e6f756e7344414f3a3a5f73657451756f72756d566f7465734250533a2061646044820152676d696e206f6e6c7960c01b6064820152608401610c0b565b60c88110158015611bf357506107d08111155b611c655760405162461bcd60e51b815260206004820152603f60248201527f4e6f756e7344414f3a3a5f73657451756f72756d566f7465734250533a20696e60448201527f76616c69642071756f72756d20766f74657320626173697320706f696e7473006064820152608401610c0b565b603880549082905560408051828152602081018490527fd73ab1b53ca7a080713bcecd1a0acb2066a6a6c3d2fd6d78b67ae5005e652d9b9101610cc9565b83337fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda485611cd283858361332d565b8686604051611ce49493929190614e76565b60405180910390a350505050565b603b546040805163f3a8225360e01b815290516000926001600160a01b03169163f3a822539160048083019260209291908290030181865afa158015611d3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d609190614d00565b603b54603a546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa158015611dac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd09190614d00565b603b60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e479190614d00565b611e519190614d42565b610e089190614d2f565b6033546001600160a01b03163314611ecc5760405162461bcd60e51b815260206004820152602e60248201527f4e6f756e7344414f3a3a5f73657450726f706f73616c5468726573686f6c644260448201526d50533a2061646d696e206f6e6c7960901b6064820152608401610c0b565b60018110158015611edf57506103e88111155b611f515760405162461bcd60e51b815260206004820152603b60248201527f4e6f756e7344414f3a3a5f73657450726f706f73616c5468726573686f6c643a60448201527f20696e76616c69642070726f706f73616c207468726573686f6c6400000000006064820152608401610c0b565b603780549082905560408051828152602081018490527ffc216faa269bf440fb06aa490693f409461bde9cdcb949c7b9f2cb79589e7a589101610cc9565b6000610e08603754610e03611cf2565b6033546001600160a01b031633146120085760405162461bcd60e51b815260206004820152602660248201527f4e6f756e7344414f3a3a5f73657450656e64696e6741646d696e3a2061646d696044820152656e206f6e6c7960d01b6064820152608401610c0b565b603480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a990600090a35050565b6002600154036120ac5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610c0b565b6002600155603f805460408051602080840282018101909252828152612113938693869383018282801561210957602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116120eb575b5050505050613740565b505060018055565b6000612125613b0c565b6121576040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b61215f611cf2565b80825260375461216e9161312a565b60208201819052603b546001600160a01b031663782d6fe133612192600143614d42565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa1580156121db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ff9190614d55565b6001600160601b03161161227b5760405162461bcd60e51b815260206004820152603a60248201527f4e6f756e7344414f3a3a70726f706f73653a2070726f706f73657220766f746560448201527f732062656c6f772070726f706f73616c207468726573686f6c640000000000006064820152608401610c0b565b8551875114801561228d575084518751145b801561229a575083518751145b61230c5760405162461bcd60e51b815260206004820152603f60248201527f4e6f756e7344414f3a3a70726f706f73653a2070726f706f73616c2066756e6360448201527f74696f6e20696e666f726d6174696f6e206172697479206d69736d61746368006064820152608401610c0b565b865160000361236d5760405162461bcd60e51b815260206004820152602760248201527f4e6f756e7344414f3a3a70726f706f73653a206d7573742070726f7669646520604482015266616374696f6e7360c81b6064820152608401610c0b565b600a875111156123cb5760405162461bcd60e51b815260206004820152602360248201527f4e6f756e7344414f3a3a70726f706f73653a20746f6f206d616e7920616374696044820152626f6e7360e81b6064820152608401610c0b565b336000908152603d60205260409081902054908201819052156125425760006123f7826040015161142e565b9050600181600781111561240d5761240d6145d2565b0361249c5760405162461bcd60e51b815260206004820152605360248201527f4e6f756e7344414f3a3a70726f706f73653a206f6e65206c6976652070726f7060448201527f6f73616c207065722070726f706f7365722c20666f756e6420616e20616c726560648201527218591e481858dd1a5d99481c1c9bdc1bdcd85b606a1b608482015260a401610c0b565b60008160078111156124b0576124b06145d2565b036125405760405162461bcd60e51b815260206004820152605460248201527f4e6f756e7344414f3a3a70726f706f73653a206f6e65206c6976652070726f7060448201527f6f73616c207065722070726f706f7365722c20666f756e6420616e20616c726560648201527318591e481c195b991a5b99c81c1c9bdc1bdcd85b60621b608482015260a401610c0b565b505b60355461254f9043614d2f565b6060820181905260365461256291614d2f565b60808201526039805490600061257783614e5d565b90915550506039546000818152603c602090815260409091209182556001820180546001600160a01b03191633179055820151600282015560385482516125be919061312a565b60038201556000600482015587516125df90600583019060208b01906140be565b5086516125f590600683019060208a0190614123565b50855161260b906007830190602089019061415e565b50845161262190600883019060208801906141b0565b506060820151600982019081556080830151600a83019081556000600b8401819055600c8401819055600d8401819055600e8401805461ffff19169055436010850155835460018501546001600160a01b03168252603d6020526040918290208190559254915490513393927f7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e0926126c4928e928e928e928e9291908e90614ebf565b60405180910390a3336001600160a01b031681600001547f6af0134faa0f9290c1d686d55012aca80302d31d5c856e4bc7954f7613dc7f878a8a8a8a876009015488600a015489600201548a600301548e60405161272a99989796959493929190614f3a565b60405180910390a354979650505050505050565b60046127498261142e565b600781111561275a5761275a6145d2565b146127cd5760405162461bcd60e51b815260206004820152603f60248201527f4e6f756e7344414f3a3a71756575653a2070726f706f73616c2063616e206f6e60448201527f6c792062652071756575656420696620697420697320737563636565646564006064820152608401610c0b565b6000818152603c60209081526040808320603a548251630d48571f60e31b815292519194936001600160a01b0390911692636a42b8f892600480830193928290030181865afa158015612824573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128489190614d00565b6128529042614d2f565b905060005b6005830154811015612a1c57612a0a83600501828154811061287b5761287b614d7e565b6000918252602090912001546006850180546001600160a01b0390921691849081106128a9576128a9614d7e565b90600052602060002001548560070184815481106128c9576128c9614d7e565b9060005260206000200180546128de90614c34565b80601f016020809104026020016040519081016040528092919081815260200182805461290a90614c34565b80156129575780601f1061292c57610100808354040283529160200191612957565b820191906000526020600020905b81548152906001019060200180831161293a57829003601f168201915b505050505086600801858154811061297157612971614d7e565b90600052602060002001805461298690614c34565b80601f01602080910402602001604051908101604052809291908181526020018280546129b290614c34565b80156129ff5780601f106129d4576101008083540402835291602001916129ff565b820191906000526020600020905b8154815290600101906020018083116129e257829003601f168201915b505050505086613c3f565b80612a1481614e5d565b915050612857565b506004820181905560405181815283907f9a2e42fd6722813d69113e7d0079d3d940171428df7373df9c7f7617cfda28929060200160405180910390a2505050565b604080516060808201835260008083526020808401829052928401819052858152603c83528381206001600160a01b0386168252600f018352839020835191820184525460ff8082161515835261010082041692820192909252620100009091046001600160601b0316918101919091525b92915050565b6034546001600160a01b031633148015612aef57503315155b612b4e5760405162461bcd60e51b815260206004820152602a60248201527f4e6f756e7344414f3a3a5f61636365707441646d696e3a2070656e64696e672060448201526961646d696e206f6e6c7960b01b6064820152608401610c0b565b60338054603480546001600160a01b03198084166001600160a01b0383811691821790965591169091556040519290911691819083907ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc90600090a36034546040516001600160a01b03918216918316907fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a990600090a35050565b612bf1613df1565b603a546001600160a01b031615612c615760405162461bcd60e51b815260206004820152602e60248201527f4e6f756e7344414f3a3a696e697469616c697a653a2063616e206f6e6c79206960448201526d6e697469616c697a65206f6e636560901b6064820152608401610c0b565b6001600160a01b038816612cce5760405162461bcd60e51b815260206004820152602e60248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c696420746960448201526d6d656c6f636b206164647265737360901b6064820152608401610c0b565b6001600160a01b038716612d385760405162461bcd60e51b815260206004820152602b60248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c6964206e6f60448201526a756e73206164647265737360a81b6064820152608401610c0b565b60365460408051918252602082018890527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e8828910160405180910390a160355460408051918252602082018790527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a93910160405180910390a160375460408051918252602082018690527ffc216faa269bf440fb06aa490693f409461bde9cdcb949c7b9f2cb79589e7a58910160405180910390a160385460408051918252602082018590527fd73ab1b53ca7a080713bcecd1a0acb2066a6a6c3d2fd6d78b67ae5005e652d9b910160405180910390a1603380546001600160a01b03199081166001600160a01b038b8116918217909355603a805483169091179055603b805490911691891691909117905560368690556035859055603784905560388390558151612e8b90603f9060208501906140be565b50603e5550505050505050565b6033546001600160a01b03163314612ec357604051633057182d60e21b815260040160405180910390fd5b612ecd82826135fe565b7fa060b0adf97c831e502683c3dfb7febfc9fd819f456b9bad900a1621bcb61a7e603f8383604051612f0193929190614fc7565b60405180910390a1612f15603f8383614202565b505050565b6005612f258261142e565b6007811115612f3657612f366145d2565b14612fab576040805162461bcd60e51b81526020600482015260248101919091527f4e6f756e7344414f3a3a657865637574653a2070726f706f73616c2063616e2060448201527f6f6e6c79206265206578656375746564206966206974206973207175657565646064820152608401610c0b565b6000818152603c60205260408120600e8101805461ff001916610100179055905b60058201548110156130fa57603a546005830180546001600160a01b0390921691630825f38f91908490811061300457613004614d7e565b6000918252602090912001546006850180546001600160a01b03909216918590811061303257613032614d7e565b906000526020600020015485600701858154811061305257613052614d7e565b9060005260206000200186600801868154811061307157613071614d7e565b9060005260206000200187600401546040518663ffffffff1660e01b81526004016130a0959493929190614e11565b6000604051808303816000875af11580156130bf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526130e7919081019061505d565b50806130f281614e5d565b915050612fcc565b5060405182907f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f90600090a25050565b600061271061313984846150d3565b61314391906150ea565b9392505050565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6033546001600160a01b031633146111635760405162461bcd60e51b815260206004820152602760248201527f4e6f756e7344414f3a3a5f617574686f72697a65557067726164653a2061646d604482015266696e206f6e6c7960c81b6064820152608401610c0b565b60006131ec61314a565b90506131f784613ea7565b6000835111806132045750815b15613215576132138484613f4c565b505b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143805460ff1661332657805460ff191660011781556040516001600160a01b038316602482015261329490869060440160408051601f198184030181529190526020810180516001600160e01b0316631b2ce7f360e11b179052613f4c565b50805460ff191681556132a561314a565b6001600160a01b0316826001600160a01b03161461331d5760405162461bcd60e51b815260206004820152602f60248201527f45524331393637557067726164653a207570677261646520627265616b73206660448201526e75727468657220757067726164657360881b6064820152608401610c0b565b61332685613f71565b5050505050565b6000600161333a8461142e565b600781111561334b5761334b6145d2565b146133ad5760405162461bcd60e51b815260206004820152602c60248201527f4e6f756e7344414f3a3a63617374566f7465496e7465726e616c3a20766f746960448201526b1b99c81a5cc818db1bdcd95960a21b6064820152608401610c0b565b60028260ff1611156134175760405162461bcd60e51b815260206004820152602d60248201527f4e6f756e7344414f3a3a63617374566f7465496e7465726e616c3a20696e766160448201526c6c696420766f7465207479706560981b6064820152608401610c0b565b6000838152603c602090815260408083206001600160a01b0388168452600f8101909252909120805460ff16156134a85760405162461bcd60e51b815260206004820152602f60248201527f4e6f756e7344414f3a3a63617374566f7465496e7465726e616c3a20766f746560448201526e1c88185b1c9958591e481d9bdd1959608a1b6064820152608401610c0b565b603b54601083015460405163782d6fe160e01b81526000926001600160a01b03169163782d6fe1916134f2918b916004016001600160a01b03929092168252602082015260400190565b602060405180830381865afa15801561350f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135339190614d55565b90508460ff1660000361356357806001600160601b031683600c01546135599190614d2f565b600c8401556135bb565b8460ff1660010361359157806001600160601b031683600b01546135879190614d2f565b600b8401556135bb565b8460ff166002036135bb57806001600160601b031683600d01546135b59190614d2f565b600d8401555b8154600161ffff1990911661010060ff88160217176dffffffffffffffffffffffff00001916620100006001600160601b03831602179091559150509392505050565b600081900361360b575050565b60005b613619600183614d42565b811015612f1557600061362d826001614d2f565b90505b828110156136c85783838281811061364a5761364a614d7e565b905060200201602081019061365f9190614424565b6001600160a01b031684848481811061367a5761367a614d7e565b905060200201602081019061368f9190614424565b6001600160a01b0316036136b657604051630254983f60e41b815260040160405180910390fd5b806136c081614e5d565b915050613630565b50806136d381614e5d565b91505061360e565b6000805b825181101561373657836001600160a01b031683828151811061370457613704614d7e565b60200260200101516001600160a01b031603613724576001915050612ad0565b8061372e81614e5d565b9150506136df565b5060009392505050565b613748613b0c565b6000613752611cf2565b905060005b8381101561380e57603b54603a546001600160a01b03918216916323b872dd9133911688888681811061378c5761378c614d7e565b6040516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909316602485015250602090910201356044820152606401600060405180830381600087803b1580156137e357600080fd5b505af11580156137f7573d6000803e3d6000fd5b50505050808061380690614e5d565b915050613757565b50600082516001600160401b0381111561382a5761382a614610565b604051908082528060200260200182016040528015613853578160200160208202803683370190505b50603a5490915060009083906138749087906001600160a01b0316316150d3565b61387e91906150ea565b905060005b84518110156139635760008582815181106138a0576138a0614d7e565b6020908102919091010151603a546040516370a0823160e01b81526001600160a01b039182166004820152919250869189918416906370a0823190602401602060405180830381865afa1580156138fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061391f9190614d00565b61392991906150d3565b61393391906150ea565b84838151811061394557613945614d7e565b6020908102919091010152508061395b81614e5d565b915050613883565b50603a546040516364a197f360e01b8152336004820152602481018390526001600160a01b03909116906364a197f390604401600060405180830381600087803b1580156139b057600080fd5b505af11580156139c4573d6000803e3d6000fd5b5050505060005b8451811015613ac05760008382815181106139e8576139e8614d7e565b60200260200101511115613aae57603a5485516001600160a01b0390911690638f975a64903390889085908110613a2157613a21614d7e565b6020026020010151868581518110613a3b57613a3b614d7e565b60209081029190910101516040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b158015613a9557600080fd5b505af1158015613aa9573d6000803e3d6000fd5b505050505b80613ab881614e5d565b9150506139cb565b50336001600160a01b03167ffa9e7cd97e6b4ce2e97ca568532b5a5ae075c6c9b14ce53de00f2d6b9d69d0848787604051613afc92919061510c565b60405180910390a2505050505050565b603b60009054906101000a90046001600160a01b03166001600160a01b0316637a6172cc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b839190614d00565b421015613ba35760405163c3e61f6560e01b815260040160405180910390fd5b603e5442108015613c1f5750603b546040805163f3a8225360e01b815290516000926001600160a01b03169163f3a822539160048083019260209291908290030181865afa158015613bf9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c1d9190614d00565b115b15613c3d57604051633598c21560e21b815260040160405180910390fd5b565b603a546040516001600160a01b039091169063f2b0653790613c6d9088908890889088908890602001615145565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b8152600401613ca191815260200190565b602060405180830381865afa158015613cbe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ce2919061517e565b15613d6e5760405162461bcd60e51b815260206004820152605060248201527f4e6f756e7344414f3a3a71756575654f72526576657274496e7465726e616c3a60448201527f206964656e746963616c2070726f706f73616c20616374696f6e20616c72656160648201526f6479207175657565642061742065746160801b608482015260a401610c0b565b603a54604051633a66f90160e01b81526001600160a01b0390911690633a66f90190613da69088908890889088908890600401615145565b6020604051808303816000875af1158015613dc5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613de99190614d00565b505050505050565b600054610100900460ff1680613e0a575060005460ff16155b613e6d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610c0b565b600054610100900460ff16158015613e8f576000805461ffff19166101011790555b600180558015611163576000805461ff001916905550565b803b613f0b5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610c0b565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b606061314383836040518060600160405280602781526020016152c260279139613fb1565b613f7a81613ea7565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060833b6140105760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610c0b565b600080856001600160a01b03168560405161402b91906151a0565b600060405180830381855af49150503d8060008114614066576040519150601f19603f3d011682016040523d82523d6000602084013e61406b565b606091505b509150915061407b828286614085565b9695505050505050565b60608315614094575081613143565b8251156140a45782518084602001fd5b8160405162461bcd60e51b8152600401610c0b91906143f5565b828054828255906000526020600020908101928215614113579160200282015b8281111561411357825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906140de565b5061411f929150614255565b5090565b828054828255906000526020600020908101928215614113579160200282015b82811115614113578251825591602001919060010190614143565b8280548282559060005260206000209081019282156141a4579160200282015b828111156141a457825182906141949082615202565b509160200191906001019061417e565b5061411f92915061426a565b8280548282559060005260206000209081019282156141f6579160200282015b828111156141f657825182906141e69082615202565b50916020019190600101906141d0565b5061411f929150614287565b828054828255906000526020600020908101928215614113579160200282015b828111156141135781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190614222565b5b8082111561411f5760008155600101614256565b8082111561411f57600061427e82826142a4565b5060010161426a565b8082111561411f57600061429b82826142a4565b50600101614287565b5080546142b090614c34565b6000825580601f106142c0575050565b601f0160209004906000526020600020908101906111639190614255565b6000602082840312156142f057600080fd5b5035919050565b815181526020808301516101a083019161431b908401826001600160a01b03169052565b5060408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e083015160e0830152610100808401518184015250610120808401518184015250610140808401516143848285018215159052565b50506101608381015180151584830152505061018092830151919092015290565b60005b838110156143c05781810151838201526020016143a8565b50506000910152565b600081518084526143e18160208601602086016143a5565b601f01601f19169290920160200192915050565b60208152600061314360208301846143c9565b80356001600160a01b038116811461441f57600080fd5b919050565b60006020828403121561443657600080fd5b61314382614408565b600081518084526020808501945080840160005b838110156144785781516001600160a01b031687529582019590820190600101614453565b509495945050505050565b600081518084526020808501945080840160005b8381101561447857815187529582019590820190600101614497565b600081518084526020808501808196508360051b8101915082860160005b858110156144fb5782840389526144e98483516143c9565b988501989350908401906001016144d1565b5091979650505050505050565b60808152600061451b608083018761443f565b828103602084015261452d8187614483565b9050828103604084015261454181866144b3565b9050828103606084015261455581856144b3565b979650505050505050565b803560ff8116811461441f57600080fd5b600080600080600060a0868803121561458957600080fd5b8535945061459960208701614560565b93506145a760408701614560565b94979396509394606081013594506080013592915050565b602081526000613143602083018461443f565b634e487b7160e01b600052602160045260246000fd5b602081016008831061460a57634e487b7160e01b600052602160045260246000fd5b91905290565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561464e5761464e614610565b604052919050565b60006001600160401b0382111561466f5761466f614610565b50601f01601f191660200190565b600082601f83011261468e57600080fd5b81356146a161469c82614656565b614626565b8181528460208386010111156146b657600080fd5b816020850160208301376000918101602001919091529392505050565b600080604083850312156146e657600080fd5b6146ef83614408565b915060208301356001600160401b0381111561470a57600080fd5b6147168582860161467d565b9150509250929050565b6000806040838503121561473357600080fd5b8235915061474360208401614560565b90509250929050565b60008083601f84011261475e57600080fd5b5081356001600160401b0381111561477557600080fd5b6020830191508360208260051b850101111561479057600080fd5b9250929050565b600080600080604085870312156147ad57600080fd5b84356001600160401b03808211156147c457600080fd5b6147d08883890161474c565b909650945060208701359150808211156147e957600080fd5b506147f68782880161474c565b95989497509550505050565b6000806000806060858703121561481857600080fd5b8435935061482860208601614560565b925060408501356001600160401b038082111561484457600080fd5b818701915087601f83011261485857600080fd5b81358181111561486757600080fd5b88602082850101111561487957600080fd5b95989497505060200194505050565b6000806020838503121561489b57600080fd5b82356001600160401b038111156148b157600080fd5b6148bd8582860161474c565b90969095509350505050565b60006001600160401b038211156148e2576148e2614610565b5060051b60200190565b600082601f8301126148fd57600080fd5b8135602061490d61469c836148c9565b82815260059290921b8401810191818101908684111561492c57600080fd5b8286015b8481101561494e5761494181614408565b8352918301918301614930565b509695505050505050565b600082601f83011261496a57600080fd5b8135602061497a61469c836148c9565b82815260059290921b8401810191818101908684111561499957600080fd5b8286015b8481101561494e578035835291830191830161499d565b600082601f8301126149c557600080fd5b813560206149d561469c836148c9565b82815260059290921b840181019181810190868411156149f457600080fd5b8286015b8481101561494e5780356001600160401b03811115614a175760008081fd5b614a258986838b010161467d565b8452509183019183016149f8565b600082601f830112614a4457600080fd5b81356020614a5461469c836148c9565b82815260059290921b84018101918181019086841115614a7357600080fd5b8286015b8481101561494e5780356001600160401b03811115614a965760008081fd5b614aa48986838b010161467d565b845250918301918301614a77565b600080600080600060a08688031215614aca57600080fd5b85356001600160401b0380821115614ae157600080fd5b614aed89838a016148ec565b96506020880135915080821115614b0357600080fd5b614b0f89838a01614959565b95506040880135915080821115614b2557600080fd5b614b3189838a016149b4565b94506060880135915080821115614b4757600080fd5b614b5389838a01614a33565b93506080880135915080821115614b6957600080fd5b50614b768882890161467d565b9150509295509295909350565b60008060408385031215614b9657600080fd5b8235915061474360208401614408565b600080600080600080600080610100898b031215614bc357600080fd5b614bcc89614408565b9750614bda60208a01614408565b965060408901359550606089013594506080890135935060a0890135925060c08901356001600160401b03811115614c1157600080fd5b614c1d8b828c016148ec565b92505060e089013590509295985092959890939650565b600181811c90821680614c4857607f821691505b6020821081036115d457634e487b7160e01b600052602260045260246000fd5b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215614d1257600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115612ad057612ad0614d19565b81810381811115612ad057612ad0614d19565b600060208284031215614d6757600080fd5b81516001600160601b038116811461314357600080fd5b634e487b7160e01b600052603260045260246000fd5b60008154614da181614c34565b808552602060018381168015614dbe5760018114614dd857614e06565b60ff1985168884015283151560051b880183019550614e06565b866000528260002060005b85811015614dfe5781548a8201860152908301908401614de3565b890184019650505b505050505092915050565b60018060a01b038616815284602082015260a060408201526000614e3860a0830186614d94565b8281036060840152614e4a8186614d94565b9150508260808301529695505050505050565b600060018201614e6f57614e6f614d19565b5060010190565b60ff851681526001600160601b038416602082015260606040820152816060820152818360808301376000818301608090810191909152601f909201601f191601019392505050565b60e081526000614ed260e083018a61443f565b8281036020840152614ee4818a614483565b90508281036040840152614ef881896144b3565b90508281036060840152614f0c81886144b3565b90508560808401528460a084015282810360c0840152614f2c81856143c9565b9a9950505050505050505050565b6000610120808352614f4e8184018d61443f565b90508281036020840152614f62818c614483565b90508281036040840152614f76818b6144b3565b90508281036060840152614f8a818a6144b3565b90508760808401528660a08401528560c08401528460e0840152828103610100840152614fb781856143c9565b9c9b505050505050505050505050565b6000604082016040835280865480835260608501915087600052602092508260002060005b828110156150115781546001600160a01b031684529284019260019182019101614fec565b505050838103828501528481528590820160005b86811015615051576001600160a01b0361503e84614408565b1682529183019190830190600101615025565b50979650505050505050565b60006020828403121561506f57600080fd5b81516001600160401b0381111561508557600080fd5b8201601f8101841361509657600080fd5b80516150a461469c82614656565b8181528560208385010111156150b957600080fd5b6150ca8260208301602086016143a5565b95945050505050565b8082028115828204841417612ad057612ad0614d19565b60008261510757634e487b7160e01b600052601260045260246000fd5b500490565b6020808252810182905260006001600160fb1b0383111561512c57600080fd5b8260051b80856040850137919091016040019392505050565b60018060a01b038616815284602082015260a06040820152600061516c60a08301866143c9565b8281036060840152614e4a81866143c9565b60006020828403121561519057600080fd5b8151801515811461314357600080fd5b600082516151b28184602087016143a5565b9190910192915050565b601f821115612f1557600081815260208120601f850160051c810160208610156151e35750805b601f850160051c820191505b81811015613de9578281556001016151ef565b81516001600160401b0381111561521b5761521b614610565b61522f816152298454614c34565b846151bc565b602080601f831160018114615264576000841561524c5750858301515b600019600386901b1c1916600185901b178555613de9565b600085815260208120601f198616915b8281101561529357888601518255948401946001909101908401615274565b50858210156152b15787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212200f55210d075eef43e92a4c02d5d18251edd52581c7c91fc96108776145ad2c2864736f6c63430008130033
Deployed Bytecode
0x6080604052600436106102ff5760003560e01c80636f3eff2811610190578063d23c2953116100dc578063e23a9a5211610095578063f56ac09c1161006f578063f56ac09c146109ca578063f58e26cb146109ea578063f851a44014610a0a578063fe0d94c114610a2a57600080fd5b8063e23a9a5214610965578063e48083fe14610886578063e9c714f2146109b557600080fd5b8063d23c29531461089b578063d33219b4146108bb578063da35c664146108db578063da95691a146108f1578063ddf0b00914610911578063deaaa7cc1461093157600080fd5b806397d048e511610149578063b58131b011610123578063b58131b01461083b578063b71d1a0c14610850578063bb67758214610870578063c82fbd081461088657600080fd5b806397d048e514610804578063a64e024a14610824578063b11262631461082457600080fd5b80636f3eff281461076e5780637b3c71d31461078e5780637bdbe4d0146107ae5780637f9262fd146107c357806383cce0e1146107d95780638f1314b6146107ef57600080fd5b806324bc1a641161024f5780633bccf4fd1161020857806340e58ee5116101e257806340e58ee5146106fb5780634f1ef2861461071b578063567813881461072e57806368e981a71461074e57600080fd5b80633bccf4fd1461068c5780633e3dad99146106ac5780633e4f49e6146106ce57600080fd5b806324bc1a64146105d157806326782247146105e65780632de45f1814610606578063328dd982146106265780633659cfe6146106565780633932abb11461067657600080fd5b806314a67ea4116102bc5780631e7b5d3a116102965780631e7b5d3a1461055c57806320606b7014610572578063215809ca146105a65780632230e155146105bc57600080fd5b806314a67ea4146104f957806317977c611461050f5780631dfb1b5a1461053c57600080fd5b8063013cf08b1461030457806302a251a31461033a57806306fdde031461035e5780630a494840146103a05780630a7473b81461049f5780630ea2d98c146104d7575b600080fd5b34801561031057600080fd5b5061032461031f3660046142de565b610a4a565b60405161033191906142f7565b60405180910390f35b34801561034657600080fd5b5061035060365481565b604051908152602001610331565b34801561036a57600080fd5b50610393604051806040016040528060098152602001684e6f756e732044414f60b81b81525081565b60405161033191906143f5565b3480156103ac57600080fd5b506104316103bb3660046142de565b603c602052600090815260409020805460018201546002830154600384015460048501546009860154600a870154600b880154600c890154600d8a0154600e8b01546010909b0154999a6001600160a01b03909916999798969795969495939492939192909160ff80831692610100900416908d565b604080519d8e526001600160a01b03909c1660208e01529a8c019990995260608b019790975260808a019590955260a089019390935260c088019190915260e0870152610100860152610120850152151561014084015215156101608301526101808201526101a001610331565b3480156104ab57600080fd5b506104bf6104ba3660046142de565b610b7c565b6040516001600160a01b039091168152602001610331565b3480156104e357600080fd5b506104f76104f23660046142de565b610ba6565b005b34801561050557600080fd5b5061035060375481565b34801561051b57600080fd5b5061035061052a366004614424565b603d6020526000908152604090205481565b34801561054857600080fd5b506104f76105573660046142de565b610cd5565b34801561056857600080fd5b506103506103e881565b34801561057e57600080fd5b506103507f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b3480156105b257600080fd5b50610350611c2081565b3480156105c857600080fd5b5061035060c881565b3480156105dd57600080fd5b50610350610df3565b3480156105f257600080fd5b506034546104bf906001600160a01b031681565b34801561061257600080fd5b50603b546104bf906001600160a01b031681565b34801561063257600080fd5b506106466106413660046142de565b610e0d565b6040516103319493929190614508565b34801561066257600080fd5b506104f7610671366004614424565b61109e565b34801561068257600080fd5b5061035060355481565b34801561069857600080fd5b506104f76106a7366004614571565b611166565b3480156106b857600080fd5b506106c16113cc565b60405161033191906145bf565b3480156106da57600080fd5b506106ee6106e93660046142de565b61142e565b60405161033191906145e8565b34801561070757600080fd5b506104f76107163660046142de565b6115da565b6104f76107293660046146d3565b6118e1565b34801561073a57600080fd5b506104f7610749366004614720565b61199a565b34801561075a57600080fd5b506104f7610769366004614797565b611a01565b34801561077a57600080fd5b506104f76107893660046142de565b611b75565b34801561079a57600080fd5b506104f76107a9366004614802565b611ca3565b3480156107ba57600080fd5b50610350600a81565b3480156107cf57600080fd5b50610350603e5481565b3480156107e557600080fd5b5061035060385481565b3480156107fb57600080fd5b50610350611cf2565b34801561081057600080fd5b506104f761081f3660046142de565b611e5b565b34801561083057600080fd5b50610350620189c081565b34801561084757600080fd5b50610350611f8f565b34801561085c57600080fd5b506104f761086b366004614424565b611f9f565b34801561087c57600080fd5b506103506107d081565b34801561089257600080fd5b50610350600181565b3480156108a757600080fd5b506104f76108b6366004614888565b61205a565b3480156108c757600080fd5b50603a546104bf906001600160a01b031681565b3480156108e757600080fd5b5061035060395481565b3480156108fd57600080fd5b5061035061090c366004614ab2565b61211b565b34801561091d57600080fd5b506104f761092c3660046142de565b61273e565b34801561093d57600080fd5b506103507f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f81565b34801561097157600080fd5b50610985610980366004614b83565b612a5e565b6040805182511515815260208084015160ff1690820152918101516001600160601b031690820152606001610331565b3480156109c157600080fd5b506104f7612ad6565b3480156109d657600080fd5b506104f76109e5366004614ba6565b612be9565b3480156109f657600080fd5b506104f7610a05366004614888565b612e98565b348015610a1657600080fd5b506033546104bf906001600160a01b031681565b348015610a3657600080fd5b506104f7610a453660046142de565b612f1a565b610ac2604051806101a001604052806000815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600015158152602001600015158152602001600081525090565b506000908152603c602090815260409182902082516101a0810184528154815260018201546001600160a01b0316928101929092526002810154928201929092526003820154606082015260048201546080820152600982015460a0820152600a82015460c0820152600b82015460e0820152600c82015461010080830191909152600d830154610120830152600e83015460ff808216151561014085015291900416151561016082015260109091015461018082015290565b603f8181548110610b8c57600080fd5b6000918252602090912001546001600160a01b0316905081565b6033546001600160a01b03163314610c145760405162461bcd60e51b815260206004820152602660248201527f4e6f756e7344414f3a3a5f736574566f74696e67506572696f643a2061646d696044820152656e206f6e6c7960d01b60648201526084015b60405180910390fd5b611c208110158015610c295750620189c08111155b610c8f5760405162461bcd60e51b815260206004820152603160248201527f4e6f756e7344414f3a3a5f736574566f74696e67506572696f643a20696e76616044820152701b1a59081d9bdd1a5b99c81c195c9a5bd9607a1b6064820152608401610c0b565b603680549082905560408051828152602081018490527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e882891015b60405180910390a15050565b6033546001600160a01b03163314610d3d5760405162461bcd60e51b815260206004820152602560248201527f4e6f756e7344414f3a3a5f736574566f74696e6744656c61793a2061646d696e604482015264206f6e6c7960d81b6064820152608401610c0b565b60018110158015610d515750620189c08111155b610db55760405162461bcd60e51b815260206004820152602f60248201527f4e6f756e7344414f3a3a5f736574566f74696e6744656c61793a20696e76616c60448201526e696420766f74696e672064656c617960881b6064820152608401610c0b565b603580549082905560408051828152602081018490527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a939101610cc9565b6000610e08603854610e03611cf2565b61312a565b905090565b6060806060806000603c600087815260200190815260200160002090508060050181600601826007018360080183805480602002602001604051908101604052809291908181526020018280548015610e8f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e71575b5050505050935082805480602002602001604051908101604052809291908181526020018280548015610ee157602002820191906000526020600020905b815481526020019060010190808311610ecd575b5050505050925081805480602002602001604051908101604052809291908181526020016000905b82821015610fb5578382906000526020600020018054610f2890614c34565b80601f0160208091040260200160405190810160405280929190818152602001828054610f5490614c34565b8015610fa15780601f10610f7657610100808354040283529160200191610fa1565b820191906000526020600020905b815481529060010190602001808311610f8457829003601f168201915b505050505081526020019060010190610f09565b50505050915080805480602002602001604051908101604052809291908181526020016000905b82821015611088578382906000526020600020018054610ffb90614c34565b80601f016020809104026020016040519081016040528092919081815260200182805461102790614c34565b80156110745780601f1061104957610100808354040283529160200191611074565b820191906000526020600020905b81548152906001019060200180831161105757829003601f168201915b505050505081526020019060010190610fdc565b5050505090509450945094509450509193509193565b6001600160a01b037f000000000000000000000000c2fdade21b35c9e84b7cc6155b1a2774f622e5731630036110e65760405162461bcd60e51b8152600401610c0b90614c68565b7f000000000000000000000000c2fdade21b35c9e84b7cc6155b1a2774f622e5736001600160a01b031661111861314a565b6001600160a01b03161461113e5760405162461bcd60e51b8152600401610c0b90614cb4565b61114781613178565b60408051600080825260208201909252611163918391906131e2565b50565b60408051808201825260098152684e6f756e732044414f60b81b60209182015281517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866818301527fe1dd93b3612547b4bb7c3d429f3df8508d84f5a4f63b5e2e44340b94698e6b3b81840152466060820152306080808301919091528351808303909101815260a0820184528051908301207f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f60c083015260e0820189905260ff8816610100808401919091528451808403909101815261012083019094528351939092019290922061190160f01b6101408401526101428301829052610162830181905290916000906101820160408051601f198184030181528282528051602091820120600080855291840180845281905260ff8a169284019290925260608301889052608083018790529092509060019060a0016020604051602081039080840390855afa1580156112df573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166113555760405162461bcd60e51b815260206004820152602a60248201527f4e6f756e7344414f3a3a63617374566f746542795369673a20696e76616c6964604482015269207369676e617475726560b01b6064820152608401610c0b565b88816001600160a01b03167fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda48a61138d858e8e61332d565b6040805160ff90931683526001600160601b039091166020830152606090820181905260009082015260800160405180910390a3505050505050505050565b6060603f80548060200260200160405190810160405280929190818152602001828054801561142457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611406575b5050505050905090565b600081603954101561148e5760405162461bcd60e51b8152602060048201526024808201527f4e6f756e7344414f3a3a73746174653a20696e76616c69642070726f706f73616044820152631b081a5960e21b6064820152608401610c0b565b6000828152603c60205260409020600e81015460ff16156114b25750600292915050565b806009015443116114c65750600092915050565b80600a015443116114da5750600192915050565b80600c015481600b01541115806114f85750806003015481600b0154105b156115065750600392915050565b806004015460000361151b5750600492915050565b600e810154610100900460ff16156115365750600792915050565b603a60009054906101000a90046001600160a01b03166001600160a01b031663c1a287e26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611589573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ad9190614d00565b81600401546115bc9190614d2f565b42106115cb5750600692915050565b50600592915050565b50919050565b60076115e58261142e565b60078111156115f6576115f66145d2565b0361165d5760405162461bcd60e51b815260206004820152603160248201527f4e6f756e7344414f3a3a63616e63656c3a2063616e6e6f742063616e63656c20604482015270195e1958dd5d1959081c1c9bdc1bdcd85b607a1b6064820152608401610c0b565b6000818152603c6020526040902060018101546001600160a01b031633148061172757506002810154603b546001808401546001600160a01b039283169263782d6fe1929116906116ae9043614d42565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa1580156116f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171b9190614d55565b6001600160601b031611155b6117865760405162461bcd60e51b815260206004820152602a60248201527f4e6f756e7344414f3a3a63616e63656c3a2070726f706f7365722061626f7665604482015269081d1a1c995cda1bdb1960b21b6064820152608401610c0b565b600e8101805460ff1916600117905560005b60058201548110156118b157603a546005830180546001600160a01b039092169163591fcdfe9190849081106117d0576117d0614d7e565b6000918252602090912001546006850180546001600160a01b0390921691859081106117fe576117fe614d7e565b906000526020600020015485600701858154811061181e5761181e614d7e565b9060005260206000200186600801868154811061183d5761183d614d7e565b9060005260206000200187600401546040518663ffffffff1660e01b815260040161186c959493929190614e11565b600060405180830381600087803b15801561188657600080fd5b505af115801561189a573d6000803e3d6000fd5b5050505080806118a990614e5d565b915050611798565b5060405182907f789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c90600090a25050565b6001600160a01b037f000000000000000000000000c2fdade21b35c9e84b7cc6155b1a2774f622e5731630036119295760405162461bcd60e51b8152600401610c0b90614c68565b7f000000000000000000000000c2fdade21b35c9e84b7cc6155b1a2774f622e5736001600160a01b031661195b61314a565b6001600160a01b0316146119815760405162461bcd60e51b8152600401610c0b90614cb4565b61198a82613178565b611996828260016131e2565b5050565b81337fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda4836119c983858361332d565b6040805160ff90931683526001600160601b039091166020830152606090820181905260009082015260800160405180910390a35050565b600260015403611a535760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610c0b565b6002600155611a6282826135fe565b6000603f805480602002602001604051908101604052809291908181526020018280548015611aba57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611a9c575b5050505050905060005b82811015611b2b57611afc848483818110611ae157611ae1614d7e565b9050602002016020810190611af69190614424565b836136db565b611b195760405163915de2bb60e01b815260040160405180910390fd5b80611b2381614e5d565b915050611ac4565b50611b6a858585858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061374092505050565b505060018055505050565b6033546001600160a01b03163314611be05760405162461bcd60e51b815260206004820152602860248201527f4e6f756e7344414f3a3a5f73657451756f72756d566f7465734250533a2061646044820152676d696e206f6e6c7960c01b6064820152608401610c0b565b60c88110158015611bf357506107d08111155b611c655760405162461bcd60e51b815260206004820152603f60248201527f4e6f756e7344414f3a3a5f73657451756f72756d566f7465734250533a20696e60448201527f76616c69642071756f72756d20766f74657320626173697320706f696e7473006064820152608401610c0b565b603880549082905560408051828152602081018490527fd73ab1b53ca7a080713bcecd1a0acb2066a6a6c3d2fd6d78b67ae5005e652d9b9101610cc9565b83337fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda485611cd283858361332d565b8686604051611ce49493929190614e76565b60405180910390a350505050565b603b546040805163f3a8225360e01b815290516000926001600160a01b03169163f3a822539160048083019260209291908290030181865afa158015611d3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d609190614d00565b603b54603a546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa158015611dac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd09190614d00565b603b60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e479190614d00565b611e519190614d42565b610e089190614d2f565b6033546001600160a01b03163314611ecc5760405162461bcd60e51b815260206004820152602e60248201527f4e6f756e7344414f3a3a5f73657450726f706f73616c5468726573686f6c644260448201526d50533a2061646d696e206f6e6c7960901b6064820152608401610c0b565b60018110158015611edf57506103e88111155b611f515760405162461bcd60e51b815260206004820152603b60248201527f4e6f756e7344414f3a3a5f73657450726f706f73616c5468726573686f6c643a60448201527f20696e76616c69642070726f706f73616c207468726573686f6c6400000000006064820152608401610c0b565b603780549082905560408051828152602081018490527ffc216faa269bf440fb06aa490693f409461bde9cdcb949c7b9f2cb79589e7a589101610cc9565b6000610e08603754610e03611cf2565b6033546001600160a01b031633146120085760405162461bcd60e51b815260206004820152602660248201527f4e6f756e7344414f3a3a5f73657450656e64696e6741646d696e3a2061646d696044820152656e206f6e6c7960d01b6064820152608401610c0b565b603480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a990600090a35050565b6002600154036120ac5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610c0b565b6002600155603f805460408051602080840282018101909252828152612113938693869383018282801561210957602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116120eb575b5050505050613740565b505060018055565b6000612125613b0c565b6121576040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b61215f611cf2565b80825260375461216e9161312a565b60208201819052603b546001600160a01b031663782d6fe133612192600143614d42565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa1580156121db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ff9190614d55565b6001600160601b03161161227b5760405162461bcd60e51b815260206004820152603a60248201527f4e6f756e7344414f3a3a70726f706f73653a2070726f706f73657220766f746560448201527f732062656c6f772070726f706f73616c207468726573686f6c640000000000006064820152608401610c0b565b8551875114801561228d575084518751145b801561229a575083518751145b61230c5760405162461bcd60e51b815260206004820152603f60248201527f4e6f756e7344414f3a3a70726f706f73653a2070726f706f73616c2066756e6360448201527f74696f6e20696e666f726d6174696f6e206172697479206d69736d61746368006064820152608401610c0b565b865160000361236d5760405162461bcd60e51b815260206004820152602760248201527f4e6f756e7344414f3a3a70726f706f73653a206d7573742070726f7669646520604482015266616374696f6e7360c81b6064820152608401610c0b565b600a875111156123cb5760405162461bcd60e51b815260206004820152602360248201527f4e6f756e7344414f3a3a70726f706f73653a20746f6f206d616e7920616374696044820152626f6e7360e81b6064820152608401610c0b565b336000908152603d60205260409081902054908201819052156125425760006123f7826040015161142e565b9050600181600781111561240d5761240d6145d2565b0361249c5760405162461bcd60e51b815260206004820152605360248201527f4e6f756e7344414f3a3a70726f706f73653a206f6e65206c6976652070726f7060448201527f6f73616c207065722070726f706f7365722c20666f756e6420616e20616c726560648201527218591e481858dd1a5d99481c1c9bdc1bdcd85b606a1b608482015260a401610c0b565b60008160078111156124b0576124b06145d2565b036125405760405162461bcd60e51b815260206004820152605460248201527f4e6f756e7344414f3a3a70726f706f73653a206f6e65206c6976652070726f7060448201527f6f73616c207065722070726f706f7365722c20666f756e6420616e20616c726560648201527318591e481c195b991a5b99c81c1c9bdc1bdcd85b60621b608482015260a401610c0b565b505b60355461254f9043614d2f565b6060820181905260365461256291614d2f565b60808201526039805490600061257783614e5d565b90915550506039546000818152603c602090815260409091209182556001820180546001600160a01b03191633179055820151600282015560385482516125be919061312a565b60038201556000600482015587516125df90600583019060208b01906140be565b5086516125f590600683019060208a0190614123565b50855161260b906007830190602089019061415e565b50845161262190600883019060208801906141b0565b506060820151600982019081556080830151600a83019081556000600b8401819055600c8401819055600d8401819055600e8401805461ffff19169055436010850155835460018501546001600160a01b03168252603d6020526040918290208190559254915490513393927f7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e0926126c4928e928e928e928e9291908e90614ebf565b60405180910390a3336001600160a01b031681600001547f6af0134faa0f9290c1d686d55012aca80302d31d5c856e4bc7954f7613dc7f878a8a8a8a876009015488600a015489600201548a600301548e60405161272a99989796959493929190614f3a565b60405180910390a354979650505050505050565b60046127498261142e565b600781111561275a5761275a6145d2565b146127cd5760405162461bcd60e51b815260206004820152603f60248201527f4e6f756e7344414f3a3a71756575653a2070726f706f73616c2063616e206f6e60448201527f6c792062652071756575656420696620697420697320737563636565646564006064820152608401610c0b565b6000818152603c60209081526040808320603a548251630d48571f60e31b815292519194936001600160a01b0390911692636a42b8f892600480830193928290030181865afa158015612824573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128489190614d00565b6128529042614d2f565b905060005b6005830154811015612a1c57612a0a83600501828154811061287b5761287b614d7e565b6000918252602090912001546006850180546001600160a01b0390921691849081106128a9576128a9614d7e565b90600052602060002001548560070184815481106128c9576128c9614d7e565b9060005260206000200180546128de90614c34565b80601f016020809104026020016040519081016040528092919081815260200182805461290a90614c34565b80156129575780601f1061292c57610100808354040283529160200191612957565b820191906000526020600020905b81548152906001019060200180831161293a57829003601f168201915b505050505086600801858154811061297157612971614d7e565b90600052602060002001805461298690614c34565b80601f01602080910402602001604051908101604052809291908181526020018280546129b290614c34565b80156129ff5780601f106129d4576101008083540402835291602001916129ff565b820191906000526020600020905b8154815290600101906020018083116129e257829003601f168201915b505050505086613c3f565b80612a1481614e5d565b915050612857565b506004820181905560405181815283907f9a2e42fd6722813d69113e7d0079d3d940171428df7373df9c7f7617cfda28929060200160405180910390a2505050565b604080516060808201835260008083526020808401829052928401819052858152603c83528381206001600160a01b0386168252600f018352839020835191820184525460ff8082161515835261010082041692820192909252620100009091046001600160601b0316918101919091525b92915050565b6034546001600160a01b031633148015612aef57503315155b612b4e5760405162461bcd60e51b815260206004820152602a60248201527f4e6f756e7344414f3a3a5f61636365707441646d696e3a2070656e64696e672060448201526961646d696e206f6e6c7960b01b6064820152608401610c0b565b60338054603480546001600160a01b03198084166001600160a01b0383811691821790965591169091556040519290911691819083907ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc90600090a36034546040516001600160a01b03918216918316907fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a990600090a35050565b612bf1613df1565b603a546001600160a01b031615612c615760405162461bcd60e51b815260206004820152602e60248201527f4e6f756e7344414f3a3a696e697469616c697a653a2063616e206f6e6c79206960448201526d6e697469616c697a65206f6e636560901b6064820152608401610c0b565b6001600160a01b038816612cce5760405162461bcd60e51b815260206004820152602e60248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c696420746960448201526d6d656c6f636b206164647265737360901b6064820152608401610c0b565b6001600160a01b038716612d385760405162461bcd60e51b815260206004820152602b60248201527f4e6f756e7344414f3a3a696e697469616c697a653a20696e76616c6964206e6f60448201526a756e73206164647265737360a81b6064820152608401610c0b565b60365460408051918252602082018890527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e8828910160405180910390a160355460408051918252602082018790527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a93910160405180910390a160375460408051918252602082018690527ffc216faa269bf440fb06aa490693f409461bde9cdcb949c7b9f2cb79589e7a58910160405180910390a160385460408051918252602082018590527fd73ab1b53ca7a080713bcecd1a0acb2066a6a6c3d2fd6d78b67ae5005e652d9b910160405180910390a1603380546001600160a01b03199081166001600160a01b038b8116918217909355603a805483169091179055603b805490911691891691909117905560368690556035859055603784905560388390558151612e8b90603f9060208501906140be565b50603e5550505050505050565b6033546001600160a01b03163314612ec357604051633057182d60e21b815260040160405180910390fd5b612ecd82826135fe565b7fa060b0adf97c831e502683c3dfb7febfc9fd819f456b9bad900a1621bcb61a7e603f8383604051612f0193929190614fc7565b60405180910390a1612f15603f8383614202565b505050565b6005612f258261142e565b6007811115612f3657612f366145d2565b14612fab576040805162461bcd60e51b81526020600482015260248101919091527f4e6f756e7344414f3a3a657865637574653a2070726f706f73616c2063616e2060448201527f6f6e6c79206265206578656375746564206966206974206973207175657565646064820152608401610c0b565b6000818152603c60205260408120600e8101805461ff001916610100179055905b60058201548110156130fa57603a546005830180546001600160a01b0390921691630825f38f91908490811061300457613004614d7e565b6000918252602090912001546006850180546001600160a01b03909216918590811061303257613032614d7e565b906000526020600020015485600701858154811061305257613052614d7e565b9060005260206000200186600801868154811061307157613071614d7e565b9060005260206000200187600401546040518663ffffffff1660e01b81526004016130a0959493929190614e11565b6000604051808303816000875af11580156130bf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526130e7919081019061505d565b50806130f281614e5d565b915050612fcc565b5060405182907f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f90600090a25050565b600061271061313984846150d3565b61314391906150ea565b9392505050565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6033546001600160a01b031633146111635760405162461bcd60e51b815260206004820152602760248201527f4e6f756e7344414f3a3a5f617574686f72697a65557067726164653a2061646d604482015266696e206f6e6c7960c81b6064820152608401610c0b565b60006131ec61314a565b90506131f784613ea7565b6000835111806132045750815b15613215576132138484613f4c565b505b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143805460ff1661332657805460ff191660011781556040516001600160a01b038316602482015261329490869060440160408051601f198184030181529190526020810180516001600160e01b0316631b2ce7f360e11b179052613f4c565b50805460ff191681556132a561314a565b6001600160a01b0316826001600160a01b03161461331d5760405162461bcd60e51b815260206004820152602f60248201527f45524331393637557067726164653a207570677261646520627265616b73206660448201526e75727468657220757067726164657360881b6064820152608401610c0b565b61332685613f71565b5050505050565b6000600161333a8461142e565b600781111561334b5761334b6145d2565b146133ad5760405162461bcd60e51b815260206004820152602c60248201527f4e6f756e7344414f3a3a63617374566f7465496e7465726e616c3a20766f746960448201526b1b99c81a5cc818db1bdcd95960a21b6064820152608401610c0b565b60028260ff1611156134175760405162461bcd60e51b815260206004820152602d60248201527f4e6f756e7344414f3a3a63617374566f7465496e7465726e616c3a20696e766160448201526c6c696420766f7465207479706560981b6064820152608401610c0b565b6000838152603c602090815260408083206001600160a01b0388168452600f8101909252909120805460ff16156134a85760405162461bcd60e51b815260206004820152602f60248201527f4e6f756e7344414f3a3a63617374566f7465496e7465726e616c3a20766f746560448201526e1c88185b1c9958591e481d9bdd1959608a1b6064820152608401610c0b565b603b54601083015460405163782d6fe160e01b81526000926001600160a01b03169163782d6fe1916134f2918b916004016001600160a01b03929092168252602082015260400190565b602060405180830381865afa15801561350f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135339190614d55565b90508460ff1660000361356357806001600160601b031683600c01546135599190614d2f565b600c8401556135bb565b8460ff1660010361359157806001600160601b031683600b01546135879190614d2f565b600b8401556135bb565b8460ff166002036135bb57806001600160601b031683600d01546135b59190614d2f565b600d8401555b8154600161ffff1990911661010060ff88160217176dffffffffffffffffffffffff00001916620100006001600160601b03831602179091559150509392505050565b600081900361360b575050565b60005b613619600183614d42565b811015612f1557600061362d826001614d2f565b90505b828110156136c85783838281811061364a5761364a614d7e565b905060200201602081019061365f9190614424565b6001600160a01b031684848481811061367a5761367a614d7e565b905060200201602081019061368f9190614424565b6001600160a01b0316036136b657604051630254983f60e41b815260040160405180910390fd5b806136c081614e5d565b915050613630565b50806136d381614e5d565b91505061360e565b6000805b825181101561373657836001600160a01b031683828151811061370457613704614d7e565b60200260200101516001600160a01b031603613724576001915050612ad0565b8061372e81614e5d565b9150506136df565b5060009392505050565b613748613b0c565b6000613752611cf2565b905060005b8381101561380e57603b54603a546001600160a01b03918216916323b872dd9133911688888681811061378c5761378c614d7e565b6040516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909316602485015250602090910201356044820152606401600060405180830381600087803b1580156137e357600080fd5b505af11580156137f7573d6000803e3d6000fd5b50505050808061380690614e5d565b915050613757565b50600082516001600160401b0381111561382a5761382a614610565b604051908082528060200260200182016040528015613853578160200160208202803683370190505b50603a5490915060009083906138749087906001600160a01b0316316150d3565b61387e91906150ea565b905060005b84518110156139635760008582815181106138a0576138a0614d7e565b6020908102919091010151603a546040516370a0823160e01b81526001600160a01b039182166004820152919250869189918416906370a0823190602401602060405180830381865afa1580156138fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061391f9190614d00565b61392991906150d3565b61393391906150ea565b84838151811061394557613945614d7e565b6020908102919091010152508061395b81614e5d565b915050613883565b50603a546040516364a197f360e01b8152336004820152602481018390526001600160a01b03909116906364a197f390604401600060405180830381600087803b1580156139b057600080fd5b505af11580156139c4573d6000803e3d6000fd5b5050505060005b8451811015613ac05760008382815181106139e8576139e8614d7e565b60200260200101511115613aae57603a5485516001600160a01b0390911690638f975a64903390889085908110613a2157613a21614d7e565b6020026020010151868581518110613a3b57613a3b614d7e565b60209081029190910101516040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b158015613a9557600080fd5b505af1158015613aa9573d6000803e3d6000fd5b505050505b80613ab881614e5d565b9150506139cb565b50336001600160a01b03167ffa9e7cd97e6b4ce2e97ca568532b5a5ae075c6c9b14ce53de00f2d6b9d69d0848787604051613afc92919061510c565b60405180910390a2505050505050565b603b60009054906101000a90046001600160a01b03166001600160a01b0316637a6172cc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b839190614d00565b421015613ba35760405163c3e61f6560e01b815260040160405180910390fd5b603e5442108015613c1f5750603b546040805163f3a8225360e01b815290516000926001600160a01b03169163f3a822539160048083019260209291908290030181865afa158015613bf9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c1d9190614d00565b115b15613c3d57604051633598c21560e21b815260040160405180910390fd5b565b603a546040516001600160a01b039091169063f2b0653790613c6d9088908890889088908890602001615145565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b8152600401613ca191815260200190565b602060405180830381865afa158015613cbe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ce2919061517e565b15613d6e5760405162461bcd60e51b815260206004820152605060248201527f4e6f756e7344414f3a3a71756575654f72526576657274496e7465726e616c3a60448201527f206964656e746963616c2070726f706f73616c20616374696f6e20616c72656160648201526f6479207175657565642061742065746160801b608482015260a401610c0b565b603a54604051633a66f90160e01b81526001600160a01b0390911690633a66f90190613da69088908890889088908890600401615145565b6020604051808303816000875af1158015613dc5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613de99190614d00565b505050505050565b600054610100900460ff1680613e0a575060005460ff16155b613e6d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610c0b565b600054610100900460ff16158015613e8f576000805461ffff19166101011790555b600180558015611163576000805461ff001916905550565b803b613f0b5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610c0b565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b606061314383836040518060600160405280602781526020016152c260279139613fb1565b613f7a81613ea7565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060833b6140105760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610c0b565b600080856001600160a01b03168560405161402b91906151a0565b600060405180830381855af49150503d8060008114614066576040519150601f19603f3d011682016040523d82523d6000602084013e61406b565b606091505b509150915061407b828286614085565b9695505050505050565b60608315614094575081613143565b8251156140a45782518084602001fd5b8160405162461bcd60e51b8152600401610c0b91906143f5565b828054828255906000526020600020908101928215614113579160200282015b8281111561411357825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906140de565b5061411f929150614255565b5090565b828054828255906000526020600020908101928215614113579160200282015b82811115614113578251825591602001919060010190614143565b8280548282559060005260206000209081019282156141a4579160200282015b828111156141a457825182906141949082615202565b509160200191906001019061417e565b5061411f92915061426a565b8280548282559060005260206000209081019282156141f6579160200282015b828111156141f657825182906141e69082615202565b50916020019190600101906141d0565b5061411f929150614287565b828054828255906000526020600020908101928215614113579160200282015b828111156141135781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190614222565b5b8082111561411f5760008155600101614256565b8082111561411f57600061427e82826142a4565b5060010161426a565b8082111561411f57600061429b82826142a4565b50600101614287565b5080546142b090614c34565b6000825580601f106142c0575050565b601f0160209004906000526020600020908101906111639190614255565b6000602082840312156142f057600080fd5b5035919050565b815181526020808301516101a083019161431b908401826001600160a01b03169052565b5060408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e083015160e0830152610100808401518184015250610120808401518184015250610140808401516143848285018215159052565b50506101608381015180151584830152505061018092830151919092015290565b60005b838110156143c05781810151838201526020016143a8565b50506000910152565b600081518084526143e18160208601602086016143a5565b601f01601f19169290920160200192915050565b60208152600061314360208301846143c9565b80356001600160a01b038116811461441f57600080fd5b919050565b60006020828403121561443657600080fd5b61314382614408565b600081518084526020808501945080840160005b838110156144785781516001600160a01b031687529582019590820190600101614453565b509495945050505050565b600081518084526020808501945080840160005b8381101561447857815187529582019590820190600101614497565b600081518084526020808501808196508360051b8101915082860160005b858110156144fb5782840389526144e98483516143c9565b988501989350908401906001016144d1565b5091979650505050505050565b60808152600061451b608083018761443f565b828103602084015261452d8187614483565b9050828103604084015261454181866144b3565b9050828103606084015261455581856144b3565b979650505050505050565b803560ff8116811461441f57600080fd5b600080600080600060a0868803121561458957600080fd5b8535945061459960208701614560565b93506145a760408701614560565b94979396509394606081013594506080013592915050565b602081526000613143602083018461443f565b634e487b7160e01b600052602160045260246000fd5b602081016008831061460a57634e487b7160e01b600052602160045260246000fd5b91905290565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561464e5761464e614610565b604052919050565b60006001600160401b0382111561466f5761466f614610565b50601f01601f191660200190565b600082601f83011261468e57600080fd5b81356146a161469c82614656565b614626565b8181528460208386010111156146b657600080fd5b816020850160208301376000918101602001919091529392505050565b600080604083850312156146e657600080fd5b6146ef83614408565b915060208301356001600160401b0381111561470a57600080fd5b6147168582860161467d565b9150509250929050565b6000806040838503121561473357600080fd5b8235915061474360208401614560565b90509250929050565b60008083601f84011261475e57600080fd5b5081356001600160401b0381111561477557600080fd5b6020830191508360208260051b850101111561479057600080fd5b9250929050565b600080600080604085870312156147ad57600080fd5b84356001600160401b03808211156147c457600080fd5b6147d08883890161474c565b909650945060208701359150808211156147e957600080fd5b506147f68782880161474c565b95989497509550505050565b6000806000806060858703121561481857600080fd5b8435935061482860208601614560565b925060408501356001600160401b038082111561484457600080fd5b818701915087601f83011261485857600080fd5b81358181111561486757600080fd5b88602082850101111561487957600080fd5b95989497505060200194505050565b6000806020838503121561489b57600080fd5b82356001600160401b038111156148b157600080fd5b6148bd8582860161474c565b90969095509350505050565b60006001600160401b038211156148e2576148e2614610565b5060051b60200190565b600082601f8301126148fd57600080fd5b8135602061490d61469c836148c9565b82815260059290921b8401810191818101908684111561492c57600080fd5b8286015b8481101561494e5761494181614408565b8352918301918301614930565b509695505050505050565b600082601f83011261496a57600080fd5b8135602061497a61469c836148c9565b82815260059290921b8401810191818101908684111561499957600080fd5b8286015b8481101561494e578035835291830191830161499d565b600082601f8301126149c557600080fd5b813560206149d561469c836148c9565b82815260059290921b840181019181810190868411156149f457600080fd5b8286015b8481101561494e5780356001600160401b03811115614a175760008081fd5b614a258986838b010161467d565b8452509183019183016149f8565b600082601f830112614a4457600080fd5b81356020614a5461469c836148c9565b82815260059290921b84018101918181019086841115614a7357600080fd5b8286015b8481101561494e5780356001600160401b03811115614a965760008081fd5b614aa48986838b010161467d565b845250918301918301614a77565b600080600080600060a08688031215614aca57600080fd5b85356001600160401b0380821115614ae157600080fd5b614aed89838a016148ec565b96506020880135915080821115614b0357600080fd5b614b0f89838a01614959565b95506040880135915080821115614b2557600080fd5b614b3189838a016149b4565b94506060880135915080821115614b4757600080fd5b614b5389838a01614a33565b93506080880135915080821115614b6957600080fd5b50614b768882890161467d565b9150509295509295909350565b60008060408385031215614b9657600080fd5b8235915061474360208401614408565b600080600080600080600080610100898b031215614bc357600080fd5b614bcc89614408565b9750614bda60208a01614408565b965060408901359550606089013594506080890135935060a0890135925060c08901356001600160401b03811115614c1157600080fd5b614c1d8b828c016148ec565b92505060e089013590509295985092959890939650565b600181811c90821680614c4857607f821691505b6020821081036115d457634e487b7160e01b600052602260045260246000fd5b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215614d1257600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115612ad057612ad0614d19565b81810381811115612ad057612ad0614d19565b600060208284031215614d6757600080fd5b81516001600160601b038116811461314357600080fd5b634e487b7160e01b600052603260045260246000fd5b60008154614da181614c34565b808552602060018381168015614dbe5760018114614dd857614e06565b60ff1985168884015283151560051b880183019550614e06565b866000528260002060005b85811015614dfe5781548a8201860152908301908401614de3565b890184019650505b505050505092915050565b60018060a01b038616815284602082015260a060408201526000614e3860a0830186614d94565b8281036060840152614e4a8186614d94565b9150508260808301529695505050505050565b600060018201614e6f57614e6f614d19565b5060010190565b60ff851681526001600160601b038416602082015260606040820152816060820152818360808301376000818301608090810191909152601f909201601f191601019392505050565b60e081526000614ed260e083018a61443f565b8281036020840152614ee4818a614483565b90508281036040840152614ef881896144b3565b90508281036060840152614f0c81886144b3565b90508560808401528460a084015282810360c0840152614f2c81856143c9565b9a9950505050505050505050565b6000610120808352614f4e8184018d61443f565b90508281036020840152614f62818c614483565b90508281036040840152614f76818b6144b3565b90508281036060840152614f8a818a6144b3565b90508760808401528660a08401528560c08401528460e0840152828103610100840152614fb781856143c9565b9c9b505050505050505050505050565b6000604082016040835280865480835260608501915087600052602092508260002060005b828110156150115781546001600160a01b031684529284019260019182019101614fec565b505050838103828501528481528590820160005b86811015615051576001600160a01b0361503e84614408565b1682529183019190830190600101615025565b50979650505050505050565b60006020828403121561506f57600080fd5b81516001600160401b0381111561508557600080fd5b8201601f8101841361509657600080fd5b80516150a461469c82614656565b8181528560208385010111156150b957600080fd5b6150ca8260208301602086016143a5565b95945050505050565b8082028115828204841417612ad057612ad0614d19565b60008261510757634e487b7160e01b600052601260045260246000fd5b500490565b6020808252810182905260006001600160fb1b0383111561512c57600080fd5b8260051b80856040850137919091016040019392505050565b60018060a01b038616815284602082015260a06040820152600061516c60a08301866143c9565b8281036060840152614e4a81866143c9565b60006020828403121561519057600080fd5b8151801515811461314357600080fd5b600082516151b28184602087016143a5565b9190910192915050565b601f821115612f1557600081815260208120601f850160051c810160208610156151e35750805b601f850160051c820191505b81811015613de9578281556001016151ef565b81516001600160401b0381111561521b5761521b614610565b61522f816152298454614c34565b846151bc565b602080601f831160018114615264576000841561524c5750858301515b600019600386901b1c1916600185901b178555613de9565b600085815260208120601f198616915b8281101561529357888601518255948401946001909101908401615274565b50858210156152b15787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212200f55210d075eef43e92a4c02d5d18251edd52581c7c91fc96108776145ad2c2864736f6c63430008130033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.