Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 86 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Execute | 21047202 | 106 days ago | IN | 0 ETH | 0.00065384 | ||||
Execute | 20933225 | 122 days ago | IN | 0 ETH | 0.00141077 | ||||
Execute | 20933220 | 122 days ago | IN | 0 ETH | 0.00142662 | ||||
Add Transaction | 20840354 | 135 days ago | IN | 0 ETH | 0.00249091 | ||||
Execute | 20571460 | 173 days ago | IN | 0 ETH | 0.00026552 | ||||
Add Transaction | 20488682 | 184 days ago | IN | 0 ETH | 0.00022416 | ||||
Add Transaction | 20488668 | 184 days ago | IN | 0 ETH | 0.00022439 | ||||
Add Transaction | 20488648 | 184 days ago | IN | 0 ETH | 0.00024333 | ||||
Execute | 19720579 | 292 days ago | IN | 0 ETH | 0.00247985 | ||||
Execute | 19715548 | 292 days ago | IN | 0 ETH | 0.00138514 | ||||
Cast Vote | 19693746 | 295 days ago | IN | 0 ETH | 0.00053344 | ||||
Cast Vote | 19693746 | 295 days ago | IN | 0 ETH | 0.00070068 | ||||
Cast Vote | 19693709 | 295 days ago | IN | 0 ETH | 0.00070983 | ||||
Cast Vote | 19692262 | 295 days ago | IN | 0 ETH | 0.00095713 | ||||
Cast Vote | 19692259 | 295 days ago | IN | 0 ETH | 0.00106874 | ||||
Cast Vote | 19689202 | 296 days ago | IN | 0 ETH | 0.0011364 | ||||
Cast Vote | 19689201 | 296 days ago | IN | 0 ETH | 0.00104338 | ||||
Cast Vote | 19689017 | 296 days ago | IN | 0 ETH | 0.00099759 | ||||
Cast Vote | 19689008 | 296 days ago | IN | 0 ETH | 0.00110511 | ||||
Cast Vote | 19688147 | 296 days ago | IN | 0 ETH | 0.00136409 | ||||
Cast Vote | 19688142 | 296 days ago | IN | 0 ETH | 0.00139834 | ||||
Add Transaction | 19687824 | 296 days ago | IN | 0 ETH | 0.00382013 | ||||
Add Transaction | 19687810 | 296 days ago | IN | 0 ETH | 0.0036622 | ||||
Execute | 19587767 | 310 days ago | IN | 0 ETH | 0.00280772 | ||||
Execute | 19570951 | 312 days ago | IN | 0 ETH | 0.00557162 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
FraxGovernorOmega
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 200 runs
Other Settings:
shanghai EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: ISC pragma solidity ^0.8.19; // ==================================================================== // | ______ _______ | // | / _____________ __ __ / ____(_____ ____ _____ ________ | // | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ | // | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ | // | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ | // | | // ==================================================================== // ========================= FraxGovernorOmega ======================== // ==================================================================== // Frax Finance: https://github.com/FraxFinance // Primary Author(s) // Jon Walch: https://github.com/jonwalch // Contributors // Jamie Turley: https://github.com/jyturley // Reviewers // Drake Evans: https://github.com/DrakeEvans // Dennis: https://github.com/denett // Sam Kazemian: https://github.com/samkazemian // ==================================================================== import { FraxGovernorBase, ConstructorParams as FraxGovernorBaseParams } from "./FraxGovernorBase.sol"; import { IFraxGovernorOmega } from "./interfaces/IFraxGovernorOmega.sol"; import { Enum, ISafe } from "./interfaces/ISafe.sol"; struct ConstructorParams { string name; address veFxs; address veFxsVotingDelegation; address[] safeAllowlist; address[] delegateCallAllowlist; address payable timelockController; uint256 initialVotingDelay; uint256 initialVotingPeriod; uint256 initialProposalThreshold; uint256 quorumNumeratorValue; uint256 initialVotingDelayBlocks; uint256 initialShortCircuitNumerator; } /// @title FraxGovernorOmega /// @author Jon Walch (Frax Finance) https://github.com/jonwalch /// @notice A Governance contract with intended use as a Gnosis Safe signer. The only Safe interaction this contract does is calling GnosisSafe::approveHash(). /// @notice Supports optimistic proposals for Gnosis Safe transactions, that default to ```ProposalState.Succeeded```, through ```addTransaction()```. contract FraxGovernorOmega is FraxGovernorBase { /// @notice The address of the TimelockController contract address public immutable TIMELOCK_CONTROLLER; uint256 public lastSnapshotTime; /// @notice Configuration and allowlist for Gnosis Safes approved for use with FraxGovernorOmega mapping(address safe => uint256 status) public $safeAllowlist; /// @notice Allowlist for external contracts allowed for use with Gnosis Safe delegatecall mapping(address contractAddress => uint256 status) public $delegateCallAllowlist; /// @notice Configuration for voting periods configured per safe. If 0, uses Omega default votingPeriod(). mapping(address safe => uint256 votingPeriod) public $safeVotingPeriod; /// @notice Lookup from Gnosis Safe to nonce to corresponding transaction hash mapping(address safe => mapping(uint256 safeNonce => bytes32 txHash)) public $gnosisSafeToNonceToTxHash; /// @notice The ```AddToSafeAllowlist``` event is emitted when governance adds a safe to the allowlist /// @param safe The address of the Gnosis Safe added event AddToSafeAllowlist(address indexed safe); /// @notice The ```RemoveFromSafeAllowlist``` event is emitted when governance removes a safe from the allowlist /// @param safe The address of the Gnosis Safe removed event RemoveFromSafeAllowlist(address indexed safe); /// @notice The ```AddToDelegateCallAllowlist``` event is emitted when governance adds a contract to the allowlist /// @param contractAddress The address of the contract added event AddToDelegateCallAllowlist(address contractAddress); /// @notice The ```RemoveFromDelegateCallAllowlist``` event is emitted when governance removes a contract from the allowlist /// @param contractAddress The address of the contract removed event RemoveFromDelegateCallAllowlist(address contractAddress); /// @notice The ```SafeVotingPeriodSet``` event is emitted when governance changes the voting period for a specific safe /// @param safe The address of the Gnosis Safe removed /// @param oldSafeVotingPeriod The old value for the safe's voting period /// @param newSafeVotingPeriod The new value for the safe's voting period event SafeVotingPeriodSet(address safe, uint256 oldSafeVotingPeriod, uint256 newSafeVotingPeriod); /// @notice The ```TransactionProposed``` event is emitted when a Frax Team optimistic proposal is put up for voting /// @param safe The address of the Gnosis Safe /// @param nonce The nonce corresponding to the safe for this proposal /// @param txHash The hash of the Gnosis Safe transaction /// @param proposalId The proposal id in FraxGovernorOmega event TransactionProposed(address indexed safe, uint256 nonce, bytes32 indexed txHash, uint256 indexed proposalId); /// @notice The ```constructor``` function is called on deployment /// @param params ConstructorParams struct constructor( ConstructorParams memory params ) FraxGovernorBase( FraxGovernorBaseParams({ veFxs: params.veFxs, veFxsVotingDelegation: params.veFxsVotingDelegation, _name: params.name, initialVotingDelay: params.initialVotingDelay, initialVotingPeriod: params.initialVotingPeriod, initialProposalThreshold: params.initialProposalThreshold, quorumNumeratorValue: params.quorumNumeratorValue, initialVotingDelayBlocks: params.initialVotingDelayBlocks, initialShortCircuitNumerator: params.initialShortCircuitNumerator }) ) { TIMELOCK_CONTROLLER = params.timelockController; // Assume safes at deploy time are properly configured for frxGov _addToSafeAllowlist(params.safeAllowlist); _addToDelegateCallAllowlist(params.delegateCallAllowlist); } /// @notice The ```_requireOnlyTimelockController``` function checks if the caller is FraxGovernorAlpha's TimelockController function _requireOnlyTimelockController() internal view { if (msg.sender != TIMELOCK_CONTROLLER) revert IFraxGovernorOmega.NotTimelockController(); } /// @notice The ```_requireSafeAllowlist``` function checks if the safe is on the allowlist /// @param safe The address of the Gnosis Safe function _requireSafeAllowlist(address safe) internal view { if ($safeAllowlist[safe] == 0) revert Unauthorized(); } /// @notice The ```_requireNotOmegaSignature``` function checks if the provided signatures are not Omega approvehash signatures /// @dev Disallow the ```v == 1``` cases of ```safe.checkNSignatures()``` for Omega. This ensures that the signatures passed /// @dev in are from other owners and disallows the implicit signing from Omega with the ```msg.sender == currentOwner``` case. /// @param signatures 1 or more packed signature data ({bytes32 r}{bytes32 s}{uint8 v}) /// @param requiredSignatures The expected amount of EOA signatures function _requireNotOmegaSignature(bytes memory signatures, uint256 requiredSignatures) internal view { uint8 v; bytes32 r; uint256 i; for (i = 0; i < requiredSignatures; ++i) { // Taken from Gnosis Safe SignatureDecoder // The signature format is a compact form of: // {bytes32 r}{bytes32 s}{uint8 v} // Compact means, uint8 is not padded to 32 bytes. /// @solidity memory-safe-assembly assembly { let signaturePos := mul(0x41, i) r := mload(add(signatures, add(signaturePos, 0x20))) // Here we are loading the last 32 bytes, including 31 bytes // of 's'. There is no 'mload8' to do this. // // 'byte' is not working due to the Solidity parser, so lets // use the second best option, 'and' v := and(mload(add(signatures, add(signaturePos, 0x41))), 0xff) } // If v is 1 then it is the approved hash safe.checkNSignatures() flow which automatically approves the msg.sender // We restrict this because we don't want omega to count as a signature, since it is the msg.sender in the later call to safe.checkNSignatures() if (v == 1) { address approver = address(uint160(uint256(r))); if (approver == address(this)) { revert IFraxGovernorOmega.WrongSafeSignatureType(); } } } } /// @dev Internal helper function for optimistic proposals function _optimisticProposalArgs( address safe, bytes32 txHash ) internal pure returns (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) { targets = new address[](1); values = new uint256[](1); calldatas = new bytes[](1); targets[0] = safe; values[0] = 0; calldatas[0] = abi.encodeWithSelector(ISafe.approveHash.selector, txHash); } /// @dev Exists solely to avoid stack too deep errors in ```addTransaction()``` /// @return txHash Gnosis Safe transaction hash function _safeGetTransactionHash( ISafe safe, IFraxGovernorOmega.TxHashArgs memory args ) internal view returns (bytes32 txHash) { txHash = safe.getTransactionHash({ to: args.to, value: args.value, data: args.data, operation: args.operation, safeTxGas: args.safeTxGas, baseGas: args.baseGas, gasPrice: args.gasPrice, gasToken: args.gasToken, refundReceiver: args.refundReceiver, _nonce: args._nonce }); } /// @notice The ```propose``` function reverts when called /// @dev Gnosis Safe owners should sign a Gnosis Transaction and then it can be proposed using ```addTransaction()``` /// @dev Cannot recover assets accidentally sent to this contract function propose( address[] memory, // targets uint256[] memory, // values bytes[] memory, // calldatas string memory // description ) public pure override returns (uint256) { revert IFraxGovernorOmega.CannotPropose(); } /// @notice The ```cancel``` function reverts when called /// @dev Optimistic proposals can be cancelled by Frax Team using ```abortTransaction()``` function cancel( address[] memory, // targets uint256[] memory, // values bytes[] memory, // calldatas bytes32 // descriptionHash ) public pure override returns (uint256) { revert IFraxGovernorOmega.CannotCancelOptimisticTransaction(); } /// @notice The ```relay``` function reverts when called /// @dev This function has no use in Omega function relay( address, // target uint256, // value bytes calldata // data ) external payable override { revert IFraxGovernorOmega.CannotRelay(); } /// @notice The ```addTransaction``` function creates optimistic proposals that correspond to a Gnosis Safe transaction that was initiated by the Frax Team /// @dev The nonce takes care of hashing a unique proposalId, so we don't need to pass a description. /// @param teamSafe Address of allowlisted Gnosis Safe /// @param args TxHashArgs of the Gnosis Safe transaction /// @param signatures EOA signatures for the Gnosis Safe transaction /// @return optimisticProposalId Proposal ID of optimistic proposal created function addTransaction( address teamSafe, IFraxGovernorOmega.TxHashArgs calldata args, bytes calldata signatures ) public returns (uint256 optimisticProposalId) { _requireSafeAllowlist(teamSafe); // Disallow Safe delegatecalls to contracts not on allowlist if (args.operation == Enum.Operation.DelegateCall && $delegateCallAllowlist[args.to] != 1) { revert IFraxGovernorOmega.DelegateCallNotAllowed(args.to); } ISafe safe = ISafe(teamSafe); // Assuming proper configuration, safe has threshold of n, where n is the number of EOA signers. uint256 requiredSignatures = safe.getThreshold(); _requireNotOmegaSignature({ signatures: signatures, requiredSignatures: requiredSignatures }); if ($gnosisSafeToNonceToTxHash[teamSafe][args._nonce] != 0) revert IFraxGovernorOmega.NonceReserved(); if (args._nonce < safe.nonce()) revert IFraxGovernorOmega.WrongNonce(); bytes32 txHash = _safeGetTransactionHash({ safe: safe, args: args }); safe.checkNSignatures({ dataHash: txHash, data: args.data, signatures: signatures, requiredSignatures: requiredSignatures }); (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = _optimisticProposalArgs({ safe: teamSafe, txHash: txHash }); optimisticProposalId = _propose({ targets: targets, values: values, calldatas: calldatas, description: "", teamSafe: teamSafe }); $gnosisSafeToNonceToTxHash[teamSafe][args._nonce] = txHash; emit TransactionProposed({ safe: teamSafe, nonce: args._nonce, txHash: txHash, proposalId: optimisticProposalId }); } /// @notice The ```batchAddTransaction``` function is a batch version of ```addTransaction()``` /// @param teamSafes Address of each allowlisted Gnosis Safe /// @param args TxHashArgs of each Gnosis Safe transaction /// @param signatures EOA signatures for each Gnosis Safe transaction /// @return optimisticProposalIds Array of optimistic Proposal IDs function batchAddTransaction( address[] calldata teamSafes, IFraxGovernorOmega.TxHashArgs[] calldata args, bytes[] calldata signatures ) external returns (uint256[] memory optimisticProposalIds) { if (teamSafes.length != args.length || teamSafes.length != signatures.length) { revert IFraxGovernorOmega.BadBatchArgs(); } optimisticProposalIds = new uint256[](teamSafes.length); for (uint256 i = 0; i < teamSafes.length; ++i) { optimisticProposalIds[i] = addTransaction({ teamSafe: teamSafes[i], args: args[i], signatures: signatures[i] }); } } /// @notice The ```rejectTransaction``` function is called when an optimistic proposal is Defeated. It calls ```safe.approveHash()``` for a 0 eth transfer with the provided ```nonce``` /// @param teamSafe Address of allowlisted Gnosis Safe /// @param nonce Gnosis Safe nonce corresponding to an optimistic proposal function rejectTransaction(address teamSafe, uint256 nonce) external { bytes32 originalTxHash = $gnosisSafeToNonceToTxHash[teamSafe][nonce]; (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = _optimisticProposalArgs({ safe: teamSafe, txHash: originalTxHash }); if ( state( hashProposal({ targets: targets, values: values, calldatas: calldatas, descriptionHash: keccak256(bytes("")) }) ) != ProposalState.Defeated ) { revert IFraxGovernorOmega.WrongProposalState(); } ISafe safe = ISafe(teamSafe); bytes32 rejectTxHash = _safeGetTransactionHash({ safe: safe, args: IFraxGovernorOmega.TxHashArgs({ to: teamSafe, value: 0, data: "", operation: Enum.Operation.Call, safeTxGas: 0, baseGas: 0, gasPrice: 0, gasToken: address(0), refundReceiver: payable(address(0)), _nonce: nonce }) }); if (safe.approvedHashes({ signer: address(this), txHash: rejectTxHash }) == 1) { revert IFraxGovernorOmega.TransactionAlreadyApproved(rejectTxHash); } // Omega approves 0 eth transfer safe.approveHash(rejectTxHash); } /// @notice The ```abortTransaction``` function is called when the Frax Team no longer wants to execute a transaction they created in the Gnosis Safe UI /// @notice This can be before or after the transaction is added using ```addTransaction()```. It signs a 0 eth transfer for the current nonce /// @notice as long as the 0 eth transfer has the configured required amount of EOA signatures. /// @dev Only works when the transaction to abort is the first in the Gnosis Safe queue (current nonce) /// @dev Only way to cancel an optimistic proposal /// @param teamSafe Address of allowlisted Gnosis Safe /// @param signatures EOA signatures for a 0 ether transfer Gnosis Safe transaction with the current nonce function abortTransaction(address teamSafe, bytes calldata signatures) external { _requireSafeAllowlist(teamSafe); ISafe safe = ISafe(teamSafe); // Assuming proper configuration, safe has threshold of n, where n is the number of EOA signers. uint256 requiredSignatures = safe.getThreshold(); _requireNotOmegaSignature({ signatures: signatures, requiredSignatures: requiredSignatures }); uint256 nonce = safe.nonce(); bytes32 rejectTxHash = safe.getTransactionHash({ to: teamSafe, value: 0, data: "", operation: Enum.Operation.Call, safeTxGas: 0, baseGas: 0, gasPrice: 0, gasToken: address(0), refundReceiver: payable(address(0)), _nonce: nonce }); // Check validity of provided 3 signatures for generated txHash safe.checkNSignatures({ dataHash: rejectTxHash, data: "", signatures: signatures, requiredSignatures: requiredSignatures }); bytes32 originalTxHash = $gnosisSafeToNonceToTxHash[teamSafe][nonce]; uint256 abortedProposalId; // If safe/nonce tuple already had addTransaction() called for it if (originalTxHash != 0) { (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = _optimisticProposalArgs({ safe: teamSafe, txHash: originalTxHash }); abortedProposalId = hashProposal({ targets: targets, values: values, calldatas: calldatas, descriptionHash: keccak256(bytes("")) }); ProposalState proposalState = state(abortedProposalId); if (proposalState == ProposalState.Canceled) { revert IFraxGovernorOmega.ProposalAlreadyCanceled(); } proposals[abortedProposalId].canceled = true; emit ProposalCanceled(abortedProposalId); } // Omega approves 0 eth transfer safe.approveHash(rejectTxHash); } /// @notice The ```setVotingDelay``` function is called by Alpha governance to change the amount of time before the voting snapshot /// @dev Only callable by FraxGovernorAlpha governance /// @param newVotingDelay New voting delay in seconds function setVotingDelay(uint256 newVotingDelay) public override { _requireOnlyTimelockController(); _setVotingDelay(newVotingDelay); } /// @notice The ```setVotingDelayBlocks``` function is called by Alpha governance to change the amount of blocks before the voting snapshot /// @dev Only callable by FraxGovernorAlpha governance /// @param newVotingDelayBlocks New voting delay in blocks function setVotingDelayBlocks(uint256 newVotingDelayBlocks) external { _requireOnlyTimelockController(); _setVotingDelayBlocks(newVotingDelayBlocks); } /// @notice The ```setVotingPeriod``` function is called by Alpha governance to change the amount of time a proposal can be voted on /// @dev Only callable by FraxGovernorAlpha governance /// @param newVotingPeriod New voting period in seconds function setVotingPeriod(uint256 newVotingPeriod) public override { _requireOnlyTimelockController(); _setVotingPeriod(newVotingPeriod); } /// @notice The ```setProposalThreshold``` function is called by Alpha governance to change the amount of veFXS a proposer needs to call propose() /// @notice proposalThreshold calculation includes all weight delegated to the proposer /// @dev Only callable by FraxGovernorAlpha governance /// @param newProposalThreshold New voting period in amount of veFXS function setProposalThreshold(uint256 newProposalThreshold) public override { _requireOnlyTimelockController(); _setProposalThreshold(newProposalThreshold); } /// @notice The ```updateQuorumNumerator``` function is called by Alpha governance to change the numerator / 100 needed for quorum /// @dev Only callable by FraxGovernorAlpha governance /// @param newQuorumNumerator Number expressed as x/100 (percentage) function updateQuorumNumerator(uint256 newQuorumNumerator) external override { _requireOnlyTimelockController(); _updateQuorumNumerator(newQuorumNumerator); } /// @notice The ```setVeFxsVotingDelegation``` function is called by Alpha governance to change the voting weight ```IERC5805``` contract /// @dev Only callable by FraxGovernorAlpha governance /// @param veFxsVotingDelegation New ```IERC5805``` veFxsVotingDelegation contract address function setVeFxsVotingDelegation(address veFxsVotingDelegation) external { _requireOnlyTimelockController(); _setVeFxsVotingDelegation(veFxsVotingDelegation); } /// @notice The ```updateShortCircuitNumerator``` function is called by Alpha governance to change the short circuit numerator /// @dev Only callable by FraxGovernorAlpha governance /// @param newShortCircuitNumerator Number expressed as x/100 (percentage) function updateShortCircuitNumerator(uint256 newShortCircuitNumerator) external { _requireOnlyTimelockController(); _updateShortCircuitNumerator(newShortCircuitNumerator); } function _addToSafeAllowlist(address[] memory safes) internal { for (uint256 i = 0; i < safes.length; ++i) { if ($safeAllowlist[safes[i]] == 1) revert IFraxGovernorOmega.AlreadyOnSafeAllowlist(safes[i]); $safeAllowlist[safes[i]] = 1; emit AddToSafeAllowlist(safes[i]); } } /// @notice The ```addToSafeAllowlist``` function is called by Alpha governance to allowlist safes for addTransaction() /// @notice Safes are expected to be properly configured before calling this function /// @notice Proper configuration entails having: the FraxGuard set, FraxGovernorOmega set as a signer and FraxGovernorAlpha's TimelockController as a Module /// @param safes Array of safe addresses to allowlist function addToSafeAllowlist(address[] calldata safes) external { _requireOnlyTimelockController(); _addToSafeAllowlist(safes); } /// @notice The ```removeSafesFromAllowlist``` function is called by Alpha governance to remove safes from the allowlist /// @dev See TestFraxGovernorUpgrade.t.sol for upgrade path /// @param safes Array of safe addresses to remove from allowlist function removeFromSafeAllowlist(address[] calldata safes) external { _requireOnlyTimelockController(); for (uint256 i = 0; i < safes.length; ++i) { if ($safeAllowlist[safes[i]] == 0) revert IFraxGovernorOmega.NotOnSafeAllowlist(safes[i]); delete $safeAllowlist[safes[i]]; emit RemoveFromSafeAllowlist(safes[i]); } } function _addToDelegateCallAllowlist(address[] memory contracts) internal { for (uint256 i = 0; i < contracts.length; ++i) { if ($delegateCallAllowlist[contracts[i]] == 1) { revert IFraxGovernorOmega.AlreadyOnDelegateCallAllowlist(contracts[i]); } $delegateCallAllowlist[contracts[i]] = 1; emit AddToDelegateCallAllowlist(contracts[i]); } } /// @notice The ```addToDelegateCallAllowlist``` function is called by Alpha governance to allowlist contracts for delegatecall with addTransaction() /// @param contracts Array of contract addresses to allowlist function addToDelegateCallAllowlist(address[] calldata contracts) external { _requireOnlyTimelockController(); _addToDelegateCallAllowlist(contracts); } /// @notice The ```removeFromDelegateCallAllowlist``` function is called by Alpha governance to remove contracts from the allowlist /// @dev See TestFraxGovernorUpgrade.t.sol for upgrade path /// @param contracts Array of contract addresses to remove from allowlist function removeFromDelegateCallAllowlist(address[] calldata contracts) external { _requireOnlyTimelockController(); for (uint256 i = 0; i < contracts.length; ++i) { if ($delegateCallAllowlist[contracts[i]] == 0) { revert IFraxGovernorOmega.NotOnDelegateCallAllowlist(contracts[i]); } delete $delegateCallAllowlist[contracts[i]]; emit RemoveFromDelegateCallAllowlist(contracts[i]); } } /// @notice The ```setSafeVotingPeriod``` function is called by Alpha governance to change the short circuit numerator /// @dev Only callable by FraxGovernorAlpha governance /// @param safe The Gnosis safe to configure /// @param newSafeVotingPeriod The voting period specific to safe, set to 0 to go back to Omega's default voting period function setSafeVotingPeriod(address safe, uint256 newSafeVotingPeriod) external { _requireOnlyTimelockController(); uint256 safeVotingPeriod = $safeVotingPeriod[safe]; if (safeVotingPeriod == newSafeVotingPeriod) revert IFraxGovernorOmega.SameSafeVotingPeriod(); $safeVotingPeriod[safe] = newSafeVotingPeriod; emit SafeVotingPeriodSet({ safe: safe, oldSafeVotingPeriod: safeVotingPeriod, newSafeVotingPeriod: newSafeVotingPeriod }); } /// @notice The ```_optimisticVoteDefeated``` function is called by state() to check if an optimistic proposal was defeated /// @param proposalId Proposal ID /// @return Whether the optimistic proposal was defeated or not function _optimisticVoteDefeated(uint256 proposalId) internal view returns (bool) { (uint256 againstVoteWeight, uint256 forVoteWeight, ) = proposalVotes(proposalId); if (againstVoteWeight == 0 && forVoteWeight == 0) { return false; } else { return forVoteWeight <= againstVoteWeight; } } /// @notice The ```_propose``` function is similar to OpenZeppelin's propose() with minor changes. /// @dev Changes include: Removal of proposal threshold check, ProposalCore struct packing, setting $snapshotToTotalVeFxsSupply, and configurable voting periods per safe /// @return proposalId Proposal ID function _propose( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description, address teamSafe ) internal returns (uint256 proposalId) { proposalId = hashProposal({ targets: targets, values: values, calldatas: calldatas, descriptionHash: keccak256(bytes(description)) }); require(targets.length == values.length, "Governor: invalid proposal length"); require(targets.length == calldatas.length, "Governor: invalid proposal length"); require(targets.length > 0, "Governor: empty proposal"); require(proposals[proposalId].voteStart == 0, "Governor: proposal already exists"); address proposer = msg.sender; uint256 snapshot = clock() + votingDelay(); uint256 deadline; try VE_FXS.newSnapshotTime(snapshot) {} catch {} lastSnapshotTime = snapshot; { uint256 safeVotingPeriod = $safeVotingPeriod[teamSafe]; // If configured, use safe's voting period. Otherwise use default Omega value. uint256 votingPeriod = safeVotingPeriod != 0 ? safeVotingPeriod : votingPeriod(); deadline = snapshot + votingPeriod; } proposals[proposalId] = ProposalCore({ proposer: proposer, voteStart: uint40(snapshot), voteEnd: uint40(deadline), executed: false, canceled: false }); // Save the block number of the snapshot, so it can be later used to fetch the total outstanding supply // of veFXS. We did this so we can still support quorum(timestamp), without breaking the OZ standard. // The underlying issue is that VE_FXS.totalSupply(timestamp) doesn't work for historical values, so we must // use VE_FXS.totalSupply(), or VE_FXS.totalSupplyAt(blockNumber). $snapshotTimestampToSnapshotBlockNumber[snapshot] = block.number + $votingDelayBlocks; emit ProposalCreated( proposalId, proposer, targets, values, new string[](targets.length), calldatas, snapshot, deadline, description ); } /// @notice The ```state``` function is similar to OpenZeppelin's propose() with minor changes /// @dev Changes include: support for early success or failure using short circuit and optimistic proposals /// @param proposalId Proposal ID /// @return proposalState ProposalState enum function state(uint256 proposalId) public view override returns (ProposalState proposalState) { ProposalCore storage $proposal = proposals[proposalId]; if ($proposal.executed) { return ProposalState.Executed; } if ($proposal.canceled) { return ProposalState.Canceled; } uint256 snapshot = proposalSnapshot(proposalId); if (snapshot == 0) { revert("Governor: unknown proposal id"); } uint256 currentTimepoint = clock(); if (snapshot >= currentTimepoint || $snapshotTimestampToSnapshotBlockNumber[snapshot] >= block.number) { return ProposalState.Pending; } // Allow early execution when overwhelming majority if (_shortCircuitFor(proposalId)) { return ProposalState.Succeeded; } else if (_shortCircuitAgainst(proposalId)) { return ProposalState.Defeated; } uint256 deadline = proposalDeadline(proposalId); if (deadline >= currentTimepoint) { return ProposalState.Active; } // Optimistic proposal with addTransaction() if (_quorumReached(proposalId) && _optimisticVoteDefeated(proposalId)) { return ProposalState.Defeated; } else { return ProposalState.Succeeded; } } }
// SPDX-License-Identifier: ISC pragma solidity ^0.8.19; // ==================================================================== // | ______ _______ | // | / _____________ __ __ / ____(_____ ____ _____ ________ | // | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ | // | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ | // | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ | // | | // ==================================================================== // ========================= FraxGovernorBase ========================= // ==================================================================== // Frax Finance: https://github.com/FraxFinance // Primary Author(s) // Jon Walch: https://github.com/jonwalch // Reviewers // Drake Evans: https://github.com/DrakeEvans // Dennis: https://github.com/denett // Sam Kazemian: https://github.com/samkazemian // ==================================================================== import { Checkpoints } from "@openzeppelin/contracts/utils/Checkpoints.sol"; import { IERC5805 } from "@openzeppelin/contracts/interfaces/IERC5805.sol"; import { Governor, IGovernor } from "./governor/Governor.sol"; import { GovernorCountingFractional, SafeCast } from "./governor/GovernorCountingFractional.sol"; import { GovernorSettings } from "./governor/GovernorSettings.sol"; import { GovernorVotes, IVotes } from "./governor/GovernorVotesQuorumFraction.sol"; import { GovernorVotesQuorumFraction } from "./governor/GovernorVotesQuorumFraction.sol"; import { IVeFxs } from "./interfaces/IVeFxs.sol"; struct ConstructorParams { address veFxs; address veFxsVotingDelegation; string _name; uint256 initialVotingDelay; uint256 initialVotingPeriod; uint256 initialProposalThreshold; uint256 quorumNumeratorValue; uint256 initialVotingDelayBlocks; uint256 initialShortCircuitNumerator; } /// @title FraxGovernorBase /// @author Jon Walch (Frax Finance) https://github.com/jonwalch /// @notice An abstract contract which contains the shared core logic and storage for FraxGovernorAlpha and FraxGovernorOmega abstract contract FraxGovernorBase is GovernorSettings, GovernorVotesQuorumFraction, GovernorCountingFractional { using SafeCast for *; using Checkpoints for Checkpoints.Trace224; /// @notice Voting delay in number of blocks /// @dev only used to look up total veFXS supply on the VE_FXS contract uint256 public $votingDelayBlocks; /// @notice Address of the veFXS contract IVeFxs public immutable VE_FXS; /// @notice Checkpoints for short circuit numerator mirroring _quorumNumeratorHistory from GovernorVotesQuorumFraction.sol Checkpoints.Trace224 private _$shortCircuitNumeratorHistory; /// @notice Lookup from snapshot timestamp to corresponding snapshot block number, used for quorum mapping(uint256 snapshot => uint256 blockNumber) public $snapshotTimestampToSnapshotBlockNumber; /// @notice The ```ShortCircuitNumeratorUpdated``` event is emitted when governance changes the short circuit numerator /// @param oldShortCircuitNumerator The old short circuit numerator /// @param newShortCircuitNumerator The new contract address event ShortCircuitNumeratorUpdated(uint256 oldShortCircuitNumerator, uint256 newShortCircuitNumerator); /// @notice The ```VeFxsVotingDelegationSet``` event is emitted when governance changes the voting weight IERC5805 contract /// @param oldVotingDelegation The old contract address /// @param newVotingDelegation The new contract address event VeFxsVotingDelegationSet(address oldVotingDelegation, address newVotingDelegation); /// @notice The ```VotingDelayBlocksSet``` event is emitted when governance changes the voting delay in blocks /// @param oldVotingDelayBlocks The old short circuit numerator /// @param newVotingDelayBlocks The new contract address event VotingDelayBlocksSet(uint256 oldVotingDelayBlocks, uint256 newVotingDelayBlocks); /// @notice The ```constructor``` function is called on deployment /// @param params ConstructorParams struct constructor( ConstructorParams memory params ) Governor(params._name) GovernorSettings(params.initialVotingDelay, params.initialVotingPeriod, params.initialProposalThreshold) GovernorVotes(IVotes(params.veFxsVotingDelegation)) GovernorVotesQuorumFraction(params.quorumNumeratorValue) { VE_FXS = IVeFxs(params.veFxs); _updateShortCircuitNumerator(params.initialShortCircuitNumerator); _setVotingDelayBlocks(params.initialVotingDelayBlocks); // Emit manually because initial setting of `token` is in GovernorVotes' constructor emit VeFxsVotingDelegationSet({ oldVotingDelegation: address(0), newVotingDelegation: params.veFxsVotingDelegation }); } /// @notice The ```_requireSenderAboveProposalThreshold``` function checks if the proposer has sufficient voting weight function _requireSenderAboveProposalThreshold() internal view { if (_getVotes(msg.sender, block.timestamp - 1, "") < proposalThreshold()) { revert SenderVotingWeightBelowProposalThreshold(); } } /// @notice The ```_setVotingDelayBlocks``` function is called by governance to change the voting delay in blocks /// @notice This must be changed in tandem with ```votingDelay``` to properly set quorum values /// @param votingDelayBlocks New voting delay in blocks value function _setVotingDelayBlocks(uint256 votingDelayBlocks) internal { uint256 oldVotingDelayBlocks = $votingDelayBlocks; $votingDelayBlocks = votingDelayBlocks; emit VotingDelayBlocksSet({ oldVotingDelayBlocks: oldVotingDelayBlocks, newVotingDelayBlocks: votingDelayBlocks }); } /// @notice The ```_setVeFxsVotingDelegation``` function is called by governance to change the voting weight IERC5805 contract /// @param veFxsVotingDelegation new IERC5805 VeFxsVotingDelegation contract address function _setVeFxsVotingDelegation(address veFxsVotingDelegation) internal { address oldVeFxsVotingDelegation = address(token); token = IERC5805(veFxsVotingDelegation); emit VeFxsVotingDelegationSet({ oldVotingDelegation: oldVeFxsVotingDelegation, newVotingDelegation: veFxsVotingDelegation }); } /// @notice The ```_quorumReached``` function is called by state() to check for early proposal success /// @param proposalId Proposal ID /// @return isQuorum Represents if quorum was reached or not function _quorumReached( uint256 proposalId ) internal view override(Governor, GovernorCountingFractional) returns (bool isQuorum) { (uint256 againstVoteWeight, uint256 forVoteWeight, uint256 abstainVoteWeight) = proposalVotes(proposalId); uint256 larger = againstVoteWeight > forVoteWeight ? againstVoteWeight : forVoteWeight; uint256 proposalVoteStart = proposalSnapshot(proposalId); isQuorum = quorum(proposalVoteStart) <= larger + abstainVoteWeight; } /// @notice The ```_shortCircuitFor``` function is called by state() to check for early proposal success /// @param proposalId Proposal ID /// @return isShortCircuitFor Represents if short circuit threshold for votes were reached or not function _shortCircuitFor(uint256 proposalId) internal view returns (bool isShortCircuitFor) { (, uint256 forVoteWeight, ) = proposalVotes(proposalId); uint256 proposalVoteStart = proposalSnapshot(proposalId); isShortCircuitFor = forVoteWeight > shortCircuitThreshold(proposalVoteStart); } /// @notice The ```_shortCircuitAgainst``` function is called by state() to check for early proposal failure /// @param proposalId Proposal ID /// @return isShortCircuitAgainst Represents if short circuit threshold against votes were reached or not function _shortCircuitAgainst(uint256 proposalId) internal view returns (bool isShortCircuitAgainst) { (uint256 againstVoteWeight, , ) = proposalVotes(proposalId); uint256 proposalVoteStart = proposalSnapshot(proposalId); isShortCircuitAgainst = againstVoteWeight > shortCircuitThreshold(proposalVoteStart); } /// @notice The ```_updateShortCircuitNumerator``` function is called by governance to change the short circuit numerator /// @dev Mirrors ```GovernorVotesQuorumFraction::_updateQuorumNumerator(uint256 newQuorumNumerator)``` /// @param newShortCircuitNumerator New short circuit numerator value function _updateShortCircuitNumerator(uint256 newShortCircuitNumerator) internal { // Numerator must be less than or equal to denominator if (newShortCircuitNumerator > quorumDenominator()) { revert ShortCircuitNumeratorGreaterThanQuorumDenominator(); } uint256 oldShortCircuitNumerator = shortCircuitNumerator(); // Set new quorum for future proposals _$shortCircuitNumeratorHistory.push(SafeCast.toUint32(clock()), SafeCast.toUint224(newShortCircuitNumerator)); emit ShortCircuitNumeratorUpdated({ oldShortCircuitNumerator: oldShortCircuitNumerator, newShortCircuitNumerator: newShortCircuitNumerator }); } function COUNTING_MODE() public pure override(IGovernor, GovernorCountingFractional) returns (string memory) { return "support=bravo&quorum=against,abstain&quorum=for,abstain¶ms=fractional"; } /// @notice The ```shortCircuitNumerator``` function returns the latest short circuit numerator /// @dev Mirrors ```GovernorVotesQuorumFraction::quorumNumerator()``` /// @return latestShortCircuitNumerator The short circuit numerator function shortCircuitNumerator() public view returns (uint256 latestShortCircuitNumerator) { latestShortCircuitNumerator = _$shortCircuitNumeratorHistory.latest(); } /// @notice The ```shortCircuitNumerator``` function returns the short circuit numerator at ```timepoint``` /// @dev Mirrors ```GovernorVotesQuorumFraction::quorumNumerator(uint256 timepoint)``` /// @param timepoint A block.timestamp /// @return shortCircuitNumeratorAtTimepoint Short circuit numerator function shortCircuitNumerator(uint256 timepoint) public view returns (uint256 shortCircuitNumeratorAtTimepoint) { // If history is empty, fallback to old storage uint256 length = _$shortCircuitNumeratorHistory._checkpoints.length; // Optimistic search, check the latest checkpoint Checkpoints.Checkpoint224 memory latest = _$shortCircuitNumeratorHistory._checkpoints[length - 1]; if (latest._key <= timepoint) { shortCircuitNumeratorAtTimepoint = latest._value; return shortCircuitNumeratorAtTimepoint; } // Otherwise, do the binary search shortCircuitNumeratorAtTimepoint = _$shortCircuitNumeratorHistory.upperLookupRecent( SafeCast.toUint32(timepoint) ); } /// @notice The ```shortCircuitThreshold``` function returns the latest short circuit numerator /// @dev Only supports historical quorum values for proposals that actually exist at ```timepoint``` /// @param timepoint A block.timestamp corresponding to a proposal snapshot /// @return shortCircuitThresholdAtTimepoint Total voting weight needed for short circuit to succeed function shortCircuitThreshold(uint256 timepoint) public view returns (uint256 shortCircuitThresholdAtTimepoint) { // uint256 snapshotBlockNumber = $snapshotTimestampToSnapshotBlockNumber[timepoint]; if (timepoint == 0 || timepoint >= block.timestamp) revert InvalidTimepoint(); shortCircuitThresholdAtTimepoint = (VE_FXS.totalSupplyAt(timepoint) * shortCircuitNumerator(timepoint)) / quorumDenominator(); } /// @notice The ```quorum``` function returns the quorum value at ```timepoint``` /// @dev Only supports historical quorum values for proposals that actually exist at ```timepoint``` /// @param timepoint A block.timestamp corresponding to a proposal snapshot /// @return quorumAtTimepoint Quorum value at ```timepoint``` function quorum( uint256 timepoint ) public view override(IGovernor, GovernorVotesQuorumFraction) returns (uint256 quorumAtTimepoint) { // uint256 snapshotBlockNumber = $snapshotTimestampToSnapshotBlockNumber[timepoint]; if (timepoint == 0 || timepoint >= block.timestamp) revert InvalidTimepoint(); quorumAtTimepoint = (VE_FXS.totalSupplyAt(timepoint) * quorumNumerator(timepoint)) / quorumDenominator(); } /// @notice The ```bulkCastVote``` function allows the caller to vote on many proposals at once /// @param proposalId An array of proposalId /// @param support An array of support function bulkCastVote(uint256[] calldata proposalId, uint8[] calldata support) external { uint256 proposalIdsLength = proposalId.length; if (proposalIdsLength != support.length) { revert ParamLengthsNotEqual(); } for (uint256 i = 0; i < proposalIdsLength; ++i) { castVote({ proposalId: proposalId[i], support: support[i] }); } } /// Boilerplate overrides /** * @notice Cast a vote with a reason and additional encoded parameters using * the user's cryptographic signature. * * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length * of params. * * @dev If casting a fractional vote via `params`, the voter's current nonce * must be appended to the `params` as the last 16 bytes and included in the * signature. I.e., the params used when constructing the signature would be: * * abi.encodePacked(againstVotes, forVotes, abstainVotes, nonce) * * See {fractionalVoteNonce} and {_castVote} for more information. */ function castVoteWithReasonAndParamsBySig( uint256 proposalId, uint8 support, string calldata reason, bytes memory params, uint8 v, bytes32 r, bytes32 s ) public virtual override(Governor, GovernorCountingFractional) returns (uint256) { return GovernorCountingFractional.castVoteWithReasonAndParamsBySig({ proposalId: proposalId, support: support, reason: reason, params: params, v: v, r: r, s: s }); } /** * @dev See {Governor-proposalThreshold}. */ function proposalThreshold() public view virtual override(Governor, GovernorSettings) returns (uint256) { return GovernorSettings.proposalThreshold(); } error InvalidTimepoint(); error ParamLengthsNotEqual(); error SenderVotingWeightBelowProposalThreshold(); error ShortCircuitNumeratorGreaterThanQuorumDenominator(); error Unauthorized(); }
// SPDX-License-Identifier: ISC pragma solidity >=0.8.19; import { Enum } from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol"; interface IFraxGovernorOmega { struct TxHashArgs { address to; uint256 value; bytes data; Enum.Operation operation; uint256 safeTxGas; uint256 baseGas; uint256 gasPrice; address gasToken; address refundReceiver; uint256 _nonce; } function $delegateCallAllowlist(address contractAddress) external view returns (uint256 status); function $gnosisSafeToNonceToTxHash(address safe, uint256 safeNonce) external view returns (bytes32 txHash); function $safeAllowlist(address safe) external view returns (uint256 status); function $safeVotingPeriod(address safe) external view returns (uint256 votingPeriod); function $snapshotTimestampToSnapshotBlockNumber(uint256 snapshot) external view returns (uint256 blockNumber); function $votingDelayBlocks() external view returns (uint256); function BALLOT_TYPEHASH() external view returns (bytes32); function CLOCK_MODE() external view returns (string memory); function COUNTING_MODE() external pure returns (string memory); function EXTENDED_BALLOT_TYPEHASH() external view returns (bytes32); function TIMELOCK_CONTROLLER() external view returns (address); function VE_FXS() external view returns (address); function abortTransaction(address teamSafe, bytes memory signatures) external; function addToDelegateCallAllowlist(address[] memory contracts) external; function addToSafeAllowlist(address[] memory safes) external; function addTransaction( address teamSafe, TxHashArgs memory args, bytes memory signatures ) external returns (uint256 optimisticProposalId); function batchAddTransaction( address[] memory teamSafes, TxHashArgs[] memory args, bytes[] memory signatures ) external returns (uint256[] memory optimisticProposalIds); function bulkCastVote(uint256[] memory proposalId, uint8[] memory support) external; function cancel(address[] memory, uint256[] memory, bytes[] memory, bytes32) external pure returns (uint256); function castVote(uint256 proposalId, uint8 support) external returns (uint256); function castVoteBySig(uint256 proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s) external returns (uint256); function castVoteWithReason(uint256 proposalId, uint8 support, string memory reason) external returns (uint256); function castVoteWithReasonAndParams( uint256 proposalId, uint8 support, string memory reason, bytes memory params ) external returns (uint256); function castVoteWithReasonAndParamsBySig( uint256 proposalId, uint8 support, string memory reason, bytes memory params, uint8 v, bytes32 r, bytes32 s ) external returns (uint256); function clock() external view returns (uint48); function eip712Domain() external view returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ); function execute( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) external payable returns (uint256); function fractionalVoteNonce(address) external view returns (uint128); function getVotes(address account, uint256 timepoint) external view returns (uint256); function getVotesWithParams( address account, uint256 timepoint, bytes memory params ) external view returns (uint256); function hasVoted(uint256 proposalId, address account) external view returns (bool); function hashProposal( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) external pure returns (uint256); function name() external view returns (string memory); function onERC1155BatchReceived( address, address, uint256[] memory, uint256[] memory, bytes memory ) external returns (bytes4); function onERC1155Received(address, address, uint256, uint256, bytes memory) external returns (bytes4); function onERC721Received(address, address, uint256, bytes memory) external returns (bytes4); function proposalDeadline(uint256 proposalId) external view returns (uint256); function proposalProposer(uint256 proposalId) external view returns (address); function proposalSnapshot(uint256 proposalId) external view returns (uint256); function proposalThreshold() external view returns (uint256); function proposalVotes( uint256 proposalId ) external view returns (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes); function proposals( uint256 ) external view returns (address proposer, uint40 voteStart, uint40 voteEnd, bool executed, bool canceled); function propose(address[] memory, uint256[] memory, bytes[] memory, string memory) external pure returns (uint256); function quorum(uint256 timepoint) external view returns (uint256 quorumAtTimepoint); function quorumDenominator() external view returns (uint256); function quorumNumerator(uint256 timepoint) external view returns (uint256); function quorumNumerator() external view returns (uint256); function rejectTransaction(address teamSafe, uint256 nonce) external; function relay(address, uint256, bytes memory) external payable; function removeFromDelegateCallAllowlist(address[] memory contracts) external; function removeFromSafeAllowlist(address[] memory safes) external; function setProposalThreshold(uint256 newProposalThreshold) external; function setSafeVotingPeriod(address safe, uint256 newSafeVotingPeriod) external; function setVeFxsVotingDelegation(address veFxsVotingDelegation) external; function setVotingDelay(uint256 newVotingDelay) external; function setVotingDelayBlocks(uint256 newVotingDelayBlocks) external; function setVotingPeriod(uint256 newVotingPeriod) external; function shortCircuitNumerator() external view returns (uint256 latestShortCircuitNumerator); function shortCircuitNumerator(uint256 timepoint) external view returns (uint256 shortCircuitNumeratorAtTimepoint); function shortCircuitThreshold(uint256 timepoint) external view returns (uint256 shortCircuitThresholdAtTimepoint); function state(uint256 proposalId) external view returns (uint8 proposalState); function supportsInterface(bytes4 interfaceId) external view returns (bool); function token() external view returns (address); function updateQuorumNumerator(uint256 newQuorumNumerator) external; function updateShortCircuitNumerator(uint256 newShortCircuitNumerator) external; function version() external view returns (string memory); function voteWeightCast(uint256 proposalId, address account) external view returns (uint128); function votingDelay() external view returns (uint256); function votingPeriod() external view returns (uint256); function lastSnapshotTime() external view returns (uint256); error AlreadyOnDelegateCallAllowlist(address contractAddress); error AlreadyOnSafeAllowlist(address safe); error BadBatchArgs(); error CannotCancelOptimisticTransaction(); error CannotPropose(); error CannotRelay(); error DelegateCallNotAllowed(address to); error DisallowedTarget(address target); error NonceReserved(); error NotOnDelegateCallAllowlist(address contractAddress); error NotOnSafeAllowlist(address safe); error NotTimelockController(); error ProposalAlreadyCanceled(); error SameSafeVotingPeriod(); error TransactionAlreadyApproved(bytes32 txHash); error WrongNonce(); error WrongProposalState(); error WrongSafeSignatureType(); }
// SPDX-License-Identifier: ISC pragma solidity >=0.8.19; import { Enum } from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol"; interface ISafe { // Mapping to keep track of all hashes (message or transaction) that have been approve by ANY owners function approvedHashes(address signer, bytes32 txHash) external returns (uint256); function nonce() external returns (uint256); /** * @dev Marks a hash as approved. This can be used to validate a hash that is used by a signature. * @param hashToApprove The hash that should be marked as approved for signatures that are verified by this contract. */ function approveHash(bytes32 hashToApprove) external; function isOwner(address) external returns (bool); function getThreshold() external view returns (uint256); /// @dev Returns hash to be signed by owners. /// @param to Destination address. /// @param value Ether value. /// @param data Data payload. /// @param operation Operation type. /// @param safeTxGas Fas that should be used for the safe transaction. /// @param baseGas Gas costs for data used to trigger the safe transaction. /// @param gasPrice Maximum gas price that should be used for this transaction. /// @param gasToken Token address (or 0 if ETH) that is used for the payment. /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin). /// @param _nonce Transaction nonce. /// @return Transaction hash. function getTransactionHash( address to, uint256 value, bytes calldata data, Enum.Operation operation, uint256 safeTxGas, uint256 baseGas, uint256 gasPrice, address gasToken, address refundReceiver, uint256 _nonce ) external view returns (bytes32); /// @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise. /// @param dataHash Hash of the data (could be either a message hash or transaction hash) /// @param data That should be signed (this is passed to an external validator contract) /// @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash. /// @param requiredSignatures Amount of required valid signatures. function checkNSignatures( bytes32 dataHash, bytes memory data, bytes memory signatures, uint256 requiredSignatures ) external view; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Checkpoints.sol) // This file was procedurally generated from scripts/generate/templates/Checkpoints.js. pragma solidity ^0.8.0; import "./math/Math.sol"; import "./math/SafeCast.sol"; /** * @dev This library defines the `History` struct, for checkpointing values as they change at different points in * time, and later looking up past values by block number. See {Votes} as an example. * * To create a history of checkpoints define a variable type `Checkpoints.History` in your contract, and store a new * checkpoint for the current transaction block using the {push} function. * * _Available since v4.5._ */ library Checkpoints { struct History { Checkpoint[] _checkpoints; } struct Checkpoint { uint32 _blockNumber; uint224 _value; } /** * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one * before it is returned, or zero otherwise. Because the number returned corresponds to that at the end of the * block, the requested block number must be in the past, excluding the current block. */ function getAtBlock(History storage self, uint256 blockNumber) internal view returns (uint256) { require(blockNumber < block.number, "Checkpoints: block not yet mined"); uint32 key = SafeCast.toUint32(blockNumber); uint256 len = self._checkpoints.length; uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one * before it is returned, or zero otherwise. Similar to {upperLookup} but optimized for the case when the searched * checkpoint is probably "recent", defined as being among the last sqrt(N) checkpoints where N is the number of * checkpoints. */ function getAtProbablyRecentBlock(History storage self, uint256 blockNumber) internal view returns (uint256) { require(blockNumber < block.number, "Checkpoints: block not yet mined"); uint32 key = SafeCast.toUint32(blockNumber); uint256 len = self._checkpoints.length; uint256 low = 0; uint256 high = len; if (len > 5) { uint256 mid = len - Math.sqrt(len); if (key < _unsafeAccess(self._checkpoints, mid)._blockNumber) { high = mid; } else { low = mid + 1; } } uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Pushes a value onto a History so that it is stored as the checkpoint for the current block. * * Returns previous value and new value. */ function push(History storage self, uint256 value) internal returns (uint256, uint256) { return _insert(self._checkpoints, SafeCast.toUint32(block.number), SafeCast.toUint224(value)); } /** * @dev Pushes a value onto a History, by updating the latest value using binary operation `op`. The new value will * be set to `op(latest, delta)`. * * Returns previous value and new value. */ function push( History storage self, function(uint256, uint256) view returns (uint256) op, uint256 delta ) internal returns (uint256, uint256) { return push(self, op(latest(self), delta)); } /** * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints. */ function latest(History storage self) internal view returns (uint224) { uint256 pos = self._checkpoints.length; return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value * in the most recent checkpoint. */ function latestCheckpoint( History storage self ) internal view returns (bool exists, uint32 _blockNumber, uint224 _value) { uint256 pos = self._checkpoints.length; if (pos == 0) { return (false, 0, 0); } else { Checkpoint memory ckpt = _unsafeAccess(self._checkpoints, pos - 1); return (true, ckpt._blockNumber, ckpt._value); } } /** * @dev Returns the number of checkpoint. */ function length(History storage self) internal view returns (uint256) { return self._checkpoints.length; } /** * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint, * or by updating the last one. */ function _insert(Checkpoint[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) { uint256 pos = self.length; if (pos > 0) { // Copying to memory is important here. Checkpoint memory last = _unsafeAccess(self, pos - 1); // Checkpoint keys must be non-decreasing. require(last._blockNumber <= key, "Checkpoint: decreasing keys"); // Update or push new checkpoint if (last._blockNumber == key) { _unsafeAccess(self, pos - 1)._value = value; } else { self.push(Checkpoint({_blockNumber: key, _value: value})); } return (last._value, value); } else { self.push(Checkpoint({_blockNumber: key, _value: value})); return (0, value); } } /** * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none. * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. * * WARNING: `high` should not be greater than the array's length. */ function _upperBinaryLookup( Checkpoint[] storage self, uint32 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._blockNumber > key) { high = mid; } else { low = mid + 1; } } return high; } /** * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none. * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. * * WARNING: `high` should not be greater than the array's length. */ function _lowerBinaryLookup( Checkpoint[] storage self, uint32 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._blockNumber < key) { low = mid + 1; } else { high = mid; } } return high; } /** * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. */ function _unsafeAccess(Checkpoint[] storage self, uint256 pos) private pure returns (Checkpoint storage result) { assembly { mstore(0, self.slot) result.slot := add(keccak256(0, 0x20), pos) } } struct Trace224 { Checkpoint224[] _checkpoints; } struct Checkpoint224 { uint32 _key; uint224 _value; } /** * @dev Pushes a (`key`, `value`) pair into a Trace224 so that it is stored as the checkpoint. * * Returns previous value and new value. */ function push(Trace224 storage self, uint32 key, uint224 value) internal returns (uint224, uint224) { return _insert(self._checkpoints, key, value); } /** * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if there is none. */ function lowerLookup(Trace224 storage self, uint32 key) internal view returns (uint224) { uint256 len = self._checkpoints.length; uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len); return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value; } /** * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none. */ function upperLookup(Trace224 storage self, uint32 key) internal view returns (uint224) { uint256 len = self._checkpoints.length; uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none. * * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high keys). */ function upperLookupRecent(Trace224 storage self, uint32 key) internal view returns (uint224) { uint256 len = self._checkpoints.length; uint256 low = 0; uint256 high = len; if (len > 5) { uint256 mid = len - Math.sqrt(len); if (key < _unsafeAccess(self._checkpoints, mid)._key) { high = mid; } else { low = mid + 1; } } uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints. */ function latest(Trace224 storage self) internal view returns (uint224) { uint256 pos = self._checkpoints.length; return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value * in the most recent checkpoint. */ function latestCheckpoint(Trace224 storage self) internal view returns (bool exists, uint32 _key, uint224 _value) { uint256 pos = self._checkpoints.length; if (pos == 0) { return (false, 0, 0); } else { Checkpoint224 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1); return (true, ckpt._key, ckpt._value); } } /** * @dev Returns the number of checkpoint. */ function length(Trace224 storage self) internal view returns (uint256) { return self._checkpoints.length; } /** * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint, * or by updating the last one. */ function _insert(Checkpoint224[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) { uint256 pos = self.length; if (pos > 0) { // Copying to memory is important here. Checkpoint224 memory last = _unsafeAccess(self, pos - 1); // Checkpoint keys must be non-decreasing. require(last._key <= key, "Checkpoint: decreasing keys"); // Update or push new checkpoint if (last._key == key) { _unsafeAccess(self, pos - 1)._value = value; } else { self.push(Checkpoint224({_key: key, _value: value})); } return (last._value, value); } else { self.push(Checkpoint224({_key: key, _value: value})); return (0, value); } } /** * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none. * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. * * WARNING: `high` should not be greater than the array's length. */ function _upperBinaryLookup( Checkpoint224[] storage self, uint32 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key > key) { high = mid; } else { low = mid + 1; } } return high; } /** * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none. * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. * * WARNING: `high` should not be greater than the array's length. */ function _lowerBinaryLookup( Checkpoint224[] storage self, uint32 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key < key) { low = mid + 1; } else { high = mid; } } return high; } /** * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. */ function _unsafeAccess( Checkpoint224[] storage self, uint256 pos ) private pure returns (Checkpoint224 storage result) { assembly { mstore(0, self.slot) result.slot := add(keccak256(0, 0x20), pos) } } struct Trace160 { Checkpoint160[] _checkpoints; } struct Checkpoint160 { uint96 _key; uint160 _value; } /** * @dev Pushes a (`key`, `value`) pair into a Trace160 so that it is stored as the checkpoint. * * Returns previous value and new value. */ function push(Trace160 storage self, uint96 key, uint160 value) internal returns (uint160, uint160) { return _insert(self._checkpoints, key, value); } /** * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if there is none. */ function lowerLookup(Trace160 storage self, uint96 key) internal view returns (uint160) { uint256 len = self._checkpoints.length; uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len); return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value; } /** * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none. */ function upperLookup(Trace160 storage self, uint96 key) internal view returns (uint160) { uint256 len = self._checkpoints.length; uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none. * * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high keys). */ function upperLookupRecent(Trace160 storage self, uint96 key) internal view returns (uint160) { uint256 len = self._checkpoints.length; uint256 low = 0; uint256 high = len; if (len > 5) { uint256 mid = len - Math.sqrt(len); if (key < _unsafeAccess(self._checkpoints, mid)._key) { high = mid; } else { low = mid + 1; } } uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints. */ function latest(Trace160 storage self) internal view returns (uint160) { uint256 pos = self._checkpoints.length; return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value * in the most recent checkpoint. */ function latestCheckpoint(Trace160 storage self) internal view returns (bool exists, uint96 _key, uint160 _value) { uint256 pos = self._checkpoints.length; if (pos == 0) { return (false, 0, 0); } else { Checkpoint160 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1); return (true, ckpt._key, ckpt._value); } } /** * @dev Returns the number of checkpoint. */ function length(Trace160 storage self) internal view returns (uint256) { return self._checkpoints.length; } /** * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint, * or by updating the last one. */ function _insert(Checkpoint160[] storage self, uint96 key, uint160 value) private returns (uint160, uint160) { uint256 pos = self.length; if (pos > 0) { // Copying to memory is important here. Checkpoint160 memory last = _unsafeAccess(self, pos - 1); // Checkpoint keys must be non-decreasing. require(last._key <= key, "Checkpoint: decreasing keys"); // Update or push new checkpoint if (last._key == key) { _unsafeAccess(self, pos - 1)._value = value; } else { self.push(Checkpoint160({_key: key, _value: value})); } return (last._value, value); } else { self.push(Checkpoint160({_key: key, _value: value})); return (0, value); } } /** * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none. * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. * * WARNING: `high` should not be greater than the array's length. */ function _upperBinaryLookup( Checkpoint160[] storage self, uint96 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key > key) { high = mid; } else { low = mid + 1; } } return high; } /** * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none. * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`. * * WARNING: `high` should not be greater than the array's length. */ function _lowerBinaryLookup( Checkpoint160[] storage self, uint96 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key < key) { low = mid + 1; } else { high = mid; } } return high; } /** * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. */ function _unsafeAccess( Checkpoint160[] storage self, uint256 pos ) private pure returns (Checkpoint160 storage result) { assembly { mstore(0, self.slot) result.slot := add(keccak256(0, 0x20), pos) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5805.sol) pragma solidity ^0.8.0; import "../governance/utils/IVotes.sol"; import "./IERC6372.sol"; interface IERC5805 is IERC6372, IVotes {}
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (governance/Governor.sol) pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol"; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; import "@openzeppelin/contracts/utils/math/SafeCast.sol"; import "@openzeppelin/contracts/utils/structs/DoubleEndedQueue.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "@openzeppelin/contracts/utils/Context.sol"; import "@openzeppelin/contracts/governance/IGovernor.sol"; /** * @dev Core of the governance system, designed to be extended though various modules. * * This contract is abstract and requires several functions to be implemented in various modules: * * - A counting module must implement {quorum}, {_quorumReached}, {_voteSucceeded} and {_countVote} * - A voting module must implement {_getVotes} * - Additionally, {votingPeriod} must also be implemented * * _Available since v4.3._ */ abstract contract Governor is Context, ERC165, EIP712, IGovernor, IERC721Receiver, IERC1155Receiver { using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque; bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)"); bytes32 public constant EXTENDED_BALLOT_TYPEHASH = keccak256("ExtendedBallot(uint256 proposalId,uint8 support,string reason,bytes params)"); struct ProposalCore { address proposer; uint40 voteStart; uint40 voteEnd; bool executed; bool canceled; } string private _name; /// @custom:oz-retyped-from mapping(uint256 => Governor.ProposalCore) mapping(uint256 => ProposalCore) public proposals; // This queue keeps track of the governor operating on itself. Calls to functions protected by the // {onlyGovernance} modifier needs to be whitelisted in this queue. Whitelisting is set in {_beforeExecute}, // consumed by the {onlyGovernance} modifier and eventually reset in {_afterExecute}. This ensures that the // execution of {onlyGovernance} protected calls can only be achieved through successful proposals. DoubleEndedQueue.Bytes32Deque private _governanceCall; /** * @dev Restricts a function so it can only be executed through governance proposals. For example, governance * parameter setters in {GovernorSettings} are protected using this modifier. * * The governance executing address may be different from the Governor's own address, for example it could be a * timelock. This can be customized by modules by overriding {_executor}. The executor is only able to invoke these * functions during the execution of the governor's {execute} function, and not under any other circumstances. Thus, * for example, additional timelock proposers are not able to change governance parameters without going through the * governance protocol (since v4.6). */ modifier onlyGovernance() { require(_msgSender() == _executor(), "Governor: onlyGovernance"); if (_executor() != address(this)) { bytes32 msgDataHash = keccak256(_msgData()); // loop until popping the expected operation - throw if deque is empty (operation not authorized) while (_governanceCall.popFront() != msgDataHash) { } } _; } /** * @dev Sets the value for {name} and {version} */ constructor(string memory name_) EIP712(name_, version()) { _name = name_; } /** * @dev Function to receive ETH that will be handled by the governor (disabled if executor is a third party contract) */ receive() external payable virtual { require(_executor() == address(this), "Governor: must send to executor"); } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { bytes4 governorCancelId = this.cancel.selector ^ this.proposalProposer.selector; bytes4 governorParamsId = this.castVoteWithReasonAndParams.selector ^ this.castVoteWithReasonAndParamsBySig.selector ^ this.getVotesWithParams.selector; // The original interface id in v4.3. bytes4 governor43Id = type(IGovernor).interfaceId ^ type(IERC6372).interfaceId ^ governorCancelId ^ governorParamsId; // An updated interface id in v4.6, with params added. bytes4 governor46Id = type(IGovernor).interfaceId ^ type(IERC6372).interfaceId ^ governorCancelId; // For the updated interface id in v4.9, we use governorCancelId directly. return interfaceId == governor43Id || interfaceId == governor46Id || interfaceId == governorCancelId || interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IGovernor-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IGovernor-version}. */ function version() public view virtual override returns (string memory) { return "1"; } /** * @dev See {IGovernor-hashProposal}. * * The proposal id is produced by hashing the ABI encoded `targets` array, the `values` array, the `calldatas` array * and the descriptionHash (bytes32 which itself is the keccak256 hash of the description string). This proposal id * can be produced from the proposal data which is part of the {ProposalCreated} event. It can even be computed in * advance, before the proposal is submitted. * * Note that the chainId and the governor address are not part of the proposal id computation. Consequently, the * same proposal (with same operation and same description) will have the same id if submitted on multiple governors * across multiple networks. This also means that in order to execute the same operation twice (on the same * governor) the proposer will have to change the description in order to avoid proposal id conflicts. */ function hashProposal(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) public pure virtual override returns (uint256) { return uint256(keccak256(abi.encode(targets, values, calldatas, descriptionHash))); } /** * @dev See {IGovernor-state}. */ function state(uint256 proposalId) public view virtual override returns (ProposalState) { ProposalCore storage proposal = proposals[proposalId]; if (proposal.executed) { return ProposalState.Executed; } if (proposal.canceled) { return ProposalState.Canceled; } uint256 snapshot = proposalSnapshot(proposalId); if (snapshot == 0) { revert("Governor: unknown proposal id"); } uint256 currentTimepoint = clock(); if (snapshot >= currentTimepoint) { return ProposalState.Pending; } uint256 deadline = proposalDeadline(proposalId); if (deadline >= currentTimepoint) { return ProposalState.Active; } if (_quorumReached(proposalId) && _voteSucceeded(proposalId)) { return ProposalState.Succeeded; } else { return ProposalState.Defeated; } } /** * @dev Part of the Governor Bravo's interface: _"The number of votes required in order for a voter to become a proposer"_. */ function proposalThreshold() public view virtual returns (uint256) { return 0; } /** * @dev See {IGovernor-proposalSnapshot}. */ function proposalSnapshot(uint256 proposalId) public view virtual override returns (uint256) { return proposals[proposalId].voteStart; } /** * @dev See {IGovernor-proposalDeadline}. */ function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256) { return proposals[proposalId].voteEnd; } /** * @dev Returns the account that created a given proposal. */ function proposalProposer(uint256 proposalId) public view virtual override returns (address) { return proposals[proposalId].proposer; } /** * @dev Amount of votes already cast passes the threshold limit. */ function _quorumReached(uint256 proposalId) internal view virtual returns (bool); /** * @dev Is the proposal successful or not. */ function _voteSucceeded(uint256 proposalId) internal view virtual returns (bool); /** * @dev Get the voting weight of `account` at a specific `timepoint`, for a vote as described by `params`. */ function _getVotes(address account, uint256 timepoint, bytes memory params) internal view virtual returns (uint256); /** * @dev Register a vote for `proposalId` by `account` with a given `support`, voting `weight` and voting `params`. * * Note: Support is generic and can represent various things depending on the voting system used. */ function _countVote(uint256 proposalId, address account, uint8 support, uint256 weight, bytes memory params) internal virtual; /** * @dev Default additional encoded parameters used by castVote methods that don't include them * * Note: Should be overridden by specific implementations to use an appropriate value, the * meaning of the additional params, in the context of that implementation */ function _defaultParams() internal view virtual returns (bytes memory) { return ""; } /** * @dev See {IGovernor-propose}. */ function propose(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description) public virtual override returns (uint256) { address proposer = _msgSender(); uint256 currentTimepoint = clock(); require(getVotes(proposer, currentTimepoint - 1) >= proposalThreshold(), "Governor: proposer votes below proposal threshold"); uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); require(targets.length == values.length, "Governor: invalid proposal length"); require(targets.length == calldatas.length, "Governor: invalid proposal length"); require(targets.length > 0, "Governor: empty proposal"); require(proposals[proposalId].voteStart == 0, "Governor: proposal already exists"); uint256 snapshot = currentTimepoint + votingDelay(); uint256 deadline = snapshot + votingPeriod(); proposals[proposalId] = ProposalCore({ proposer: proposer, voteStart: SafeCast.toUint40(snapshot), voteEnd: SafeCast.toUint40(deadline), executed: false, canceled: false }); emit ProposalCreated(proposalId, proposer, targets, values, new string[](targets.length), calldatas, snapshot, deadline, description); return proposalId; } /** * @dev See {IGovernor-execute}. */ function execute(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) public payable virtual override returns (uint256) { uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); ProposalState currentState = state(proposalId); require(currentState == ProposalState.Succeeded || currentState == ProposalState.Queued, "Governor: proposal not successful"); proposals[proposalId].executed = true; emit ProposalExecuted(proposalId); _beforeExecute(proposalId, targets, values, calldatas, descriptionHash); _execute(proposalId, targets, values, calldatas, descriptionHash); _afterExecute(proposalId, targets, values, calldatas, descriptionHash); return proposalId; } /** * @dev See {IGovernor-cancel}. */ function cancel(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) public virtual override returns (uint256) { uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); require(state(proposalId) == ProposalState.Pending, "Governor: too late to cancel"); require(_msgSender() == proposals[proposalId].proposer, "Governor: only proposer can cancel"); return _cancel(targets, values, calldatas, descriptionHash); } /** * @dev Internal execution mechanism. Can be overridden to implement different execution mechanism */ function _execute(uint256, /* proposalId */ address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 /*descriptionHash*/ ) internal virtual { string memory errorMessage = "Governor: call reverted without message"; for (uint256 i = 0; i < targets.length; ++i) { (bool success, bytes memory returndata) = targets[i].call{ value: values[i] }(calldatas[i]); Address.verifyCallResult(success, returndata, errorMessage); } } /** * @dev Hook before execution is triggered. */ function _beforeExecute(uint256, /* proposalId */ address[] memory targets, uint256[] memory, /* values */ bytes[] memory calldatas, bytes32 /*descriptionHash*/ ) internal virtual { if (_executor() != address(this)) { for (uint256 i = 0; i < targets.length; ++i) { if (targets[i] == address(this)) { _governanceCall.pushBack(keccak256(calldatas[i])); } } } } /** * @dev Hook after execution is triggered. */ function _afterExecute(uint256, /* proposalId */ address[] memory, /* targets */ uint256[] memory, /* values */ bytes[] memory, /* calldatas */ bytes32 /*descriptionHash*/ ) internal virtual { if (_executor() != address(this)) { if (!_governanceCall.empty()) { _governanceCall.clear(); } } } /** * @dev Internal cancel mechanism: locks up the proposal timer, preventing it from being re-submitted. Marks it as * canceled to allow distinguishing it from executed proposals. * * Emits a {IGovernor-ProposalCanceled} event. */ function _cancel(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) internal virtual returns (uint256) { uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); ProposalState currentState = state(proposalId); require(currentState != ProposalState.Canceled && currentState != ProposalState.Expired && currentState != ProposalState.Executed, "Governor: proposal not active"); proposals[proposalId].canceled = true; emit ProposalCanceled(proposalId); return proposalId; } /** * @dev See {IGovernor-getVotes}. */ function getVotes(address account, uint256 timepoint) public view virtual override returns (uint256) { return _getVotes(account, timepoint, _defaultParams()); } /** * @dev See {IGovernor-getVotesWithParams}. */ function getVotesWithParams(address account, uint256 timepoint, bytes memory params) public view virtual override returns (uint256) { return _getVotes(account, timepoint, params); } /** * @dev See {IGovernor-castVote}. */ function castVote(uint256 proposalId, uint8 support) public virtual override returns (uint256) { address voter = _msgSender(); return _castVote(proposalId, voter, support, ""); } /** * @dev See {IGovernor-castVoteWithReason}. */ function castVoteWithReason(uint256 proposalId, uint8 support, string calldata reason) public virtual override returns (uint256) { address voter = _msgSender(); return _castVote(proposalId, voter, support, reason); } /** * @dev See {IGovernor-castVoteWithReasonAndParams}. */ function castVoteWithReasonAndParams(uint256 proposalId, uint8 support, string calldata reason, bytes memory params) public virtual override returns (uint256) { address voter = _msgSender(); return _castVote(proposalId, voter, support, reason, params); } /** * @dev See {IGovernor-castVoteBySig}. */ function castVoteBySig(uint256 proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s) public virtual override returns (uint256) { address voter = ECDSA.recover(_hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support))), v, r, s); return _castVote(proposalId, voter, support, ""); } /** * @dev See {IGovernor-castVoteWithReasonAndParamsBySig}. */ function castVoteWithReasonAndParamsBySig(uint256 proposalId, uint8 support, string calldata reason, bytes memory params, uint8 v, bytes32 r, bytes32 s) public virtual override returns (uint256) { address voter = ECDSA.recover(_hashTypedDataV4(keccak256(abi.encode(EXTENDED_BALLOT_TYPEHASH, proposalId, support, keccak256(bytes(reason)), keccak256(params)))), v, r, s); return _castVote(proposalId, voter, support, reason, params); } /** * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function. Uses the _defaultParams(). * * Emits a {IGovernor-VoteCast} event. */ function _castVote(uint256 proposalId, address account, uint8 support, string memory reason) internal virtual returns (uint256) { return _castVote(proposalId, account, support, reason, _defaultParams()); } /** * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function. * * Emits a {IGovernor-VoteCast} event. */ function _castVote(uint256 proposalId, address account, uint8 support, string memory reason, bytes memory params) internal virtual returns (uint256) { ProposalCore storage proposal = proposals[proposalId]; require(state(proposalId) == ProposalState.Active, "Governor: vote not currently active"); uint256 weight = _getVotes(account, proposal.voteStart, params); _countVote(proposalId, account, support, weight, params); if (params.length == 0) { emit VoteCast(account, proposalId, support, weight, reason); } else { emit VoteCastWithParams(account, proposalId, support, weight, reason, params); } return weight; } /** * @dev Relays a transaction or function call to an arbitrary target. In cases where the governance executor * is some contract other than the governor itself, like when using a timelock, this function can be invoked * in a governance proposal to recover tokens or Ether that was sent to the governor contract by mistake. * Note that if the executor is simply the governor itself, use of `relay` is redundant. */ function relay(address target, uint256 value, bytes calldata data) external payable virtual onlyGovernance { (bool success, bytes memory returndata) = target.call{ value: value }(data); Address.verifyCallResult(success, returndata, "Governor: relay reverted without message"); } /** * @dev Address through which the governor executes action. Will be overloaded by module that execute actions * through another contract such as a timelock. */ function _executor() internal view virtual returns (address) { return address(this); } /** * @dev See {IERC721Receiver-onERC721Received}. */ function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) { return this.onERC721Received.selector; } /** * @dev See {IERC1155Receiver-onERC1155Received}. */ function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual override returns (bytes4) { return this.onERC1155Received.selector; } /** * @dev See {IERC1155Receiver-onERC1155BatchReceived}. */ function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) public virtual override returns (bytes4) { return this.onERC1155BatchReceived.selector; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.X.X (governance/extensions/GovernorCountingFractional.sol) pragma solidity ^0.8.0; import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import { Governor } from "./Governor.sol"; import { GovernorCompatibilityBravo } from "@openzeppelin/contracts/governance/compatibility/GovernorCompatibilityBravo.sol"; import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol"; /** * @notice Extension of {Governor} for 3 option fractional vote counting. When * voting, a delegate may split their vote weight between Against/For/Abstain. * This is most useful when the delegate is itself a contract, implementing its * own rules for voting. By allowing a contract-delegate to split its vote * weight, the voting preferences of many disparate token holders can be rolled * up into a single vote to the Governor itself. Some example use cases include * voting with tokens that are held by a DeFi pool, voting from L2 with tokens * held by a bridge, or voting privately from a shielded pool using zero * knowledge proofs. */ abstract contract GovernorCountingFractional is Governor { struct ProposalVote { uint128 againstVotes; uint128 forVotes; uint128 abstainVotes; } /** * @dev Mapping from proposal ID to vote tallies for that proposal. */ mapping(uint256 => ProposalVote) private _proposalVotes; /** * @dev Mapping from proposal ID and address to the weight the address * has cast on that proposal, e.g. _proposalVotersWeightCast[42][0xBEEF] * would tell you the number of votes that 0xBEEF has cast on proposal 42. */ mapping(uint256 => mapping(address => uint128)) private _proposalVotersWeightCast; /** * @dev Mapping from voter address to signature-based vote nonce. The * voter's nonce increments each time a signature-based vote is cast with * fractional voting params and must be included in the `params` as the last * 16 bytes when signing for a fractional vote. */ mapping(address => uint128) public fractionalVoteNonce; /** * @dev See {IGovernor-COUNTING_MODE}. */ // solhint-disable-next-line func-name-mixedcase function COUNTING_MODE() public pure virtual override returns (string memory) { return "support=bravo&quorum=for,abstain¶ms=fractional"; } /** * @dev See {IGovernor-hasVoted}. */ function hasVoted(uint256 proposalId, address account) public view virtual override returns (bool) { return _proposalVotersWeightCast[proposalId][account] > 0; } /** * @dev Get the number of votes cast thus far on proposal `proposalId` by * account `account`. Useful for integrations that allow delegates to cast * rolling, partial votes. */ function voteWeightCast(uint256 proposalId, address account) public view returns (uint128) { return _proposalVotersWeightCast[proposalId][account]; } /** * @dev Accessor to the internal vote counts. */ function proposalVotes( uint256 proposalId ) public view virtual returns (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes) { ProposalVote storage proposalVote = _proposalVotes[proposalId]; return (proposalVote.againstVotes, proposalVote.forVotes, proposalVote.abstainVotes); } /** * @dev See {Governor-_quorumReached}. */ function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) { ProposalVote storage proposalVote = _proposalVotes[proposalId]; return quorum(proposalSnapshot(proposalId)) <= proposalVote.forVotes + proposalVote.abstainVotes; } /** * @dev See {Governor-_voteSucceeded}. In this module, forVotes must be > againstVotes. */ function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) { ProposalVote storage proposalVote = _proposalVotes[proposalId]; return proposalVote.forVotes > proposalVote.againstVotes; } /** * @notice See {Governor-_countVote}. * * @dev Function that records the delegate's votes. * * If the `voteData` bytes parameter is empty, then this module behaves * identically to GovernorBravo. That is, it assigns the full weight of the * delegate to the `support` parameter, which follows the `VoteType` enum * from Governor Bravo. * * If the `voteData` bytes parameter is not zero, then it _must_ be three * packed uint128s, totaling 48 bytes, representing the weight the delegate * assigns to Against, For, and Abstain respectively, i.e. * `abi.encodePacked(againstVotes, forVotes, abstainVotes)`. The sum total of * the three decoded vote weights _must_ be less than or equal to the * delegate's remaining weight on the proposal, i.e. their checkpointed * total weight minus votes already cast on the proposal. * * See `_countVoteNominal` and `_countVoteFractional` for more details. */ function _countVote( uint256 proposalId, address account, uint8 support, uint256 totalWeight, bytes memory voteData ) internal virtual override { require(totalWeight > 0, "GovernorCountingFractional: no weight"); if (_proposalVotersWeightCast[proposalId][account] >= totalWeight) { revert("GovernorCountingFractional: all weight cast"); } uint128 safeTotalWeight = SafeCast.toUint128(totalWeight); if (voteData.length == 0) { _countVoteNominal(proposalId, account, safeTotalWeight, support); } else { _countVoteFractional(proposalId, account, safeTotalWeight, voteData); } } /** * @dev Record votes with full weight cast for `support`. * * Because this function votes with the delegate's full weight, it can only * be called once per proposal. It will revert if combined with a fractional * vote before or after. */ function _countVoteNominal(uint256 proposalId, address account, uint128 totalWeight, uint8 support) internal { require( _proposalVotersWeightCast[proposalId][account] == 0, "GovernorCountingFractional: vote would exceed weight" ); _proposalVotersWeightCast[proposalId][account] = totalWeight; if (support == uint8(GovernorCompatibilityBravo.VoteType.Against)) { _proposalVotes[proposalId].againstVotes += totalWeight; } else if (support == uint8(GovernorCompatibilityBravo.VoteType.For)) { _proposalVotes[proposalId].forVotes += totalWeight; } else if (support == uint8(GovernorCompatibilityBravo.VoteType.Abstain)) { _proposalVotes[proposalId].abstainVotes += totalWeight; } else { revert("GovernorCountingFractional: invalid support value, must be included in VoteType enum"); } } /** * @dev Count votes with fractional weight. * * `voteData` is expected to be three packed uint128s, i.e. * `abi.encodePacked(againstVotes, forVotes, abstainVotes)`. * * This function can be called multiple times for the same account and * proposal, i.e. partial/rolling votes are allowed. For example, an account * with total weight of 10 could call this function three times with the * following vote data: * - against: 1, for: 0, abstain: 2 * - against: 3, for: 1, abstain: 0 * - against: 1, for: 1, abstain: 1 * The result of these three calls would be that the account casts 5 votes * AGAINST, 2 votes FOR, and 3 votes ABSTAIN on the proposal. Though * partial, votes are still final once cast and cannot be changed or * overridden. Subsequent partial votes simply increment existing totals. * * Note that if partial votes are cast, all remaining weight must be cast * with _countVoteFractional: _countVoteNominal will revert. */ function _countVoteFractional( uint256 proposalId, address account, uint128 totalWeight, bytes memory voteData ) internal { require(voteData.length == 48, "GovernorCountingFractional: invalid voteData"); (uint128 _againstVotes, uint128 _forVotes, uint128 _abstainVotes) = _decodePackedVotes(voteData); uint128 _existingWeight = _proposalVotersWeightCast[proposalId][account]; uint256 _newWeight = uint256(_againstVotes) + _forVotes + _abstainVotes + _existingWeight; require(_newWeight <= totalWeight, "GovernorCountingFractional: vote would exceed weight"); // It's safe to downcast here because we've just confirmed that // _newWeight <= totalWeight, and totalWeight is a uint128. _proposalVotersWeightCast[proposalId][account] = uint128(_newWeight); ProposalVote memory _proposalVote = _proposalVotes[proposalId]; _proposalVote = ProposalVote( _proposalVote.againstVotes + _againstVotes, _proposalVote.forVotes + _forVotes, _proposalVote.abstainVotes + _abstainVotes ); _proposalVotes[proposalId] = _proposalVote; } uint256 internal constant _MASK_HALF_WORD_RIGHT = 0xffffffffffffffffffffffffffffffff; // 128 bits of 0's, 128 bits of 1's /** * @dev Decodes three packed uint128's. Uses assembly because of a Solidity * language limitation which prevents slicing bytes stored in memory, rather * than calldata. */ function _decodePackedVotes( bytes memory voteData ) internal pure returns (uint128 againstVotes, uint128 forVotes, uint128 abstainVotes) { assembly { againstVotes := shr(128, mload(add(voteData, 0x20))) forVotes := and(_MASK_HALF_WORD_RIGHT, mload(add(voteData, 0x20))) abstainVotes := shr(128, mload(add(voteData, 0x40))) } } /** * @notice Cast a vote with a reason and additional encoded parameters using * the user's cryptographic signature. * * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length * of params. * * @dev If casting a fractional vote via `params`, the voter's current nonce * must be appended to the `params` as the last 16 bytes and included in the * signature. I.e., the params used when constructing the signature would be: * * abi.encodePacked(againstVotes, forVotes, abstainVotes, nonce) * * See {fractionalVoteNonce} and {_castVote} for more information. */ function castVoteWithReasonAndParamsBySig( uint256 proposalId, uint8 support, string calldata reason, bytes memory params, uint8 v, bytes32 r, bytes32 s ) public virtual override returns (uint256) { // Signature-based fractional voting requires `params` be two full words // in length: // 16 bytes for againstVotes. // 16 bytes for forVotes. // 16 bytes for abstainVotes. // 16 bytes for the signature nonce. // Signature-based nominal voting requires `params` be 0 bytes. require( params.length == 64 || params.length == 0, "GovernorCountingFractional: invalid params for signature-based vote" ); address voter = ECDSA.recover( _hashTypedDataV4( keccak256( abi.encode( EXTENDED_BALLOT_TYPEHASH, proposalId, support, keccak256(bytes(reason)), keccak256(params) ) ) ), v, r, s ); // If params are zero-length all of the voter's weight will be cast so // we don't have to worry about checking/incrementing a nonce. if (params.length == 64) { // Get the nonce out of the params. It is the last half-word. uint128 nonce; assembly { nonce := and( // Perform bitwise AND operation on the data in the second word of // `params` with a mask of 128 zeros followed by 128 ones, i.e. take // the last 128 bits of `params`. _MASK_HALF_WORD_RIGHT, // Load the data from memory at the returned address. mload( // Skip the first 64 bytes (0x40): // 32 bytes encoding the length of the bytes array. // 32 bytes for the first word in the params // Return the memory address for the last word in params. add(params, 0x40) ) ) } require(fractionalVoteNonce[voter] == nonce, "GovernorCountingFractional: signature has already been used"); fractionalVoteNonce[voter]++; // Trim params in place to keep only the first 48 bytes (which are // the voting params) and save gas. assembly { mstore(params, 0x30) } } return _castVote(proposalId, voter, support, reason, params); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (governance/extensions/GovernorSettings.sol) pragma solidity ^0.8.0; import { Governor } from "./Governor.sol"; /** * @dev Extension of {Governor} for settings updatable through governance. * * _Available since v4.4._ */ abstract contract GovernorSettings is Governor { uint256 private _votingDelay; uint256 private _votingPeriod; uint256 private _proposalThreshold; event VotingDelaySet(uint256 oldVotingDelay, uint256 newVotingDelay); event VotingPeriodSet(uint256 oldVotingPeriod, uint256 newVotingPeriod); event ProposalThresholdSet(uint256 oldProposalThreshold, uint256 newProposalThreshold); /** * @dev Initialize the governance parameters. */ constructor(uint256 initialVotingDelay, uint256 initialVotingPeriod, uint256 initialProposalThreshold) { _setVotingDelay(initialVotingDelay); _setVotingPeriod(initialVotingPeriod); _setProposalThreshold(initialProposalThreshold); } /** * @dev See {IGovernor-votingDelay}. */ function votingDelay() public view virtual override returns (uint256) { return _votingDelay; } /** * @dev See {IGovernor-votingPeriod}. */ function votingPeriod() public view virtual override returns (uint256) { return _votingPeriod; } /** * @dev See {Governor-proposalThreshold}. */ function proposalThreshold() public view virtual override returns (uint256) { return _proposalThreshold; } /** * @dev Update the voting delay. This operation can only be performed through a governance proposal. * * Emits a {VotingDelaySet} event. */ function setVotingDelay(uint256 newVotingDelay) public virtual onlyGovernance { _setVotingDelay(newVotingDelay); } /** * @dev Update the voting period. This operation can only be performed through a governance proposal. * * Emits a {VotingPeriodSet} event. */ function setVotingPeriod(uint256 newVotingPeriod) public virtual onlyGovernance { _setVotingPeriod(newVotingPeriod); } /** * @dev Update the proposal threshold. This operation can only be performed through a governance proposal. * * Emits a {ProposalThresholdSet} event. */ function setProposalThreshold(uint256 newProposalThreshold) public virtual onlyGovernance { _setProposalThreshold(newProposalThreshold); } /** * @dev Internal setter for the voting delay. * * Emits a {VotingDelaySet} event. */ function _setVotingDelay(uint256 newVotingDelay) internal virtual { emit VotingDelaySet(_votingDelay, newVotingDelay); _votingDelay = newVotingDelay; } /** * @dev Internal setter for the voting period. * * Emits a {VotingPeriodSet} event. */ function _setVotingPeriod(uint256 newVotingPeriod) internal virtual { // voting period must be at least one block long require(newVotingPeriod > 0, "GovernorSettings: voting period too low"); emit VotingPeriodSet(_votingPeriod, newVotingPeriod); _votingPeriod = newVotingPeriod; } /** * @dev Internal setter for the proposal threshold. * * Emits a {ProposalThresholdSet} event. */ function _setProposalThreshold(uint256 newProposalThreshold) internal virtual { emit ProposalThresholdSet(_proposalThreshold, newProposalThreshold); _proposalThreshold = newProposalThreshold; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (governance/extensions/GovernorVotesQuorumFraction.sol) pragma solidity ^0.8.0; import "./GovernorVotes.sol"; import "@openzeppelin/contracts/utils/Checkpoints.sol"; import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol"; /** * @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token and a quorum expressed as a * fraction of the total supply. * * _Available since v4.3._ */ abstract contract GovernorVotesQuorumFraction is GovernorVotes { using Checkpoints for Checkpoints.Trace224; /// @custom:oz-retyped-from Checkpoints.History Checkpoints.Trace224 private _quorumNumeratorHistory; event QuorumNumeratorUpdated(uint256 oldQuorumNumerator, uint256 newQuorumNumerator); /** * @dev Initialize quorum as a fraction of the token's total supply. * * The fraction is specified as `numerator / denominator`. By default the denominator is 100, so quorum is * specified as a percent: a numerator of 10 corresponds to quorum being 10% of total supply. The denominator can be * customized by overriding {quorumDenominator}. */ constructor(uint256 quorumNumeratorValue) { _updateQuorumNumerator(quorumNumeratorValue); } /** * @dev Returns the current quorum numerator. See {quorumDenominator}. */ function quorumNumerator() public view virtual returns (uint256) { return _quorumNumeratorHistory.latest(); } /** * @dev Returns the quorum numerator at a specific timepoint. See {quorumDenominator}. */ function quorumNumerator(uint256 timepoint) public view virtual returns (uint256) { // If history is empty, fallback to old storage uint256 length = _quorumNumeratorHistory._checkpoints.length; // Optimistic search, check the latest checkpoint Checkpoints.Checkpoint224 memory latest = _quorumNumeratorHistory._checkpoints[length - 1]; if (latest._key <= timepoint) { return latest._value; } // Otherwise, do the binary search return _quorumNumeratorHistory.upperLookupRecent(SafeCast.toUint32(timepoint)); } /** * @dev Returns the quorum denominator. Defaults to 100, but may be overridden. */ function quorumDenominator() public view virtual returns (uint256) { return 100; } /** * @dev Returns the quorum for a timepoint, in terms of number of votes: `supply * numerator / denominator`. */ function quorum(uint256 timepoint) public view virtual override returns (uint256) { return (token.getPastTotalSupply(timepoint) * quorumNumerator(timepoint)) / quorumDenominator(); } /** * @dev Changes the quorum numerator. * * Emits a {QuorumNumeratorUpdated} event. * * Requirements: * * - Must be called through a governance proposal. * - New numerator must be smaller or equal to the denominator. */ function updateQuorumNumerator(uint256 newQuorumNumerator) external virtual onlyGovernance { _updateQuorumNumerator(newQuorumNumerator); } /** * @dev Changes the quorum numerator. * * Emits a {QuorumNumeratorUpdated} event. * * Requirements: * * - New numerator must be smaller or equal to the denominator. */ function _updateQuorumNumerator(uint256 newQuorumNumerator) internal virtual { require( newQuorumNumerator <= quorumDenominator(), "GovernorVotesQuorumFraction: quorumNumerator over quorumDenominator" ); uint256 oldQuorumNumerator = quorumNumerator(); // Set new quorum for future proposals _quorumNumeratorHistory.push(SafeCast.toUint32(clock()), SafeCast.toUint224(newQuorumNumerator)); emit QuorumNumeratorUpdated(oldQuorumNumerator, newQuorumNumerator); } }
// SPDX-License-Identifier: ISC pragma solidity >=0.6.11; pragma abicoder v2; interface IVeFxs { struct LockedBalance { int128 amount; uint256 end; } function commit_transfer_ownership(address addr) external; function apply_transfer_ownership() external; function commit_smart_wallet_checker(address addr) external; function apply_smart_wallet_checker() external; function toggleEmergencyUnlock() external; function recoverERC20(address token_addr, uint256 amount) external; function get_last_user_slope(address addr) external view returns (int128); function user_point_history__ts(address _addr, uint256 _idx) external view returns (uint256); function locked__end(address _addr) external view returns (uint256); function checkpoint() external; function deposit_for(address _addr, uint256 _value) external; function create_lock(uint256 _value, uint256 _unlock_time) external; function increase_amount(uint256 _value) external; function increase_unlock_time(uint256 _unlock_time) external; function withdraw() external; function balanceOf(address addr) external view returns (uint256); function balanceOf(address addr, uint256 _t) external view returns (uint256); function balanceOfAt(address addr, uint256 _block) external view returns (uint256); function totalSupply() external view returns (uint256); function totalSupply(uint256 t) external view returns (uint256); function totalSupplyAt(uint256 _block) external view returns (uint256); function totalFXSSupply() external view returns (uint256); function totalFXSSupplyAt(uint256 _block) external view returns (uint256); function changeController(address _newController) external; function token() external view returns (address); function supply() external view returns (uint256); function locked(address addr) external view returns (LockedBalance memory); function epoch() external view returns (uint256); function point_history( uint256 arg0 ) external view returns (int128 bias, int128 slope, uint256 ts, uint256 blk, uint256 fxs_amt); function user_point_history( address _addr, uint256 _idx ) external view returns (int128 bias, int128 slope, uint256 ts, uint256 blk, uint256 fxs_amt); function user_point_epoch(address arg0) external view returns (uint256); function slope_changes(uint256 arg0) external view returns (int128); function controller() external view returns (address); function transfersEnabled() external view returns (bool); function emergencyUnlockActive() external view returns (bool); function name() external view returns (string memory); function symbol() external view returns (string memory); function version() external view returns (string memory); function decimals() external view returns (uint256); function future_smart_wallet_checker() external view returns (address); function smart_wallet_checker() external view returns (address); function admin() external view returns (address); function future_admin() external view returns (address); function newSnapshotTime(uint256 snapshot) external; }
// SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.7.0 <0.9.0; /// @title Enum - Collection of enums /// @author Richard Meissner - <[email protected]> contract Enum { enum Operation {Call, DelegateCall} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toUint248(uint256 value) internal pure returns (uint248) { require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits"); return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toUint240(uint256 value) internal pure returns (uint240) { require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits"); return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toUint232(uint256 value) internal pure returns (uint232) { require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits"); return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.2._ */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toUint216(uint256 value) internal pure returns (uint216) { require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits"); return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toUint208(uint256 value) internal pure returns (uint208) { require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits"); return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toUint200(uint256 value) internal pure returns (uint200) { require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits"); return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toUint192(uint256 value) internal pure returns (uint192) { require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits"); return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toUint184(uint256 value) internal pure returns (uint184) { require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits"); return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toUint176(uint256 value) internal pure returns (uint176) { require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits"); return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toUint168(uint256 value) internal pure returns (uint168) { require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits"); return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toUint160(uint256 value) internal pure returns (uint160) { require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits"); return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toUint152(uint256 value) internal pure returns (uint152) { require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits"); return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toUint144(uint256 value) internal pure returns (uint144) { require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits"); return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toUint136(uint256 value) internal pure returns (uint136) { require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits"); return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v2.5._ */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toUint120(uint256 value) internal pure returns (uint120) { require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits"); return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toUint112(uint256 value) internal pure returns (uint112) { require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits"); return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toUint104(uint256 value) internal pure returns (uint104) { require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits"); return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.2._ */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toUint88(uint256 value) internal pure returns (uint88) { require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toUint80(uint256 value) internal pure returns (uint80) { require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits"); return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toUint72(uint256 value) internal pure returns (uint72) { require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits"); return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v2.5._ */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toUint56(uint256 value) internal pure returns (uint56) { require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits"); return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toUint48(uint256 value) internal pure returns (uint48) { require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits"); return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toUint40(uint256 value) internal pure returns (uint40) { require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits"); return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v2.5._ */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toUint24(uint256 value) internal pure returns (uint24) { require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits"); return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v2.5._ */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v2.5._ */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. * * _Available since v3.0._ */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); require(downcasted == value, "SafeCast: value doesn't fit in 248 bits"); } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); require(downcasted == value, "SafeCast: value doesn't fit in 240 bits"); } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); require(downcasted == value, "SafeCast: value doesn't fit in 232 bits"); } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.7._ */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); require(downcasted == value, "SafeCast: value doesn't fit in 224 bits"); } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); require(downcasted == value, "SafeCast: value doesn't fit in 216 bits"); } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); require(downcasted == value, "SafeCast: value doesn't fit in 208 bits"); } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); require(downcasted == value, "SafeCast: value doesn't fit in 200 bits"); } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); require(downcasted == value, "SafeCast: value doesn't fit in 192 bits"); } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); require(downcasted == value, "SafeCast: value doesn't fit in 184 bits"); } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); require(downcasted == value, "SafeCast: value doesn't fit in 176 bits"); } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); require(downcasted == value, "SafeCast: value doesn't fit in 168 bits"); } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); require(downcasted == value, "SafeCast: value doesn't fit in 160 bits"); } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); require(downcasted == value, "SafeCast: value doesn't fit in 152 bits"); } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); require(downcasted == value, "SafeCast: value doesn't fit in 144 bits"); } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); require(downcasted == value, "SafeCast: value doesn't fit in 136 bits"); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); require(downcasted == value, "SafeCast: value doesn't fit in 128 bits"); } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); require(downcasted == value, "SafeCast: value doesn't fit in 120 bits"); } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); require(downcasted == value, "SafeCast: value doesn't fit in 112 bits"); } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); require(downcasted == value, "SafeCast: value doesn't fit in 104 bits"); } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.7._ */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); require(downcasted == value, "SafeCast: value doesn't fit in 96 bits"); } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); require(downcasted == value, "SafeCast: value doesn't fit in 88 bits"); } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); require(downcasted == value, "SafeCast: value doesn't fit in 80 bits"); } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); require(downcasted == value, "SafeCast: value doesn't fit in 72 bits"); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); require(downcasted == value, "SafeCast: value doesn't fit in 64 bits"); } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); require(downcasted == value, "SafeCast: value doesn't fit in 56 bits"); } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); require(downcasted == value, "SafeCast: value doesn't fit in 48 bits"); } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); require(downcasted == value, "SafeCast: value doesn't fit in 40 bits"); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); require(downcasted == value, "SafeCast: value doesn't fit in 32 bits"); } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); require(downcasted == value, "SafeCast: value doesn't fit in 24 bits"); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); require(downcasted == value, "SafeCast: value doesn't fit in 16 bits"); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); require(downcasted == value, "SafeCast: value doesn't fit in 8 bits"); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. * * _Available since v3.0._ */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (governance/utils/IVotes.sol) pragma solidity ^0.8.0; /** * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts. * * _Available since v4.5._ */ interface IVotes { /** * @dev Emitted when an account changes their delegate. */ event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); /** * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes. */ event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance); /** * @dev Returns the current amount of votes that `account` has. */ function getVotes(address account) external view returns (uint256); /** * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is * configured to use block numbers, this will return the value at the end of the corresponding block. */ function getPastVotes(address account, uint256 timepoint) external view returns (uint256); /** * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is * configured to use block numbers, this will return the value at the end of the corresponding block. * * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. * Votes that have not been delegated are still part of total supply, even though they would not participate in a * vote. */ function getPastTotalSupply(uint256 timepoint) external view returns (uint256); /** * @dev Returns the delegate that `account` has chosen. */ function delegates(address account) external view returns (address); /** * @dev Delegates votes from the sender to `delegatee`. */ function delegate(address delegatee) external; /** * @dev Delegates votes from signer to `delegatee`. */ function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC6372.sol) pragma solidity ^0.8.0; interface IERC6372 { /** * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting). */ function clock() external view returns (uint48); /** * @dev Description of the clock */ // solhint-disable-next-line func-name-mixedcase function CLOCK_MODE() external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev _Available since v3.1._ */ interface IERC1155Receiver is IERC165 { /** * @dev Handles the receipt of a single ERC1155 token type. This function is * called at the end of a `safeTransferFrom` after the balance has been updated. * * NOTE: To accept the transfer, this must return * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * (i.e. 0xf23a6e61, or its own function selector). * * @param operator The address which initiated the transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param id The ID of the token being transferred * @param value The amount of tokens being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @dev Handles the receipt of a multiple ERC1155 token types. This function * is called at the end of a `safeBatchTransferFrom` after the balances have * been updated. * * NOTE: To accept the transfer(s), this must return * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * (i.e. 0xbc197c81, or its own function selector). * * @param operator The address which initiated the batch transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param ids An array containing ids of each token being transferred (order and length must match values array) * @param values An array containing amounts of each token being transferred (order and length must match ids array) * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) { // 32 is the length in bytes of hash, // enforced by the type signature above /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") mstore(0x1c, hash) message := keccak256(0x00, 0x3c) } } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, "\x19\x01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) data := keccak256(ptr, 0x42) } } /** * @dev Returns an Ethereum Signed Data with intended validator, created from a * `validator` and `data` according to the version 0 of EIP-191. * * See {recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x00", validator, data)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol) pragma solidity ^0.8.8; import "./ECDSA.sol"; import "../ShortStrings.sol"; import "../../interfaces/IERC5267.sol"; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding * they need in their contracts using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the * separator from the immutable values, which is cheaper than accessing a cached version in cold storage. * * _Available since v3.4._ * * @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment */ abstract contract EIP712 is IERC5267 { using ShortStrings for *; bytes32 private constant _TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to // invalidate the cached domain separator if the chain id changes. bytes32 private immutable _cachedDomainSeparator; uint256 private immutable _cachedChainId; address private immutable _cachedThis; bytes32 private immutable _hashedName; bytes32 private immutable _hashedVersion; ShortString private immutable _name; ShortString private immutable _version; string private _nameFallback; string private _versionFallback; /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ constructor(string memory name, string memory version) { _name = name.toShortStringWithFallback(_nameFallback); _version = version.toShortStringWithFallback(_versionFallback); _hashedName = keccak256(bytes(name)); _hashedVersion = keccak256(bytes(version)); _cachedChainId = block.chainid; _cachedDomainSeparator = _buildDomainSeparator(); _cachedThis = address(this); } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { if (address(this) == _cachedThis && block.chainid == _cachedChainId) { return _cachedDomainSeparator; } else { return _buildDomainSeparator(); } } function _buildDomainSeparator() private view returns (bytes32) { return keccak256(abi.encode(_TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash); } /** * @dev See {EIP-5267}. * * _Available since v4.9._ */ function eip712Domain() public view virtual override returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ) { return ( hex"0f", // 01111 _name.toStringWithFallback(_nameFallback), _version.toStringWithFallback(_versionFallback), block.chainid, address(this), bytes32(0), new uint256[](0) ); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/DoubleEndedQueue.sol) pragma solidity ^0.8.4; import "../math/SafeCast.sol"; /** * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that * the existing queue contents are left in storage. * * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be * used in storage, and not in memory. * ```solidity * DoubleEndedQueue.Bytes32Deque queue; * ``` * * _Available since v4.6._ */ library DoubleEndedQueue { /** * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty. */ error Empty(); /** * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds. */ error OutOfBounds(); /** * @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end * are packed in a single storage slot for efficient access. Since the items are added one at a time we can safely * assume that these 128-bit indices will not overflow, and use unchecked arithmetic. * * Struct members have an underscore prefix indicating that they are "private" and should not be read or written to * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and * lead to unexpected behavior. * * Indices are in the range [begin, end) which means the first item is at data[begin] and the last item is at * data[end - 1]. */ struct Bytes32Deque { int128 _begin; int128 _end; mapping(int128 => bytes32) _data; } /** * @dev Inserts an item at the end of the queue. */ function pushBack(Bytes32Deque storage deque, bytes32 value) internal { int128 backIndex = deque._end; deque._data[backIndex] = value; unchecked { deque._end = backIndex + 1; } } /** * @dev Removes the item at the end of the queue and returns it. * * Reverts with `Empty` if the queue is empty. */ function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) { if (empty(deque)) revert Empty(); int128 backIndex; unchecked { backIndex = deque._end - 1; } value = deque._data[backIndex]; delete deque._data[backIndex]; deque._end = backIndex; } /** * @dev Inserts an item at the beginning of the queue. */ function pushFront(Bytes32Deque storage deque, bytes32 value) internal { int128 frontIndex; unchecked { frontIndex = deque._begin - 1; } deque._data[frontIndex] = value; deque._begin = frontIndex; } /** * @dev Removes the item at the beginning of the queue and returns it. * * Reverts with `Empty` if the queue is empty. */ function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) { if (empty(deque)) revert Empty(); int128 frontIndex = deque._begin; value = deque._data[frontIndex]; delete deque._data[frontIndex]; unchecked { deque._begin = frontIndex + 1; } } /** * @dev Returns the item at the beginning of the queue. * * Reverts with `Empty` if the queue is empty. */ function front(Bytes32Deque storage deque) internal view returns (bytes32 value) { if (empty(deque)) revert Empty(); int128 frontIndex = deque._begin; return deque._data[frontIndex]; } /** * @dev Returns the item at the end of the queue. * * Reverts with `Empty` if the queue is empty. */ function back(Bytes32Deque storage deque) internal view returns (bytes32 value) { if (empty(deque)) revert Empty(); int128 backIndex; unchecked { backIndex = deque._end - 1; } return deque._data[backIndex]; } /** * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at * `length(deque) - 1`. * * Reverts with `OutOfBounds` if the index is out of bounds. */ function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) { // int256(deque._begin) is a safe upcast int128 idx = SafeCast.toInt128(int256(deque._begin) + SafeCast.toInt256(index)); if (idx >= deque._end) revert OutOfBounds(); return deque._data[idx]; } /** * @dev Resets the queue back to being empty. * * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses * out on potential gas refunds. */ function clear(Bytes32Deque storage deque) internal { deque._begin = 0; deque._end = 0; } /** * @dev Returns the number of items in the queue. */ function length(Bytes32Deque storage deque) internal view returns (uint256) { // The interface preserves the invariant that begin <= end so we assume this will not overflow. // We also assume there are at most int256.max items in the queue. unchecked { return uint256(int256(deque._end) - int256(deque._begin)); } } /** * @dev Returns true if the queue is empty. */ function empty(Bytes32Deque storage deque) internal view returns (bool) { return deque._end <= deque._begin; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @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 * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 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://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or 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 { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (governance/IGovernor.sol) pragma solidity ^0.8.0; import "../interfaces/IERC165.sol"; import "../interfaces/IERC6372.sol"; /** * @dev Interface of the {Governor} core. * * _Available since v4.3._ */ abstract contract IGovernor is IERC165, IERC6372 { enum ProposalState { Pending, Active, Canceled, Defeated, Succeeded, Queued, Expired, Executed } /** * @dev Emitted when a proposal is created. */ event ProposalCreated( uint256 proposalId, address proposer, address[] targets, uint256[] values, string[] signatures, bytes[] calldatas, uint256 voteStart, uint256 voteEnd, string description ); /** * @dev Emitted when a proposal is canceled. */ event ProposalCanceled(uint256 proposalId); /** * @dev Emitted when a proposal is executed. */ event ProposalExecuted(uint256 proposalId); /** * @dev Emitted when a vote is cast without params. * * Note: `support` values should be seen as buckets. Their interpretation depends on the voting module used. */ event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason); /** * @dev Emitted when a vote is cast with params. * * Note: `support` values should be seen as buckets. Their interpretation depends on the voting module used. * `params` are additional encoded parameters. Their interpepretation also depends on the voting module used. */ event VoteCastWithParams( address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason, bytes params ); /** * @notice module:core * @dev Name of the governor instance (used in building the ERC712 domain separator). */ function name() public view virtual returns (string memory); /** * @notice module:core * @dev Version of the governor instance (used in building the ERC712 domain separator). Default: "1" */ function version() public view virtual returns (string memory); /** * @notice module:core * @dev See {IERC6372} */ function clock() public view virtual override returns (uint48); /** * @notice module:core * @dev See EIP-6372. */ // solhint-disable-next-line func-name-mixedcase function CLOCK_MODE() public view virtual override returns (string memory); /** * @notice module:voting * @dev A description of the possible `support` values for {castVote} and the way these votes are counted, meant to * be consumed by UIs to show correct vote options and interpret the results. The string is a URL-encoded sequence of * key-value pairs that each describe one aspect, for example `support=bravo&quorum=for,abstain`. * * There are 2 standard keys: `support` and `quorum`. * * - `support=bravo` refers to the vote options 0 = Against, 1 = For, 2 = Abstain, as in `GovernorBravo`. * - `quorum=bravo` means that only For votes are counted towards quorum. * - `quorum=for,abstain` means that both For and Abstain votes are counted towards quorum. * * If a counting module makes use of encoded `params`, it should include this under a `params` key with a unique * name that describes the behavior. For example: * * - `params=fractional` might refer to a scheme where votes are divided fractionally between for/against/abstain. * - `params=erc721` might refer to a scheme where specific NFTs are delegated to vote. * * NOTE: The string can be decoded by the standard * https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams[`URLSearchParams`] * JavaScript class. */ // solhint-disable-next-line func-name-mixedcase function COUNTING_MODE() public view virtual returns (string memory); /** * @notice module:core * @dev Hashing function used to (re)build the proposal id from the proposal details.. */ function hashProposal( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public pure virtual returns (uint256); /** * @notice module:core * @dev Current state of a proposal, following Compound's convention */ function state(uint256 proposalId) public view virtual returns (ProposalState); /** * @notice module:core * @dev Timepoint used to retrieve user's votes and quorum. If using block number (as per Compound's Comp), the * snapshot is performed at the end of this block. Hence, voting for this proposal starts at the beginning of the * following block. */ function proposalSnapshot(uint256 proposalId) public view virtual returns (uint256); /** * @notice module:core * @dev Timepoint at which votes close. If using block number, votes close at the end of this block, so it is * possible to cast a vote during this block. */ function proposalDeadline(uint256 proposalId) public view virtual returns (uint256); /** * @notice module:core * @dev The account that created a proposal. */ function proposalProposer(uint256 proposalId) public view virtual returns (address); /** * @notice module:user-config * @dev Delay, between the proposal is created and the vote starts. The unit this duration is expressed in depends * on the clock (see EIP-6372) this contract uses. * * This can be increased to leave time for users to buy voting power, or delegate it, before the voting of a * proposal starts. */ function votingDelay() public view virtual returns (uint256); /** * @notice module:user-config * @dev Delay between the vote start and vote end. The unit this duration is expressed in depends on the clock * (see EIP-6372) this contract uses. * * NOTE: The {votingDelay} can delay the start of the vote. This must be considered when setting the voting * duration compared to the voting delay. */ function votingPeriod() public view virtual returns (uint256); /** * @notice module:user-config * @dev Minimum number of cast voted required for a proposal to be successful. * * NOTE: The `timepoint` parameter corresponds to the snapshot used for counting vote. This allows to scale the * quorum depending on values such as the totalSupply of a token at this timepoint (see {ERC20Votes}). */ function quorum(uint256 timepoint) public view virtual returns (uint256); /** * @notice module:reputation * @dev Voting power of an `account` at a specific `timepoint`. * * Note: this can be implemented in a number of ways, for example by reading the delegated balance from one (or * multiple), {ERC20Votes} tokens. */ function getVotes(address account, uint256 timepoint) public view virtual returns (uint256); /** * @notice module:reputation * @dev Voting power of an `account` at a specific `timepoint` given additional encoded parameters. */ function getVotesWithParams( address account, uint256 timepoint, bytes memory params ) public view virtual returns (uint256); /** * @notice module:voting * @dev Returns whether `account` has cast a vote on `proposalId`. */ function hasVoted(uint256 proposalId, address account) public view virtual returns (bool); /** * @dev Create a new proposal. Vote start after a delay specified by {IGovernor-votingDelay} and lasts for a * duration specified by {IGovernor-votingPeriod}. * * Emits a {ProposalCreated} event. */ function propose( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description ) public virtual returns (uint256 proposalId); /** * @dev Execute a successful proposal. This requires the quorum to be reached, the vote to be successful, and the * deadline to be reached. * * Emits a {ProposalExecuted} event. * * Note: some module can modify the requirements for execution, for example by adding an additional timelock. */ function execute( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public payable virtual returns (uint256 proposalId); /** * @dev Cancel a proposal. A proposal is cancellable by the proposer, but only while it is Pending state, i.e. * before the vote starts. * * Emits a {ProposalCanceled} event. */ function cancel( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public virtual returns (uint256 proposalId); /** * @dev Cast a vote * * Emits a {VoteCast} event. */ function castVote(uint256 proposalId, uint8 support) public virtual returns (uint256 balance); /** * @dev Cast a vote with a reason * * Emits a {VoteCast} event. */ function castVoteWithReason( uint256 proposalId, uint8 support, string calldata reason ) public virtual returns (uint256 balance); /** * @dev Cast a vote with a reason and additional encoded parameters * * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params. */ function castVoteWithReasonAndParams( uint256 proposalId, uint8 support, string calldata reason, bytes memory params ) public virtual returns (uint256 balance); /** * @dev Cast a vote using the user's cryptographic signature. * * Emits a {VoteCast} event. */ function castVoteBySig( uint256 proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s ) public virtual returns (uint256 balance); /** * @dev Cast a vote with a reason and additional encoded parameters using the user's cryptographic signature. * * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params. */ function castVoteWithReasonAndParamsBySig( uint256 proposalId, uint8 support, string calldata reason, bytes memory params, uint8 v, bytes32 r, bytes32 s ) public virtual returns (uint256 balance); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (governance/compatibility/GovernorCompatibilityBravo.sol) pragma solidity ^0.8.0; import "../../utils/math/SafeCast.sol"; import "../extensions/IGovernorTimelock.sol"; import "../Governor.sol"; import "./IGovernorCompatibilityBravo.sol"; /** * @dev Compatibility layer that implements GovernorBravo compatibility on top of {Governor}. * * This compatibility layer includes a voting system and requires a {IGovernorTimelock} compatible module to be added * through inheritance. It does not include token bindings, nor does it include any variable upgrade patterns. * * NOTE: When using this module, you may need to enable the Solidity optimizer to avoid hitting the contract size limit. * * _Available since v4.3._ */ abstract contract GovernorCompatibilityBravo is IGovernorTimelock, IGovernorCompatibilityBravo, Governor { enum VoteType { Against, For, Abstain } struct ProposalDetails { address proposer; address[] targets; uint256[] values; string[] signatures; bytes[] calldatas; uint256 forVotes; uint256 againstVotes; uint256 abstainVotes; mapping(address => Receipt) receipts; bytes32 descriptionHash; } mapping(uint256 => ProposalDetails) private _proposalDetails; // solhint-disable-next-line func-name-mixedcase function COUNTING_MODE() public pure virtual override returns (string memory) { return "support=bravo&quorum=bravo"; } // ============================================== Proposal lifecycle ============================================== /** * @dev See {IGovernor-propose}. */ function propose( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description ) public virtual override(IGovernor, Governor) returns (uint256) { // Stores the proposal details (if not already present) and executes the propose logic from the core. _storeProposal(_msgSender(), targets, values, new string[](calldatas.length), calldatas, description); return super.propose(targets, values, calldatas, description); } /** * @dev See {IGovernorCompatibilityBravo-propose}. */ function propose( address[] memory targets, uint256[] memory values, string[] memory signatures, bytes[] memory calldatas, string memory description ) public virtual override returns (uint256) { require(signatures.length == calldatas.length, "GovernorBravo: invalid signatures length"); // Stores the full proposal and fallback to the public (possibly overridden) propose. The fallback is done // after the full proposal is stored, so the store operation included in the fallback will be skipped. Here we // call `propose` and not `super.propose` to make sure if a child contract override `propose`, whatever code // is added there is also executed when calling this alternative interface. _storeProposal(_msgSender(), targets, values, signatures, calldatas, description); return propose(targets, values, _encodeCalldata(signatures, calldatas), description); } /** * @dev See {IGovernorCompatibilityBravo-queue}. */ function queue(uint256 proposalId) public virtual override { ( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) = _getProposalParameters(proposalId); queue(targets, values, calldatas, descriptionHash); } /** * @dev See {IGovernorCompatibilityBravo-execute}. */ function execute(uint256 proposalId) public payable virtual override { ( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) = _getProposalParameters(proposalId); execute(targets, values, calldatas, descriptionHash); } /** * @dev Cancel a proposal with GovernorBravo logic. */ function cancel(uint256 proposalId) public virtual override { ( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) = _getProposalParameters(proposalId); cancel(targets, values, calldatas, descriptionHash); } /** * @dev Cancel a proposal with GovernorBravo logic. At any moment a proposal can be cancelled, either by the * proposer, or by third parties if the proposer's voting power has dropped below the proposal threshold. */ function cancel( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public virtual override(IGovernor, Governor) returns (uint256) { uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); address proposer = _proposalDetails[proposalId].proposer; require( _msgSender() == proposer || getVotes(proposer, clock() - 1) < proposalThreshold(), "GovernorBravo: proposer above threshold" ); return _cancel(targets, values, calldatas, descriptionHash); } /** * @dev Encodes calldatas with optional function signature. */ function _encodeCalldata( string[] memory signatures, bytes[] memory calldatas ) private pure returns (bytes[] memory) { bytes[] memory fullcalldatas = new bytes[](calldatas.length); for (uint256 i = 0; i < fullcalldatas.length; ++i) { fullcalldatas[i] = bytes(signatures[i]).length == 0 ? calldatas[i] : abi.encodePacked(bytes4(keccak256(bytes(signatures[i]))), calldatas[i]); } return fullcalldatas; } /** * @dev Retrieve proposal parameters by id, with fully encoded calldatas. */ function _getProposalParameters( uint256 proposalId ) private view returns (address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) { ProposalDetails storage details = _proposalDetails[proposalId]; return ( details.targets, details.values, _encodeCalldata(details.signatures, details.calldatas), details.descriptionHash ); } /** * @dev Store proposal metadata (if not already present) for later lookup. */ function _storeProposal( address proposer, address[] memory targets, uint256[] memory values, string[] memory signatures, bytes[] memory calldatas, string memory description ) private { bytes32 descriptionHash = keccak256(bytes(description)); uint256 proposalId = hashProposal(targets, values, _encodeCalldata(signatures, calldatas), descriptionHash); ProposalDetails storage details = _proposalDetails[proposalId]; if (details.descriptionHash == bytes32(0)) { details.proposer = proposer; details.targets = targets; details.values = values; details.signatures = signatures; details.calldatas = calldatas; details.descriptionHash = descriptionHash; } } // ==================================================== Views ===================================================== /** * @dev See {IGovernorCompatibilityBravo-proposals}. */ function proposals( uint256 proposalId ) public view virtual override returns ( uint256 id, address proposer, uint256 eta, uint256 startBlock, uint256 endBlock, uint256 forVotes, uint256 againstVotes, uint256 abstainVotes, bool canceled, bool executed ) { id = proposalId; eta = proposalEta(proposalId); startBlock = proposalSnapshot(proposalId); endBlock = proposalDeadline(proposalId); ProposalDetails storage details = _proposalDetails[proposalId]; proposer = details.proposer; forVotes = details.forVotes; againstVotes = details.againstVotes; abstainVotes = details.abstainVotes; ProposalState currentState = state(proposalId); canceled = currentState == ProposalState.Canceled; executed = currentState == ProposalState.Executed; } /** * @dev See {IGovernorCompatibilityBravo-getActions}. */ function getActions( uint256 proposalId ) public view virtual override returns ( address[] memory targets, uint256[] memory values, string[] memory signatures, bytes[] memory calldatas ) { ProposalDetails storage details = _proposalDetails[proposalId]; return (details.targets, details.values, details.signatures, details.calldatas); } /** * @dev See {IGovernorCompatibilityBravo-getReceipt}. */ function getReceipt(uint256 proposalId, address voter) public view virtual override returns (Receipt memory) { return _proposalDetails[proposalId].receipts[voter]; } /** * @dev See {IGovernorCompatibilityBravo-quorumVotes}. */ function quorumVotes() public view virtual override returns (uint256) { return quorum(clock() - 1); } // ==================================================== Voting ==================================================== /** * @dev See {IGovernor-hasVoted}. */ function hasVoted(uint256 proposalId, address account) public view virtual override returns (bool) { return _proposalDetails[proposalId].receipts[account].hasVoted; } /** * @dev See {Governor-_quorumReached}. In this module, only forVotes count toward the quorum. */ function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) { ProposalDetails storage details = _proposalDetails[proposalId]; return quorum(proposalSnapshot(proposalId)) <= details.forVotes; } /** * @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be strictly over the againstVotes. */ function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) { ProposalDetails storage details = _proposalDetails[proposalId]; return details.forVotes > details.againstVotes; } /** * @dev See {Governor-_countVote}. In this module, the support follows Governor Bravo. */ function _countVote( uint256 proposalId, address account, uint8 support, uint256 weight, bytes memory // params ) internal virtual override { ProposalDetails storage details = _proposalDetails[proposalId]; Receipt storage receipt = details.receipts[account]; require(!receipt.hasVoted, "GovernorCompatibilityBravo: vote already cast"); receipt.hasVoted = true; receipt.support = support; receipt.votes = SafeCast.toUint96(weight); if (support == uint8(VoteType.Against)) { details.againstVotes += weight; } else if (support == uint8(VoteType.For)) { details.forVotes += weight; } else if (support == uint8(VoteType.Abstain)) { details.abstainVotes += weight; } else { revert("GovernorCompatibilityBravo: invalid vote type"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (governance/extensions/GovernorVotes.sol) pragma solidity ^0.8.0; import { Governor } from "./Governor.sol"; import { IERC5805, IVotes } from "@openzeppelin/contracts/interfaces/IERC5805.sol"; import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol"; /** * @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token, or since v4.5 an {ERC721Votes} token. * * _Available since v4.3._ */ abstract contract GovernorVotes is Governor { IERC5805 public token; constructor(IVotes tokenAddress) { token = IERC5805(address(tokenAddress)); } /** * @dev Clock (as specified in EIP-6372) is set to match the token's clock. Fallback to block numbers if the token * does not implement EIP-6372. */ function clock() public view virtual override returns (uint48) { try token.clock() returns (uint48 timepoint) { return timepoint; } catch { return SafeCast.toUint48(block.number); } } /** * @dev Machine-readable description of the clock as specified in EIP-6372. */ // solhint-disable-next-line func-name-mixedcase function CLOCK_MODE() public view virtual override returns (string memory) { try token.CLOCK_MODE() returns (string memory clockmode) { return clockmode; } catch { return "mode=blocknumber&from=default"; } } /** * Read the voting weight from the token's built in snapshot mechanism (see {Governor-_getVotes}). */ function _getVotes( address account, uint256 timepoint, bytes memory /*params*/ ) internal view virtual override returns (uint256) { return token.getPastVotes(account, timepoint); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; import "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/ShortStrings.sol) pragma solidity ^0.8.8; import "./StorageSlot.sol"; // | string | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | // | length | 0x BB | type ShortString is bytes32; /** * @dev This library provides functions to convert short memory strings * into a `ShortString` type that can be used as an immutable variable. * * Strings of arbitrary length can be optimized using this library if * they are short enough (up to 31 bytes) by packing them with their * length (1 byte) in a single EVM word (32 bytes). Additionally, a * fallback mechanism can be used for every other case. * * Usage example: * * ```solidity * contract Named { * using ShortStrings for *; * * ShortString private immutable _name; * string private _nameFallback; * * constructor(string memory contractName) { * _name = contractName.toShortStringWithFallback(_nameFallback); * } * * function name() external view returns (string memory) { * return _name.toStringWithFallback(_nameFallback); * } * } * ``` */ library ShortStrings { // Used as an identifier for strings longer than 31 bytes. bytes32 private constant _FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF; error StringTooLong(string str); error InvalidShortString(); /** * @dev Encode a string of at most 31 chars into a `ShortString`. * * This will trigger a `StringTooLong` error is the input string is too long. */ function toShortString(string memory str) internal pure returns (ShortString) { bytes memory bstr = bytes(str); if (bstr.length > 31) { revert StringTooLong(str); } return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length)); } /** * @dev Decode a `ShortString` back to a "normal" string. */ function toString(ShortString sstr) internal pure returns (string memory) { uint256 len = byteLength(sstr); // using `new string(len)` would work locally but is not memory safe. string memory str = new string(32); /// @solidity memory-safe-assembly assembly { mstore(str, len) mstore(add(str, 0x20), sstr) } return str; } /** * @dev Return the length of a `ShortString`. */ function byteLength(ShortString sstr) internal pure returns (uint256) { uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF; if (result > 31) { revert InvalidShortString(); } return result; } /** * @dev Encode a string into a `ShortString`, or write it to storage if it is too long. */ function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) { if (bytes(value).length < 32) { return toShortString(value); } else { StorageSlot.getStringSlot(store).value = value; return ShortString.wrap(_FALLBACK_SENTINEL); } } /** * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}. */ function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) { if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) { return toString(value); } else { return store; } } /** * @dev Return the length of a string that was encoded to `ShortString` or written to storage using {setWithFallback}. * * WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of * actual characters as the UTF-8 encoding of a single character can span over multiple bytes. */ function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) { if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) { return byteLength(value); } else { return bytes(store).length; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol) pragma solidity ^0.8.0; interface IERC5267 { /** * @dev MAY be emitted to signal that the domain could have changed. */ event EIP712DomainChanged(); /** * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712 * signature. */ function eip712Domain() external view returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol) pragma solidity ^0.8.0; import "../utils/introspection/IERC165.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (governance/extensions/IGovernorTimelock.sol) pragma solidity ^0.8.0; import "../IGovernor.sol"; /** * @dev Extension of the {IGovernor} for timelock supporting modules. * * _Available since v4.3._ */ abstract contract IGovernorTimelock is IGovernor { event ProposalQueued(uint256 proposalId, uint256 eta); function timelock() public view virtual returns (address); function proposalEta(uint256 proposalId) public view virtual returns (uint256); function queue( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public virtual returns (uint256 proposalId); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.1) (governance/Governor.sol) pragma solidity ^0.8.0; import "../token/ERC721/IERC721Receiver.sol"; import "../token/ERC1155/IERC1155Receiver.sol"; import "../utils/cryptography/ECDSA.sol"; import "../utils/cryptography/EIP712.sol"; import "../utils/introspection/ERC165.sol"; import "../utils/math/SafeCast.sol"; import "../utils/structs/DoubleEndedQueue.sol"; import "../utils/Address.sol"; import "../utils/Context.sol"; import "./IGovernor.sol"; /** * @dev Core of the governance system, designed to be extended though various modules. * * This contract is abstract and requires several functions to be implemented in various modules: * * - A counting module must implement {quorum}, {_quorumReached}, {_voteSucceeded} and {_countVote} * - A voting module must implement {_getVotes} * - Additionally, {votingPeriod} must also be implemented * * _Available since v4.3._ */ abstract contract Governor is Context, ERC165, EIP712, IGovernor, IERC721Receiver, IERC1155Receiver { using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque; bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)"); bytes32 public constant EXTENDED_BALLOT_TYPEHASH = keccak256("ExtendedBallot(uint256 proposalId,uint8 support,string reason,bytes params)"); // solhint-disable var-name-mixedcase struct ProposalCore { // --- start retyped from Timers.BlockNumber at offset 0x00 --- uint64 voteStart; address proposer; bytes4 __gap_unused0; // --- start retyped from Timers.BlockNumber at offset 0x20 --- uint64 voteEnd; bytes24 __gap_unused1; // --- Remaining fields starting at offset 0x40 --------------- bool executed; bool canceled; } // solhint-enable var-name-mixedcase string private _name; /// @custom:oz-retyped-from mapping(uint256 => Governor.ProposalCore) mapping(uint256 => ProposalCore) private _proposals; // This queue keeps track of the governor operating on itself. Calls to functions protected by the // {onlyGovernance} modifier needs to be whitelisted in this queue. Whitelisting is set in {_beforeExecute}, // consumed by the {onlyGovernance} modifier and eventually reset in {_afterExecute}. This ensures that the // execution of {onlyGovernance} protected calls can only be achieved through successful proposals. DoubleEndedQueue.Bytes32Deque private _governanceCall; /** * @dev Restricts a function so it can only be executed through governance proposals. For example, governance * parameter setters in {GovernorSettings} are protected using this modifier. * * The governance executing address may be different from the Governor's own address, for example it could be a * timelock. This can be customized by modules by overriding {_executor}. The executor is only able to invoke these * functions during the execution of the governor's {execute} function, and not under any other circumstances. Thus, * for example, additional timelock proposers are not able to change governance parameters without going through the * governance protocol (since v4.6). */ modifier onlyGovernance() { require(_msgSender() == _executor(), "Governor: onlyGovernance"); if (_executor() != address(this)) { bytes32 msgDataHash = keccak256(_msgData()); // loop until popping the expected operation - throw if deque is empty (operation not authorized) while (_governanceCall.popFront() != msgDataHash) {} } _; } /** * @dev Sets the value for {name} and {version} */ constructor(string memory name_) EIP712(name_, version()) { _name = name_; } /** * @dev Function to receive ETH that will be handled by the governor (disabled if executor is a third party contract) */ receive() external payable virtual { require(_executor() == address(this), "Governor: must send to executor"); } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { bytes4 governorCancelId = this.cancel.selector ^ this.proposalProposer.selector; bytes4 governorParamsId = this.castVoteWithReasonAndParams.selector ^ this.castVoteWithReasonAndParamsBySig.selector ^ this.getVotesWithParams.selector; // The original interface id in v4.3. bytes4 governor43Id = type(IGovernor).interfaceId ^ type(IERC6372).interfaceId ^ governorCancelId ^ governorParamsId; // An updated interface id in v4.6, with params added. bytes4 governor46Id = type(IGovernor).interfaceId ^ type(IERC6372).interfaceId ^ governorCancelId; // For the updated interface id in v4.9, we use governorCancelId directly. return interfaceId == governor43Id || interfaceId == governor46Id || interfaceId == governorCancelId || interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IGovernor-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IGovernor-version}. */ function version() public view virtual override returns (string memory) { return "1"; } /** * @dev See {IGovernor-hashProposal}. * * The proposal id is produced by hashing the ABI encoded `targets` array, the `values` array, the `calldatas` array * and the descriptionHash (bytes32 which itself is the keccak256 hash of the description string). This proposal id * can be produced from the proposal data which is part of the {ProposalCreated} event. It can even be computed in * advance, before the proposal is submitted. * * Note that the chainId and the governor address are not part of the proposal id computation. Consequently, the * same proposal (with same operation and same description) will have the same id if submitted on multiple governors * across multiple networks. This also means that in order to execute the same operation twice (on the same * governor) the proposer will have to change the description in order to avoid proposal id conflicts. */ function hashProposal( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public pure virtual override returns (uint256) { return uint256(keccak256(abi.encode(targets, values, calldatas, descriptionHash))); } /** * @dev See {IGovernor-state}. */ function state(uint256 proposalId) public view virtual override returns (ProposalState) { ProposalCore storage proposal = _proposals[proposalId]; if (proposal.executed) { return ProposalState.Executed; } if (proposal.canceled) { return ProposalState.Canceled; } uint256 snapshot = proposalSnapshot(proposalId); if (snapshot == 0) { revert("Governor: unknown proposal id"); } uint256 currentTimepoint = clock(); if (snapshot >= currentTimepoint) { return ProposalState.Pending; } uint256 deadline = proposalDeadline(proposalId); if (deadline >= currentTimepoint) { return ProposalState.Active; } if (_quorumReached(proposalId) && _voteSucceeded(proposalId)) { return ProposalState.Succeeded; } else { return ProposalState.Defeated; } } /** * @dev Part of the Governor Bravo's interface: _"The number of votes required in order for a voter to become a proposer"_. */ function proposalThreshold() public view virtual returns (uint256) { return 0; } /** * @dev See {IGovernor-proposalSnapshot}. */ function proposalSnapshot(uint256 proposalId) public view virtual override returns (uint256) { return _proposals[proposalId].voteStart; } /** * @dev See {IGovernor-proposalDeadline}. */ function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256) { return _proposals[proposalId].voteEnd; } /** * @dev Returns the account that created a given proposal. */ function proposalProposer(uint256 proposalId) public view virtual override returns (address) { return _proposals[proposalId].proposer; } /** * @dev Amount of votes already cast passes the threshold limit. */ function _quorumReached(uint256 proposalId) internal view virtual returns (bool); /** * @dev Is the proposal successful or not. */ function _voteSucceeded(uint256 proposalId) internal view virtual returns (bool); /** * @dev Get the voting weight of `account` at a specific `timepoint`, for a vote as described by `params`. */ function _getVotes(address account, uint256 timepoint, bytes memory params) internal view virtual returns (uint256); /** * @dev Register a vote for `proposalId` by `account` with a given `support`, voting `weight` and voting `params`. * * Note: Support is generic and can represent various things depending on the voting system used. */ function _countVote( uint256 proposalId, address account, uint8 support, uint256 weight, bytes memory params ) internal virtual; /** * @dev Default additional encoded parameters used by castVote methods that don't include them * * Note: Should be overridden by specific implementations to use an appropriate value, the * meaning of the additional params, in the context of that implementation */ function _defaultParams() internal view virtual returns (bytes memory) { return ""; } /** * @dev See {IGovernor-propose}. This function has opt-in frontrunning protection, described in {_isValidDescriptionForProposer}. */ function propose( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description ) public virtual override returns (uint256) { address proposer = _msgSender(); require(_isValidDescriptionForProposer(proposer, description), "Governor: proposer restricted"); uint256 currentTimepoint = clock(); require( getVotes(proposer, currentTimepoint - 1) >= proposalThreshold(), "Governor: proposer votes below proposal threshold" ); uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); require(targets.length == values.length, "Governor: invalid proposal length"); require(targets.length == calldatas.length, "Governor: invalid proposal length"); require(targets.length > 0, "Governor: empty proposal"); require(_proposals[proposalId].voteStart == 0, "Governor: proposal already exists"); uint256 snapshot = currentTimepoint + votingDelay(); uint256 deadline = snapshot + votingPeriod(); _proposals[proposalId] = ProposalCore({ proposer: proposer, voteStart: SafeCast.toUint64(snapshot), voteEnd: SafeCast.toUint64(deadline), executed: false, canceled: false, __gap_unused0: 0, __gap_unused1: 0 }); emit ProposalCreated( proposalId, proposer, targets, values, new string[](targets.length), calldatas, snapshot, deadline, description ); return proposalId; } /** * @dev See {IGovernor-execute}. */ function execute( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public payable virtual override returns (uint256) { uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); ProposalState currentState = state(proposalId); require( currentState == ProposalState.Succeeded || currentState == ProposalState.Queued, "Governor: proposal not successful" ); _proposals[proposalId].executed = true; emit ProposalExecuted(proposalId); _beforeExecute(proposalId, targets, values, calldatas, descriptionHash); _execute(proposalId, targets, values, calldatas, descriptionHash); _afterExecute(proposalId, targets, values, calldatas, descriptionHash); return proposalId; } /** * @dev See {IGovernor-cancel}. */ function cancel( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public virtual override returns (uint256) { uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); require(state(proposalId) == ProposalState.Pending, "Governor: too late to cancel"); require(_msgSender() == _proposals[proposalId].proposer, "Governor: only proposer can cancel"); return _cancel(targets, values, calldatas, descriptionHash); } /** * @dev Internal execution mechanism. Can be overridden to implement different execution mechanism */ function _execute( uint256 /* proposalId */, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 /*descriptionHash*/ ) internal virtual { string memory errorMessage = "Governor: call reverted without message"; for (uint256 i = 0; i < targets.length; ++i) { (bool success, bytes memory returndata) = targets[i].call{value: values[i]}(calldatas[i]); Address.verifyCallResult(success, returndata, errorMessage); } } /** * @dev Hook before execution is triggered. */ function _beforeExecute( uint256 /* proposalId */, address[] memory targets, uint256[] memory /* values */, bytes[] memory calldatas, bytes32 /*descriptionHash*/ ) internal virtual { if (_executor() != address(this)) { for (uint256 i = 0; i < targets.length; ++i) { if (targets[i] == address(this)) { _governanceCall.pushBack(keccak256(calldatas[i])); } } } } /** * @dev Hook after execution is triggered. */ function _afterExecute( uint256 /* proposalId */, address[] memory /* targets */, uint256[] memory /* values */, bytes[] memory /* calldatas */, bytes32 /*descriptionHash*/ ) internal virtual { if (_executor() != address(this)) { if (!_governanceCall.empty()) { _governanceCall.clear(); } } } /** * @dev Internal cancel mechanism: locks up the proposal timer, preventing it from being re-submitted. Marks it as * canceled to allow distinguishing it from executed proposals. * * Emits a {IGovernor-ProposalCanceled} event. */ function _cancel( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) internal virtual returns (uint256) { uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); ProposalState currentState = state(proposalId); require( currentState != ProposalState.Canceled && currentState != ProposalState.Expired && currentState != ProposalState.Executed, "Governor: proposal not active" ); _proposals[proposalId].canceled = true; emit ProposalCanceled(proposalId); return proposalId; } /** * @dev See {IGovernor-getVotes}. */ function getVotes(address account, uint256 timepoint) public view virtual override returns (uint256) { return _getVotes(account, timepoint, _defaultParams()); } /** * @dev See {IGovernor-getVotesWithParams}. */ function getVotesWithParams( address account, uint256 timepoint, bytes memory params ) public view virtual override returns (uint256) { return _getVotes(account, timepoint, params); } /** * @dev See {IGovernor-castVote}. */ function castVote(uint256 proposalId, uint8 support) public virtual override returns (uint256) { address voter = _msgSender(); return _castVote(proposalId, voter, support, ""); } /** * @dev See {IGovernor-castVoteWithReason}. */ function castVoteWithReason( uint256 proposalId, uint8 support, string calldata reason ) public virtual override returns (uint256) { address voter = _msgSender(); return _castVote(proposalId, voter, support, reason); } /** * @dev See {IGovernor-castVoteWithReasonAndParams}. */ function castVoteWithReasonAndParams( uint256 proposalId, uint8 support, string calldata reason, bytes memory params ) public virtual override returns (uint256) { address voter = _msgSender(); return _castVote(proposalId, voter, support, reason, params); } /** * @dev See {IGovernor-castVoteBySig}. */ function castVoteBySig( uint256 proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s ) public virtual override returns (uint256) { address voter = ECDSA.recover( _hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support))), v, r, s ); return _castVote(proposalId, voter, support, ""); } /** * @dev See {IGovernor-castVoteWithReasonAndParamsBySig}. */ function castVoteWithReasonAndParamsBySig( uint256 proposalId, uint8 support, string calldata reason, bytes memory params, uint8 v, bytes32 r, bytes32 s ) public virtual override returns (uint256) { address voter = ECDSA.recover( _hashTypedDataV4( keccak256( abi.encode( EXTENDED_BALLOT_TYPEHASH, proposalId, support, keccak256(bytes(reason)), keccak256(params) ) ) ), v, r, s ); return _castVote(proposalId, voter, support, reason, params); } /** * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function. Uses the _defaultParams(). * * Emits a {IGovernor-VoteCast} event. */ function _castVote( uint256 proposalId, address account, uint8 support, string memory reason ) internal virtual returns (uint256) { return _castVote(proposalId, account, support, reason, _defaultParams()); } /** * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function. * * Emits a {IGovernor-VoteCast} event. */ function _castVote( uint256 proposalId, address account, uint8 support, string memory reason, bytes memory params ) internal virtual returns (uint256) { ProposalCore storage proposal = _proposals[proposalId]; require(state(proposalId) == ProposalState.Active, "Governor: vote not currently active"); uint256 weight = _getVotes(account, proposal.voteStart, params); _countVote(proposalId, account, support, weight, params); if (params.length == 0) { emit VoteCast(account, proposalId, support, weight, reason); } else { emit VoteCastWithParams(account, proposalId, support, weight, reason, params); } return weight; } /** * @dev Relays a transaction or function call to an arbitrary target. In cases where the governance executor * is some contract other than the governor itself, like when using a timelock, this function can be invoked * in a governance proposal to recover tokens or Ether that was sent to the governor contract by mistake. * Note that if the executor is simply the governor itself, use of `relay` is redundant. */ function relay(address target, uint256 value, bytes calldata data) external payable virtual onlyGovernance { (bool success, bytes memory returndata) = target.call{value: value}(data); Address.verifyCallResult(success, returndata, "Governor: relay reverted without message"); } /** * @dev Address through which the governor executes action. Will be overloaded by module that execute actions * through another contract such as a timelock. */ function _executor() internal view virtual returns (address) { return address(this); } /** * @dev See {IERC721Receiver-onERC721Received}. */ function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) { return this.onERC721Received.selector; } /** * @dev See {IERC1155Receiver-onERC1155Received}. */ function onERC1155Received( address, address, uint256, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155Received.selector; } /** * @dev See {IERC1155Receiver-onERC1155BatchReceived}. */ function onERC1155BatchReceived( address, address, uint256[] memory, uint256[] memory, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155BatchReceived.selector; } /** * @dev Check if the proposer is authorized to submit a proposal with the given description. * * If the proposal description ends with `#proposer=0x???`, where `0x???` is an address written as a hex string * (case insensitive), then the submission of this proposal will only be authorized to said address. * * This is used for frontrunning protection. By adding this pattern at the end of their proposal, one can ensure * that no other address can submit the same proposal. An attacker would have to either remove or change that part, * which would result in a different proposal id. * * If the description does not match this pattern, it is unrestricted and anyone can submit it. This includes: * - If the `0x???` part is not a valid hex string. * - If the `0x???` part is a valid hex string, but does not contain exactly 40 hex digits. * - If it ends with the expected suffix followed by newlines or other whitespace. * - If it ends with some other similar suffix, e.g. `#other=abc`. * - If it does not end with any such suffix. */ function _isValidDescriptionForProposer( address proposer, string memory description ) internal view virtual returns (bool) { uint256 len = bytes(description).length; // Length is too short to contain a valid proposer suffix if (len < 52) { return true; } // Extract what would be the `#proposer=0x` marker beginning the suffix bytes12 marker; assembly { // - Start of the string contents in memory = description + 32 // - First character of the marker = len - 52 // - Length of "#proposer=0x0000000000000000000000000000000000000000" = 52 // - We read the memory word starting at the first character of the marker: // - (description + 32) + (len - 52) = description + (len - 20) // - Note: Solidity will ignore anything past the first 12 bytes marker := mload(add(description, sub(len, 20))) } // If the marker is not found, there is no proposer suffix to check if (marker != bytes12("#proposer=0x")) { return true; } // Parse the 40 characters following the marker as uint160 uint160 recovered = 0; for (uint256 i = len - 40; i < len; ++i) { (bool isHex, uint8 value) = _tryHexToUint(bytes(description)[i]); // If any of the characters is not a hex digit, ignore the suffix entirely if (!isHex) { return true; } recovered = (recovered << 4) | value; } return recovered == uint160(proposer); } /** * @dev Try to parse a character from a string as a hex value. Returns `(true, value)` if the char is in * `[0-9a-fA-F]` and `(false, 0)` otherwise. Value is guaranteed to be in the range `0 <= value < 16` */ function _tryHexToUint(bytes1 char) private pure returns (bool, uint8) { uint8 c = uint8(char); unchecked { // Case 0-9 if (47 < c && c < 58) { return (true, c - 48); } // Case A-F else if (64 < c && c < 71) { return (true, c - 55); } // Case a-f else if (96 < c && c < 103) { return (true, c - 87); } // Else: not a hex char else { return (false, 0); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (governance/compatibility/IGovernorCompatibilityBravo.sol) pragma solidity ^0.8.0; import "../IGovernor.sol"; /** * @dev Interface extension that adds missing functions to the {Governor} core to provide `GovernorBravo` compatibility. * * _Available since v4.3._ */ abstract contract IGovernorCompatibilityBravo is IGovernor { /** * @dev Proposal structure from Compound Governor Bravo. Not actually used by the compatibility layer, as * {{proposal}} returns a very different structure. */ struct Proposal { uint256 id; address proposer; uint256 eta; address[] targets; uint256[] values; string[] signatures; bytes[] calldatas; uint256 startBlock; uint256 endBlock; uint256 forVotes; uint256 againstVotes; uint256 abstainVotes; bool canceled; bool executed; mapping(address => Receipt) receipts; } /** * @dev Receipt structure from Compound Governor Bravo */ struct Receipt { bool hasVoted; uint8 support; uint96 votes; } /** * @dev Part of the Governor Bravo's interface. */ function quorumVotes() public view virtual returns (uint256); /** * @dev Part of the Governor Bravo's interface: _"The official record of all proposals ever proposed"_. */ function proposals( uint256 ) public view virtual returns ( uint256 id, address proposer, uint256 eta, uint256 startBlock, uint256 endBlock, uint256 forVotes, uint256 againstVotes, uint256 abstainVotes, bool canceled, bool executed ); /** * @dev Part of the Governor Bravo's interface: _"Function used to propose a new proposal"_. */ function propose( address[] memory targets, uint256[] memory values, string[] memory signatures, bytes[] memory calldatas, string memory description ) public virtual returns (uint256); /** * @dev Part of the Governor Bravo's interface: _"Queues a proposal of state succeeded"_. */ function queue(uint256 proposalId) public virtual; /** * @dev Part of the Governor Bravo's interface: _"Executes a queued proposal if eta has passed"_. */ function execute(uint256 proposalId) public payable virtual; /** * @dev Cancels a proposal only if the sender is the proposer or the proposer delegates' voting power dropped below the proposal threshold. */ function cancel(uint256 proposalId) public virtual; /** * @dev Part of the Governor Bravo's interface: _"Gets actions of a proposal"_. */ function getActions( uint256 proposalId ) public view virtual returns ( address[] memory targets, uint256[] memory values, string[] memory signatures, bytes[] memory calldatas ); /** * @dev Part of the Governor Bravo's interface: _"Gets the receipt for a voter on a given proposal"_. */ function getReceipt(uint256 proposalId, address voter) public view virtual returns (Receipt memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. 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: * ```solidity * 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`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } }
{ "remappings": [ "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", "@src/=src/", "@test/=test/", "@script-deploy/=script/deploy/", "@governance/=lib/frax-governance/", "@solmate/=lib/solmate/", "@chainlink/=lib/frax-governance/node_modules/@chainlink/", "@eth-optimism/=lib/frax-governance/node_modules/@eth-optimism/contracts/", "@gnosis.pm/=lib/frax-governance/node_modules/@gnosis.pm/", "ds-test/=lib/frax-governance/node_modules/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "frax-governance/=lib/frax-governance/", "frax-standard-solidity/=lib/frax-governance/node_modules/frax-standard-solidity/src/", "frax-std/=lib/frax-governance/node_modules/frax-standard-solidity/src/", "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "openzeppelin-solidity/=lib/frax-governance/node_modules/openzeppelin-solidity/contracts/", "openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/", "safe-contracts/=lib/frax-governance/node_modules/@gnosis.pm/safe-contracts/contracts/", "safe-tools/=lib/frax-governance/node_modules/safe-tools/src/", "solady/=lib/frax-governance/node_modules/solady/src/", "solmate/=lib/solmate/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "shanghai", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"veFxs","type":"address"},{"internalType":"address","name":"veFxsVotingDelegation","type":"address"},{"internalType":"address[]","name":"safeAllowlist","type":"address[]"},{"internalType":"address[]","name":"delegateCallAllowlist","type":"address[]"},{"internalType":"address payable","name":"timelockController","type":"address"},{"internalType":"uint256","name":"initialVotingDelay","type":"uint256"},{"internalType":"uint256","name":"initialVotingPeriod","type":"uint256"},{"internalType":"uint256","name":"initialProposalThreshold","type":"uint256"},{"internalType":"uint256","name":"quorumNumeratorValue","type":"uint256"},{"internalType":"uint256","name":"initialVotingDelayBlocks","type":"uint256"},{"internalType":"uint256","name":"initialShortCircuitNumerator","type":"uint256"}],"internalType":"struct ConstructorParams","name":"params","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"name":"AlreadyOnDelegateCallAllowlist","type":"error"},{"inputs":[{"internalType":"address","name":"safe","type":"address"}],"name":"AlreadyOnSafeAllowlist","type":"error"},{"inputs":[],"name":"BadBatchArgs","type":"error"},{"inputs":[],"name":"CannotCancelOptimisticTransaction","type":"error"},{"inputs":[],"name":"CannotPropose","type":"error"},{"inputs":[],"name":"CannotRelay","type":"error"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"DelegateCallNotAllowed","type":"error"},{"inputs":[],"name":"InvalidShortString","type":"error"},{"inputs":[],"name":"InvalidTimepoint","type":"error"},{"inputs":[],"name":"NonceReserved","type":"error"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"name":"NotOnDelegateCallAllowlist","type":"error"},{"inputs":[{"internalType":"address","name":"safe","type":"address"}],"name":"NotOnSafeAllowlist","type":"error"},{"inputs":[],"name":"NotTimelockController","type":"error"},{"inputs":[],"name":"ParamLengthsNotEqual","type":"error"},{"inputs":[],"name":"ProposalAlreadyCanceled","type":"error"},{"inputs":[],"name":"SameSafeVotingPeriod","type":"error"},{"inputs":[],"name":"SenderVotingWeightBelowProposalThreshold","type":"error"},{"inputs":[],"name":"ShortCircuitNumeratorGreaterThanQuorumDenominator","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","type":"error"},{"inputs":[{"internalType":"bytes32","name":"txHash","type":"bytes32"}],"name":"TransactionAlreadyApproved","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"WrongNonce","type":"error"},{"inputs":[],"name":"WrongProposalState","type":"error"},{"inputs":[],"name":"WrongSafeSignatureType","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"contractAddress","type":"address"}],"name":"AddToDelegateCallAllowlist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"safe","type":"address"}],"name":"AddToSafeAllowlist","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"ProposalCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"address","name":"proposer","type":"address"},{"indexed":false,"internalType":"address[]","name":"targets","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"},{"indexed":false,"internalType":"string[]","name":"signatures","type":"string[]"},{"indexed":false,"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"indexed":false,"internalType":"uint256","name":"voteStart","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"voteEnd","type":"uint256"},{"indexed":false,"internalType":"string","name":"description","type":"string"}],"name":"ProposalCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"ProposalExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldProposalThreshold","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newProposalThreshold","type":"uint256"}],"name":"ProposalThresholdSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldQuorumNumerator","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newQuorumNumerator","type":"uint256"}],"name":"QuorumNumeratorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"contractAddress","type":"address"}],"name":"RemoveFromDelegateCallAllowlist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"safe","type":"address"}],"name":"RemoveFromSafeAllowlist","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"safe","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldSafeVotingPeriod","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newSafeVotingPeriod","type":"uint256"}],"name":"SafeVotingPeriodSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldShortCircuitNumerator","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newShortCircuitNumerator","type":"uint256"}],"name":"ShortCircuitNumeratorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"safe","type":"address"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"txHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"TransactionProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldVotingDelegation","type":"address"},{"indexed":false,"internalType":"address","name":"newVotingDelegation","type":"address"}],"name":"VeFxsVotingDelegationSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"support","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"weight","type":"uint256"},{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"VoteCast","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"support","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"weight","type":"uint256"},{"indexed":false,"internalType":"string","name":"reason","type":"string"},{"indexed":false,"internalType":"bytes","name":"params","type":"bytes"}],"name":"VoteCastWithParams","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldVotingDelayBlocks","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newVotingDelayBlocks","type":"uint256"}],"name":"VotingDelayBlocksSet","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":[{"internalType":"address","name":"contractAddress","type":"address"}],"name":"$delegateCallAllowlist","outputs":[{"internalType":"uint256","name":"status","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"safe","type":"address"},{"internalType":"uint256","name":"safeNonce","type":"uint256"}],"name":"$gnosisSafeToNonceToTxHash","outputs":[{"internalType":"bytes32","name":"txHash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"safe","type":"address"}],"name":"$safeAllowlist","outputs":[{"internalType":"uint256","name":"status","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"safe","type":"address"}],"name":"$safeVotingPeriod","outputs":[{"internalType":"uint256","name":"votingPeriod","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"snapshot","type":"uint256"}],"name":"$snapshotTimestampToSnapshotBlockNumber","outputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"$votingDelayBlocks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BALLOT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CLOCK_MODE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"COUNTING_MODE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"EXTENDED_BALLOT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TIMELOCK_CONTROLLER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VE_FXS","outputs":[{"internalType":"contract IVeFxs","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"teamSafe","type":"address"},{"internalType":"bytes","name":"signatures","type":"bytes"}],"name":"abortTransaction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"contracts","type":"address[]"}],"name":"addToDelegateCallAllowlist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"safes","type":"address[]"}],"name":"addToSafeAllowlist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"teamSafe","type":"address"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"enum Enum.Operation","name":"operation","type":"uint8"},{"internalType":"uint256","name":"safeTxGas","type":"uint256"},{"internalType":"uint256","name":"baseGas","type":"uint256"},{"internalType":"uint256","name":"gasPrice","type":"uint256"},{"internalType":"address","name":"gasToken","type":"address"},{"internalType":"address","name":"refundReceiver","type":"address"},{"internalType":"uint256","name":"_nonce","type":"uint256"}],"internalType":"struct IFraxGovernorOmega.TxHashArgs","name":"args","type":"tuple"},{"internalType":"bytes","name":"signatures","type":"bytes"}],"name":"addTransaction","outputs":[{"internalType":"uint256","name":"optimisticProposalId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"teamSafes","type":"address[]"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"enum Enum.Operation","name":"operation","type":"uint8"},{"internalType":"uint256","name":"safeTxGas","type":"uint256"},{"internalType":"uint256","name":"baseGas","type":"uint256"},{"internalType":"uint256","name":"gasPrice","type":"uint256"},{"internalType":"address","name":"gasToken","type":"address"},{"internalType":"address","name":"refundReceiver","type":"address"},{"internalType":"uint256","name":"_nonce","type":"uint256"}],"internalType":"struct IFraxGovernorOmega.TxHashArgs[]","name":"args","type":"tuple[]"},{"internalType":"bytes[]","name":"signatures","type":"bytes[]"}],"name":"batchAddTransaction","outputs":[{"internalType":"uint256[]","name":"optimisticProposalIds","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"proposalId","type":"uint256[]"},{"internalType":"uint8[]","name":"support","type":"uint8[]"}],"name":"bulkCastVote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes[]","name":"","type":"bytes[]"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"cancel","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"}],"name":"castVote","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"string","name":"reason","type":"string"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"castVoteWithReasonAndParams","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"string","name":"reason","type":"string"},{"internalType":"bytes","name":"params","type":"bytes"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"castVoteWithReasonAndParamsBySig","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"clock","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"internalType":"bytes32","name":"descriptionHash","type":"bytes32"}],"name":"execute","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"fractionalVoteNonce","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"getVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"timepoint","type":"uint256"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"getVotesWithParams","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"name":"hasVoted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"internalType":"bytes32","name":"descriptionHash","type":"bytes32"}],"name":"hashProposal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"lastSnapshotTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalDeadline","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalProposer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalSnapshot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposalThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalVotes","outputs":[{"internalType":"uint256","name":"againstVotes","type":"uint256"},{"internalType":"uint256","name":"forVotes","type":"uint256"},{"internalType":"uint256","name":"abstainVotes","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proposals","outputs":[{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint40","name":"voteStart","type":"uint40"},{"internalType":"uint40","name":"voteEnd","type":"uint40"},{"internalType":"bool","name":"executed","type":"bool"},{"internalType":"bool","name":"canceled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes[]","name":"","type":"bytes[]"},{"internalType":"string","name":"","type":"string"}],"name":"propose","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"quorum","outputs":[{"internalType":"uint256","name":"quorumAtTimepoint","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quorumDenominator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"quorumNumerator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quorumNumerator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"teamSafe","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"rejectTransaction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"relay","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"contracts","type":"address[]"}],"name":"removeFromDelegateCallAllowlist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"safes","type":"address[]"}],"name":"removeFromSafeAllowlist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newProposalThreshold","type":"uint256"}],"name":"setProposalThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"safe","type":"address"},{"internalType":"uint256","name":"newSafeVotingPeriod","type":"uint256"}],"name":"setSafeVotingPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"veFxsVotingDelegation","type":"address"}],"name":"setVeFxsVotingDelegation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newVotingDelay","type":"uint256"}],"name":"setVotingDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newVotingDelayBlocks","type":"uint256"}],"name":"setVotingDelayBlocks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newVotingPeriod","type":"uint256"}],"name":"setVotingPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shortCircuitNumerator","outputs":[{"internalType":"uint256","name":"latestShortCircuitNumerator","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"shortCircuitNumerator","outputs":[{"internalType":"uint256","name":"shortCircuitNumeratorAtTimepoint","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"shortCircuitThreshold","outputs":[{"internalType":"uint256","name":"shortCircuitThresholdAtTimepoint","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"state","outputs":[{"internalType":"enum IGovernor.ProposalState","name":"proposalState","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC5805","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newQuorumNumerator","type":"uint256"}],"name":"updateQuorumNumerator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newShortCircuitNumerator","type":"uint256"}],"name":"updateShortCircuitNumerator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"name":"voteWeightCast","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6101a060405234801562000011575f80fd5b506040516200715b3803806200715b833981016040819052620000349162000e87565b60405180610120016040528082602001516001600160a01b0316815260200182604001516001600160a01b03168152602001825f015181526020018260c0015181526020018260e0015181526020018261010001518152602001826101200151815260200182610140015181526020018261016001518152508060c001518160200151826060015183608001518460a00151856040015180620000dc620002a560201b60201c565b620000e8825f620002c0565b61012052620000f9816001620002c0565b61014052815160208084019190912060e052815190820120610100524660a0526200018660e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b60805250503060c05260026200019d82826200104a565b50620001ab905083620002f8565b620001b68262000339565b620001c181620003df565b5050600980546001600160a01b0319166001600160a01b03939093169290921790915550620001f08162000420565b5080516001600160a01b031661016052610100810151620002119062000527565b60e08101516200022190620005b6565b602080820151604080515f81526001600160a01b03909216928201929092527fc255828f3e19c78de5df3dd5b6706d49bd5dd58e76275f97bd69987870099520910160405180910390a15060a08101516001600160a01b03166101805260608101516200028e90620005f5565b60808101516200029e906200073e565b50620011ea565b6040805180820190915260018152603160f81b602082015290565b5f602083511015620002df57620002d78362000894565b9050620002f2565b81620002ec84826200104a565b5060ff90505b92915050565b60065460408051918252602082018390527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a93910160405180910390a1600655565b5f81116200039e5760405162461bcd60e51b815260206004820152602760248201527f476f7665726e6f7253657474696e67733a20766f74696e6720706572696f6420604482015266746f6f206c6f7760c81b60648201526084015b60405180910390fd5b60075460408051918252602082018390527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e8828910160405180910390a1600755565b60085460408051918252602082018390527fccb45da8d5717e6c4544694297c4ba5cf151d455c9bb0ed4fc7a38411bc05461910160405180910390a1600855565b6064811115620004a55760405162461bcd60e51b815260206004820152604360248201527f476f7665726e6f72566f74657351756f72756d4672616374696f6e3a2071756f60448201527f72756d4e756d657261746f72206f7665722071756f72756d44656e6f6d696e616064820152623a37b960e91b608482015260a40162000395565b5f620004b0620008d6565b9050620004e7620004d2620004c4620008f1565b65ffffffffffff1662000973565b620004dd84620009dd565b600a919062000a47565b505060408051828152602081018490527f0553476bf02ef2726e8ce5ced78d63e26e602e4a2257b1f559418e24b463399791015b60405180910390a15050565b606481111562000549576040516271e29960e21b815260040160405180910390fd5b5f6200055462000a63565b90506200057d62000568620004c4620008f1565b6200057384620009dd565b600f919062000a47565b505060408051828152602081018490527fdd2b8b2d874e19a344cba53b9fb534ea748ef117ed4b75c67569a7948645419391016200051b565b600e80549082905560408051828152602081018490527fd3c1cdfd662fbb8e44190410d3a0d46855746182cb8d1e5e41bc84f5afecef4f91016200051b565b5f5b81518110156200073a5760125f83838151811062000619576200061962001112565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f205460010362000690578181815181106200065e576200065e62001112565b6020026020010151604051630b58d77560e41b81526004016200039591906001600160a01b0391909116815260200190565b600160125f848481518110620006aa57620006aa62001112565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2081905550818181518110620006ea57620006ea62001112565b60200260200101516001600160a01b03167f4149776fc93a7a68120df1638269488e1915cd17b09b0ab741e6bf768a38c46d60405160405180910390a262000732816200113a565b9050620005f7565b5050565b5f5b81518110156200073a5760135f83838151811062000762576200076262001112565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2054600103620007d957818181518110620007a757620007a762001112565b60200260200101516040516394369fd360e01b81526004016200039591906001600160a01b0391909116815260200190565b600160135f848481518110620007f357620007f362001112565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f20819055507ff48d3b938905d7162ca91551f61d4d458d43159e04847eb28ed7d94fbdb3bc2f82828151811062000854576200085462001112565b60200260200101516040516200087991906001600160a01b0391909116815260200190565b60405180910390a16200088c816200113a565b905062000740565b5f80829050601f81511115620008c1578260405163305a27a960e01b815260040162000395919062001155565b8051620008ce8262001189565b179392505050565b5f620008e3600a62000a6b565b6001600160e01b0316905090565b600954604080516324776b7d60e21b815290515f926001600160a01b0316916391ddadf49160048083019260209291908290030181865afa92505050801562000959575060408051601f3d908101601f191682019092526200095691810190620011ad565b60015b6200096e57620009694362000ab6565b905090565b919050565b5f63ffffffff821115620009d95760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b606482015260840162000395565b5090565b5f6001600160e01b03821115620009d95760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663234206269747360c81b606482015260840162000395565b5f8062000a5685858562000b1e565b915091505b935093915050565b5f620008e3600f5b80545f90801562000aad5762000a958362000a88600184620011d4565b5f91825260209091200190565b5464010000000090046001600160e01b031662000aaf565b5f5b9392505050565b5f65ffffffffffff821115620009d95760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203460448201526538206269747360d01b606482015260840162000395565b82545f908190801562000c70575f62000b3e8762000a88600185620011d4565b60408051808201909152905463ffffffff8082168084526401000000009092046001600160e01b03166020840152919250908716101562000bc25760405162461bcd60e51b815260206004820152601b60248201527f436865636b706f696e743a2064656372656173696e67206b6579730000000000604482015260640162000395565b805163ffffffff80881691160362000c10578462000be78862000a88600186620011d4565b80546001600160e01b03929092166401000000000263ffffffff90921691909117905562000c5f565b6040805180820190915263ffffffff80881682526001600160e01b0380881660208085019182528b54600181018d555f8d81529190912094519151909216640100000000029216919091179101555b60200151925083915062000a5b9050565b50506040805180820190915263ffffffff80851682526001600160e01b0380851660208085019182528854600181018a555f8a81529182209551925190931664010000000002919093161792019190915590508162000a5b565b634e487b7160e01b5f52604160045260245ffd5b60405161018081016001600160401b038111828210171562000d045762000d0462000cca565b60405290565b604051601f8201601f191681016001600160401b038111828210171562000d355762000d3562000cca565b604052919050565b5f5b8381101562000d5957818101518382015260200162000d3f565b50505f910152565b5f82601f83011262000d71575f80fd5b81516001600160401b0381111562000d8d5762000d8d62000cca565b62000da2601f8201601f191660200162000d0a565b81815284602083860101111562000db7575f80fd5b62000dca82602083016020870162000d3d565b949350505050565b6001600160a01b038116811462000de7575f80fd5b50565b80516200096e8162000dd2565b5f82601f83011262000e07575f80fd5b815160206001600160401b0382111562000e255762000e2562000cca565b8160051b62000e3682820162000d0a565b928352848101820192828101908785111562000e50575f80fd5b83870192505b8483101562000e7c57825162000e6c8162000dd2565b8252918301919083019062000e56565b979650505050505050565b5f6020828403121562000e98575f80fd5b81516001600160401b038082111562000eaf575f80fd5b90830190610180828603121562000ec4575f80fd5b62000ece62000cde565b82518281111562000edd575f80fd5b62000eeb8782860162000d61565b82525062000efc6020840162000dea565b602082015262000f0f6040840162000dea565b604082015260608301518281111562000f26575f80fd5b62000f348782860162000df7565b60608301525060808301518281111562000f4c575f80fd5b62000f5a8782860162000df7565b60808301525062000f6e60a0840162000dea565b60a082015260c0838101519082015260e080840151908201526101008084015190820152610120808401519082015261014080840151908201526101609283015192810192909252509392505050565b600181811c9082168062000fd357607f821691505b60208210810362000ff257634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111562001045575f81815260208120601f850160051c81016020861015620010205750805b601f850160051c820191505b8181101562001041578281556001016200102c565b5050505b505050565b81516001600160401b0381111562001066576200106662000cca565b6200107e8162001077845462000fbe565b8462000ff8565b602080601f831160018114620010b4575f84156200109c5750858301515b5f19600386901b1c1916600185901b17855562001041565b5f85815260208120601f198616915b82811015620010e457888601518255948401946001909101908401620010c3565b50858210156200110257878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f600182016200114e576200114e62001126565b5060010190565b602081525f82518060208401526200117581604085016020870162000d3d565b601f01601f19169190910160400192915050565b8051602080830151919081101562000ff2575f1960209190910360031b1b16919050565b5f60208284031215620011be575f80fd5b815165ffffffffffff8116811462000aaf575f80fd5b81810381811115620002f257620002f262001126565b60805160a05160c05160e0516101005161012051610140516101605161018051615ef6620012655f395f81816108f40152612a7301525f81816108200152818161269d01526137bb01525f6119e401525f6119ba01525f613f2101525f613ef901525f613e5401525f613e7e01525f613ea80152615ef65ff3fe6080604052600436106103f8575f3560e01c806384b0196e1161020a578063c28bc2fa1161011e578063e80f1aa7116100a8578063ece40cc111610078578063ece40cc114610dcb578063f23a6e6114610dea578063f8cc2e3c14610e15578063f8ce560a14610e34578063fc0c546a14610e53575f80fd5b8063e80f1aa714610d4f578063ea0217cf14610d6e578063eb9019d414610d8d578063ec2de58b14610dac575f80fd5b8063d914e172116100ee578063d914e17214610c8a578063dd4e2ba514610cb5578063deaaa7cc14610cc9578063df482caf14610cfc578063dfc3c9e714610d30575f80fd5b8063c28bc2fa14610c25578063c3dcf92214610c38578063c59057e414610c57578063ccb8370b14610c76575f80fd5b8063aa75a3c21161019f578063bc197c811161016f578063bc197c8114610b57578063be13109414610b82578063be74baf214610ba1578063c01f9e3714610bb6578063c1de4eed14610bef575f80fd5b8063aa75a3c214610ae6578063b021d2c314610b05578063b12c327714610b24578063b58131b014610b43575f80fd5b806397c3d334116101da57806397c3d33414610a8b5780639a802a6d14610a9e578063a7713a7014610abd578063a89f263814610ad1575f80fd5b806384b0196e146109ef57806386e80e9014610a165780638bb53cd314610a4157806391ddadf414610a60575f80fd5b8063438596321161030c5780635c0855891161029657806364cda3d41161026657806364cda3d41461095457806370b0f6601461097357806377d76602146109925780637b3c71d3146109b15780637d5e81e2146109d0575f80fd5b80635c085589146108c45780635d049c0a146108e35780635f398a141461091657806360c4247f14610935575f80fd5b80634bf5d7e9116102dc5780634bf5d7e9146107fb578063506d1f811461080f578063544ffc9c1461084257806354fd4d501461087c57806356781388146108a5575f80fd5b8063438596321461074657806343ec3e0914610792578063452115d6146107b15780634571969b146107d0575f80fd5b8063150b7a021161038d5780632fe3e2611161035d5780632fe3e2611461067d578063342cfab6146106b05780633932abb1146106e75780633bccf4fd146106fb5780633e4f49e61461071a575f80fd5b8063150b7a02146105dd5780632214a33f146106205780632656227d1461064b5780632d63f6931461065e575f80fd5b806306f3f9e6116103c857806306f3f9e61461052557806306fdde0314610544578063072c8e0d14610565578063143489d014610591575f80fd5b8063013cf08b1461040e57806301ffc9a7146104b957806302a251a3146104e85780630342018114610506575f80fd5b3661040a57005b60405180910390fd5b005b5f80fd5b348015610419575f80fd5b50610473610428366004614b1f565b60036020525f90815260409020546001600160a01b0381169064ffffffffff600160a01b8204811691600160c81b81049091169060ff600160f01b8204811691600160f81b90041685565b604080516001600160a01b03909616865264ffffffffff9485166020870152939092169284019290925290151560608301521515608082015260a0015b60405180910390f35b3480156104c4575f80fd5b506104d86104d3366004614b36565b610e72565b60405190151581526020016104b0565b3480156104f3575f80fd5b506007545b6040519081526020016104b0565b348015610511575f80fd5b506104f8610520366004614c9d565b610f0e565b348015610530575f80fd5b5061040861053f366004614b1f565b610f2c565b34801561054f575f80fd5b50610558610f40565b6040516104b09190614d89565b348015610570575f80fd5b5061058461057f366004614ddb565b610fd0565b6040516104b09190614ea6565b34801561059c575f80fd5b506105c56105ab366004614b1f565b5f908152600360205260409020546001600160a01b031690565b6040516001600160a01b0390911681526020016104b0565b3480156105e8575f80fd5b506106076105f7366004614ece565b630a85bd0160e11b949350505050565b6040516001600160e01b031990911681526020016104b0565b34801561062b575f80fd5b506104f861063a366004614f31565b60146020525f908152604090205481565b6104f861065936600461509e565b6110f7565b348015610669575f80fd5b506104f8610678366004614b1f565b611223565b348015610688575f80fd5b506104f87fb3b3f3b703cd84ce352197dcff232b1b5d3cfb2025ce47cf04742d0651f1af8881565b3480156106bb575f80fd5b506106cf6106ca366004615127565b611242565b6040516001600160801b0390911681526020016104b0565b3480156106f2575f80fd5b506006546104f8565b348015610706575f80fd5b506104f8610715366004615151565b611274565b348015610725575f80fd5b50610739610734366004614b1f565b611307565b6040516104b091906151af565b348015610751575f80fd5b506104d8610760366004615127565b5f918252600c602090815260408084206001600160a01b039390931684529190529020546001600160801b0316151590565b34801561079d575f80fd5b506104086107ac366004614b1f565b611478565b3480156107bc575f80fd5b506104f86107cb36600461509e565b611489565b3480156107db575f80fd5b506104f86107ea366004614f31565b60126020525f908152604090205481565b348015610806575f80fd5b506105586114a6565b34801561081a575f80fd5b506105c57f000000000000000000000000000000000000000000000000000000000000000081565b34801561084d575f80fd5b5061086161085c366004614b1f565b611550565b604080519384526020840192909252908201526060016104b0565b348015610887575f80fd5b506040805180820190915260018152603160f81b6020820152610558565b3480156108b0575f80fd5b506104f86108bf3660046151c9565b611581565b3480156108cf575f80fd5b506104086108de3660046151ea565b6115a8565b3480156108ee575f80fd5b506105c57f000000000000000000000000000000000000000000000000000000000000000081565b348015610921575f80fd5b506104f8610930366004615212565b6117bf565b348015610940575f80fd5b506104f861094f366004614b1f565b611807565b34801561095f575f80fd5b5061040861096e366004614b1f565b6118a4565b34801561097e575f80fd5b5061040861098d366004614b1f565b6118b5565b34801561099d575f80fd5b506104086109ac36600461528f565b6118c6565b3480156109bc575f80fd5b506104f86109cb3660046152f5565b61194d565b3480156109db575f80fd5b506104f86109ea36600461533e565b611993565b3480156109fa575f80fd5b50610a036119ad565b6040516104b097969594939291906153ea565b348015610a21575f80fd5b506104f8610a30366004614f31565b60136020525f908152604090205481565b348015610a4c575f80fd5b50610408610a5b36600461544b565b611a33565b348015610a6b575f80fd5b50610a74611ba5565b60405165ffffffffffff90911681526020016104b0565b348015610a96575f80fd5b5060646104f8565b348015610aa9575f80fd5b506104f8610ab8366004615489565b611c1c565b348015610ac8575f80fd5b506104f8611c32565b348015610adc575f80fd5b506104f8600e5481565b348015610af1575f80fd5b50610408610b00366004614f31565b611c4b565b348015610b10575f80fd5b506104f8610b1f3660046154db565b611c5c565b348015610b2f575f80fd5b50610408610b3e366004615548565b611fb6565b348015610b4e575f80fd5b506104f861231d565b348015610b62575f80fd5b50610607610b71366004615596565b63bc197c8160e01b95945050505050565b348015610b8d575f80fd5b50610408610b9c36600461544b565b612327565b348015610bac575f80fd5b506104f860115481565b348015610bc1575f80fd5b506104f8610bd0366004614b1f565b5f90815260036020526040902054600160c81b900464ffffffffff1690565b348015610bfa575f80fd5b506104f8610c093660046151ea565b601560209081525f928352604080842090915290825290205481565b610408610c3336600461561e565b61236e565b348015610c43575f80fd5b50610408610c5236600461544b565b612387565b348015610c62575f80fd5b506104f8610c7136600461509e565b6124ed565b348015610c81575f80fd5b506104f8612526565b348015610c95575f80fd5b506104f8610ca4366004614b1f565b60106020525f908152604090205481565b348015610cc0575f80fd5b50610558612531565b348015610cd4575f80fd5b506104f87f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f81565b348015610d07575f80fd5b506106cf610d16366004614f31565b600d6020525f90815260409020546001600160801b031681565b348015610d3b575f80fd5b506104f8610d4a366004614b1f565b612551565b348015610d5a575f80fd5b50610408610d6936600461544b565b6125dd565b348015610d79575f80fd5b50610408610d88366004614b1f565b612620565b348015610d98575f80fd5b506104f8610da73660046151ea565b612631565b348015610db7575f80fd5b506104f8610dc6366004614b1f565b612650565b348015610dd6575f80fd5b50610408610de5366004614b1f565b612722565b348015610df5575f80fd5b50610607610e0436600461565b565b63f23a6e6160e01b95945050505050565b348015610e20575f80fd5b50610408610e2f3660046151ea565b612733565b348015610e3f575f80fd5b506104f8610e4e366004614b1f565b6127d2565b348015610e5e575f80fd5b506009546105c5906001600160a01b031681565b5f63288ace0360e11b6318df743f60e31b63bf26d89760e01b6379dd796f60e01b6001600160e01b03198616821480610eb757506001600160e01b0319868116908216145b80610ece57506001600160e01b0319868116908516145b80610ee957506001600160e01b03198616630271189760e51b145b80610f0457506301ffc9a760e01b6001600160e01b03198716145b9695505050505050565b5f610f1f8989898989898989612809565b9998505050505050505050565b610f34612a68565b610f3d81612ab3565b50565b606060028054610f4f906156ba565b80601f0160208091040260200160405190810160405280929190818152602001828054610f7b906156ba565b8015610fc65780601f10610f9d57610100808354040283529160200191610fc6565b820191905f5260205f20905b815481529060010190602001808311610fa957829003601f168201915b5050505050905090565b60608584141580610fe15750858214155b15610fff57604051630a1eb2d160e11b815260040160405180910390fd5b856001600160401b0381111561101757611017614bb1565b604051908082528060200260200182016040528015611040578160200160208202803683370190505b5090505f5b868110156110ec576110bf888883818110611062576110626156f2565b90506020020160208101906110779190614f31565b878784818110611089576110896156f2565b905060200281019061109b9190615706565b8686858181106110ad576110ad6156f2565b9050602002810190610b1f9190615725565b8282815181106110d1576110d16156f2565b60209081029190910101526110e58161577b565b9050611045565b509695505050505050565b5f80611105868686866124ed565b90505f61111182611307565b905060048160078111156111275761112761519b565b1480611144575060058160078111156111425761114261519b565b145b61119a5760405162461bcd60e51b815260206004820152602160248201527f476f7665726e6f723a2070726f706f73616c206e6f74207375636365737366756044820152601b60fa1b60648201526084016103ff565b5f8281526003602052604090819020805460ff60f01b1916600160f01b179055517f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f906111ea9084815260200190565b60405180910390a16111ff8288888888612bae565b61120c8288888888612c39565b6112198288888888612bae565b5095945050505050565b5f90815260036020526040902054600160a01b900464ffffffffff1690565b5f828152600c602090815260408083206001600160a01b03851684529091529020546001600160801b03165b92915050565b604080517f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f602082015290810186905260ff851660608201525f9081906112e0906112d8906080015b60405160208183030381529060405280519060200120612d32565b868686612d5e565b90506112fc87828860405180602001604052805f815250612d7a565b979650505050505050565b5f8181526003602052604081208054600160f01b900460ff161561132e5750600792915050565b8054600160f81b900460ff16156113485750600292915050565b5f61135284611223565b9050805f036113a35760405162461bcd60e51b815260206004820152601d60248201527f476f7665726e6f723a20756e6b6e6f776e2070726f706f73616c20696400000060448201526064016103ff565b5f6113ac611ba5565b65ffffffffffff16905080821015806113d257505f828152601060205260409020544311155b156113e157505f949350505050565b6113ea85612da4565b156113fa57506004949350505050565b61140385612dd2565b1561141357506003949350505050565b5f85815260036020526040902054600160c81b900464ffffffffff168181106114425750600195945050505050565b61144b86612deb565b801561145b575061145b86612e3c565b1561146c5750600395945050505050565b50600495945050505050565b611480612a68565b610f3d81612e70565b5f60405160016205739760e41b0319815260040160405180910390fd5b60095460408051634bf5d7e960e01b815290516060926001600160a01b031691634bf5d7e9916004808301925f9291908290030181865afa92505050801561150f57506040513d5f823e601f3d908101601f1916820160405261150c9190810190615793565b60015b61154b575060408051808201909152601d81527f6d6f64653d626c6f636b6e756d6265722666726f6d3d64656661756c74000000602082015290565b919050565b5f908152600b6020526040902080546001909101546001600160801b0380831693600160801b909304811692911690565b5f803390506115a084828560405180602001604052805f815250612d7a565b949350505050565b6001600160a01b0382165f9081526015602090815260408083208484529091528120549080806115d88685612ef4565b91945092509050600360408051602081019091525f905261161e6107348585857fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706124ed565b600781111561162f5761162f61519b565b1461164d57604051630fd1155b60e41b815260040160405180910390fd5b5f8690505f6116cc826040518061014001604052808b6001600160a01b031681526020015f815260200160405180602001604052805f81525081526020015f600181111561169d5761169d61519b565b81525f6020820181905260408201819052606082018190526080820181905260a082015260c0018a9052613016565b604051631f60ca5d60e21b8152306004820152602481018290529091506001600160a01b03831690637d832974906044016020604051808303815f875af1158015611719573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061173d91906157fb565b60010361176057604051635c0abc6d60e11b8152600481018290526024016103ff565b60405163d4d9bdcd60e01b8152600481018290526001600160a01b0383169063d4d9bdcd906024015f604051808303815f87803b15801561179f575f80fd5b505af11580156117b1573d5f803e3d5ffd5b505050505050505050505050565b5f803390506112fc87828888888080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508a92506130bd915050565b600a80545f91829061181a600184615812565b8154811061182a5761182a6156f2565b5f9182526020918290206040805180820190915291015463ffffffff8116808352600160201b9091046001600160e01b0316928201929092529150841061187f57602001516001600160e01b03169392505050565b61189361188b85613214565b600a9061327c565b6001600160e01b0316949350505050565b6118ac612a68565b610f3d81613329565b6118bd612a68565b610f3d81613367565b828181146118e75760405163a669fc0560e01b815260040160405180910390fd5b5f5b8181101561194557611934868683818110611906576119066156f2565b9050602002013585858481811061191f5761191f6156f2565b90506020020160208101906108bf9190615825565b5061193e8161577b565b90506118e9565b505050505050565b5f80339050610f0486828787878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250612d7a92505050565b5f60405163098bb82f60e01b815260040160405180910390fd5b5f606080828080836119df7f0000000000000000000000000000000000000000000000000000000000000000836133a8565b611a0a7f000000000000000000000000000000000000000000000000000000000000000060016133a8565b604080515f80825260208201909252600f60f81b9b939a50919850469750309650945092509050565b611a3b612a68565b5f5b81811015611ba05760135f848484818110611a5a57611a5a6156f2565b9050602002016020810190611a6f9190614f31565b6001600160a01b03166001600160a01b031681526020019081526020015f20545f03611ae157828282818110611aa757611aa76156f2565b9050602002016020810190611abc9190614f31565b604051630ee1e0b360e41b81526001600160a01b0390911660048201526024016103ff565b60135f848484818110611af657611af66156f2565b9050602002016020810190611b0b9190614f31565b6001600160a01b03166001600160a01b031681526020019081526020015f205f90557f3f75b27f9b6f643d57ab0006da862b383ffc26813fc08462f2d56270aaa950c0838383818110611b6057611b606156f2565b9050602002016020810190611b759190614f31565b6040516001600160a01b03909116815260200160405180910390a1611b998161577b565b9050611a3d565b505050565b600954604080516324776b7d60e21b815290515f926001600160a01b0316916391ddadf49160048083019260209291908290030181865afa925050508015611c0a575060408051601f3d908101601f19168201909252611c079181019061583e565b60015b61154b57611c1743613451565b905090565b5f611c288484846134b7565b90505b9392505050565b5f611c3d600a61352a565b6001600160e01b0316905090565b611c53612a68565b610f3d81613561565b5f611c66856135bb565b6001611c786080860160608701615871565b6001811115611c8957611c8961519b565b148015611cc6575060135f611ca16020870187614f31565b6001600160a01b03166001600160a01b031681526020019081526020015f2054600114155b15611cfd57611cd86020850185614f31565b6040516317645e7d60e21b81526001600160a01b0390911660048201526024016103ff565b5f8590505f816001600160a01b031663e75235b86040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d3e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d6291906157fb565b9050611da485858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508592506135f1915050565b6001600160a01b0387165f9081526015602090815260408083206101208a0135845290915290205415611dea57604051639e01d15b60e01b815260040160405180910390fd5b816001600160a01b031663affed0e06040518163ffffffff1660e01b81526004016020604051808303815f875af1158015611e27573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e4b91906157fb565b8661012001351015611e705760405163d9c6386f60e01b815260040160405180910390fd5b5f611e8383611e7e8961588a565b613016565b90506001600160a01b0383166312fb68e082611ea260408b018b615725565b8a8a886040518763ffffffff1660e01b8152600401611ec69695949392919061596e565b5f6040518083038186803b158015611edc575f80fd5b505afa158015611eee573d5f803e3d5ffd5b505050505f805f611eff8b85612ef4565b925092509250611f2083838360405180602001604052805f8152508f613658565b96508360155f8d6001600160a01b03166001600160a01b031681526020019081526020015f205f8c610120013581526020019081526020015f208190555086848c6001600160a01b03167f5ed3fb2763971f1f5e3d1e6f215e92ebe28160b512c2da07f4b12a46021adb0b8d6101200135604051611fa091815260200190565b60405180910390a4505050505050949350505050565b611fbf836135bb565b5f8390505f816001600160a01b031663e75235b86040518163ffffffff1660e01b8152600401602060405180830381865afa158015612000573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061202491906157fb565b905061206684848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508592506135f1915050565b5f826001600160a01b031663affed0e06040518163ffffffff1660e01b81526004016020604051808303815f875af11580156120a4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120c891906157fb565b90505f836001600160a01b031663d8d11f78885f805f805f805f8b6040518a63ffffffff1660e01b8152600401612107999897969594939291906159c2565b602060405180830381865afa158015612122573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061214691906157fb565b6040516297db4760e51b81529091506001600160a01b038516906312fb68e09061217a9084908a908a908990600401615a31565b5f6040518083038186803b158015612190575f80fd5b505afa1580156121a2573d5f803e3d5ffd5b5050506001600160a01b0388165f908152601560209081526040808320868452909152812054915081156122bd575f805f6121dd8c86612ef4565b60408051602081019091525f90529194509250905061221e8383837fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706124ed565b93505f61222a85611307565b905060028160078111156122405761224061519b565b0361225e576040516303ff04cd60e51b815260040160405180910390fd5b5f858152600360205260409081902080546001600160f81b0316600160f81b179055517f789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c906122b09087815260200190565b60405180910390a1505050505b60405163d4d9bdcd60e01b8152600481018490526001600160a01b0387169063d4d9bdcd906024015f604051808303815f87803b1580156122fc575f80fd5b505af115801561230e573d5f803e3d5ffd5b50505050505050505050505050565b5f611c1760085490565b61232f612a68565b61236a8282808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250613a1b92505050565b5050565b604051635adddc5560e01b815260040160405180910390fd5b61238f612a68565b5f5b81811015611ba05760125f8484848181106123ae576123ae6156f2565b90506020020160208101906123c39190614f31565b6001600160a01b03166001600160a01b031681526020019081526020015f20545f03612435578282828181106123fb576123fb6156f2565b90506020020160208101906124109190614f31565b60405163138c2add60e01b81526001600160a01b0390911660048201526024016103ff565b60125f84848481811061244a5761244a6156f2565b905060200201602081019061245f9190614f31565b6001600160a01b03166001600160a01b031681526020019081526020015f205f9055828282818110612493576124936156f2565b90506020020160208101906124a89190614f31565b6001600160a01b03167fe710dd5e6adb3eb2ba468162b8ead4d66e26d337074a5067caab50b676925ab860405160405180910390a26124e68161577b565b9050612391565b5f848484846040516020016125059493929190615af2565b60408051601f19818403018152919052805160209091012095945050505050565b5f611c3d600f61352a565b6060604051806080016040528060498152602001615e7860499139905090565b600f80545f918290612564600184615812565b81548110612574576125746156f2565b5f9182526020918290206040805180820190915291015463ffffffff8116808352600160201b9091046001600160e01b031692820192909252915084106125c957602001516001600160e01b03169392505050565b6118936125d585613214565b600f9061327c565b6125e5612a68565b61236a8282808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250613b5e92505050565b612628612a68565b610f3d81613c91565b5f611c2b838361264b60408051602081019091525f815290565b6134b7565b5f81158061265e5750428210155b1561267c5760405163749c2c6d60e01b815260040160405180910390fd5b606461268783612551565b604051630981b24d60e41b8152600481018590527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063981b24d090602401602060405180830381865afa1580156126ea573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061270e91906157fb565b6127189190615b3c565b61126e9190615b67565b61272a612a68565b610f3d81613d31565b61273b612a68565b6001600160a01b0382165f9081526014602052604090205481810361277357604051631a73bda360e11b815260040160405180910390fd5b6001600160a01b0383165f818152601460209081526040918290208590558151928352820183905281018390527fad48c7f5802308fb2675c0f699237e1a6d39e5170f647470b1d8ed2803262e599060600160405180910390a1505050565b5f8115806127e05750428210155b156127fe5760405163749c2c6d60e01b815260040160405180910390fd5b606461268783611807565b5f84516040148061281957508451155b6128975760405162461bcd60e51b815260206004820152604360248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a20696e766160448201527f6c696420706172616d7320666f72207369676e61747572652d626173656420766064820152626f746560e81b608482015260a4016103ff565b5f6129166112d87fb3b3f3b703cd84ce352197dcff232b1b5d3cfb2025ce47cf04742d0651f1af888c8c8c8c6040516128d1929190615b86565b60405180910390208b805190602001206040516020016112bd959493929190948552602085019390935260ff9190911660408401526060830152608082015260a00190565b90508551604003612a17576040868101516001600160a01b0383165f908152600d60205291909120546001600160801b03918216911681146129c05760405162461bcd60e51b815260206004820152603b60248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a207369676e60448201527f61747572652068617320616c7265616479206265656e2075736564000000000060648201526084016103ff565b6001600160a01b0382165f908152600d6020526040812080546001600160801b0316916129ec83615b95565b91906101000a8154816001600160801b0302191690836001600160801b031602179055505060308752505b612a5a8a828b8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508d92506130bd915050565b9a9950505050505050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614612ab1576040516362c4ffa560e11b815260040160405180910390fd5b565b6064811115612b365760405162461bcd60e51b815260206004820152604360248201527f476f7665726e6f72566f74657351756f72756d4672616374696f6e3a2071756f60448201527f72756d4e756d657261746f72206f7665722071756f72756d44656e6f6d696e616064820152623a37b960e91b608482015260a4016103ff565b5f612b3f611c32565b9050612b6e612b5c612b4f611ba5565b65ffffffffffff16613214565b612b6584613d72565b600a9190613dda565b505060408051828152602081018490527f0553476bf02ef2726e8ce5ced78d63e26e602e4a2257b1f559418e24b463399791015b60405180910390a15050565b612c32565b845181101561194557306001600160a01b0316858281518110612bd857612bd86156f2565b60200260200101516001600160a01b031603612c2257612c22838281518110612c0357612c036156f2565b6020026020010151805190602001206004613df490919063ffffffff16565b612c2b8161577b565b9050612bb3565b5050505050565b5f604051806060016040528060278152602001615e516027913990505f5b8551811015612d29575f80878381518110612c7457612c746156f2565b60200260200101516001600160a01b0316878481518110612c9757612c976156f2565b6020026020010151878581518110612cb157612cb16156f2565b6020026020010151604051612cc69190615bba565b5f6040518083038185875af1925050503d805f8114612d00576040519150601f19603f3d011682016040523d82523d5f602084013e612d05565b606091505b5091509150612d15828286613e2f565b50505080612d229061577b565b9050612c57565b50505050505050565b5f61126e612d3e613e48565b8360405161190160f01b8152600281019290925260228201526042902090565b5f805f612d6d87878787613f71565b915091506112198161402e565b5f612d9b85858585612d9660408051602081019091525f815290565b6130bd565b95945050505050565b5f80612daf83611550565b509150505f612dbd84611223565b9050612dc881612650565b9091119392505050565b5f80612ddd83611550565b505090505f612dbd84611223565b5f805f80612df885611550565b9250925092505f828411612e0c5782612e0e565b835b90505f612e1a87611223565b9050612e268383615bcb565b612e2f826127d2565b1115979650505050505050565b5f805f612e4884611550565b5091509150815f148015612e5a575080155b15612e6857505f9392505050565b111592915050565b6064811115612e91576040516271e29960e21b815260040160405180910390fd5b5f612e9a612526565b9050612ebc612eaa612b4f611ba5565b612eb384613d72565b600f9190613dda565b505060408051828152602081018490527fdd2b8b2d874e19a344cba53b9fb534ea748ef117ed4b75c67569a794864541939101612ba2565b6040805160018082528183019092526060918291829160208083019080368337505060408051600180825281830190925292955090506020808301908036833701905050604080516001808252818301909252919350816020015b6060815260200190600190039081612f4f57905050905084835f81518110612f7957612f796156f2565b60200260200101906001600160a01b031690816001600160a01b0316815250505f825f81518110612fac57612fac6156f2565b60209081029190910181019190915260408051602480820188905282518083039091018152604490910190915290810180516001600160e01b031663d4d9bdcd60e01b179052815182905f90613004576130046156f2565b60200260200101819052509250925092565b5f826001600160a01b031663d8d11f78835f015184602001518560400151866060015187608001518860a001518960c001518a60e001518b61010001518c61012001516040518b63ffffffff1660e01b815260040161307e9a99989796959493929190615bde565b602060405180830381865afa158015613099573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c2b91906157fb565b5f85815260036020526040812060016130d588611307565b60078111156130e6576130e661519b565b1461313f5760405162461bcd60e51b815260206004820152602360248201527f476f7665726e6f723a20766f7465206e6f742063757272656e746c792061637460448201526269766560e81b60648201526084016103ff565b80545f9061315d908890600160a01b900464ffffffffff16866134b7565b905061316c8888888488614177565b83515f036131c057866001600160a01b03167fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda4898884896040516131b39493929190615c53565b60405180910390a26112fc565b866001600160a01b03167fe2babfbac5889a709b63bb7f598b324e08bc5a4fb9ec647fb3cbc9ec07eb87128988848989604051613201959493929190615c7a565b60405180910390a2979650505050505050565b5f63ffffffff8211156132785760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b60648201526084016103ff565b5090565b81545f90818160058111156132d6575f61329584614292565b61329f9085615812565b5f8881526020902090915081015463ffffffff90811690871610156132c6578091506132d4565b6132d1816001615bcb565b92505b505b5f6132e387878585614376565b9050801561331d57613307876132fa600184615812565b5f91825260209091200190565b54600160201b90046001600160e01b03166112fc565b5f979650505050505050565b600e80549082905560408051828152602081018490527fd3c1cdfd662fbb8e44190410d3a0d46855746182cb8d1e5e41bc84f5afecef4f9101612ba2565b60065460408051918252602082018390527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a93910160405180910390a1600655565b606060ff83146133c2576133bb836143d1565b905061126e565b8180546133ce906156ba565b80601f01602080910402602001604051908101604052809291908181526020018280546133fa906156ba565b80156134455780601f1061341c57610100808354040283529160200191613445565b820191905f5260205f20905b81548152906001019060200180831161342857829003601f168201915b5050505050905061126e565b5f65ffffffffffff8211156132785760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203460448201526538206269747360d01b60648201526084016103ff565b600954604051630748d63560e31b81526001600160a01b038581166004830152602482018590525f921690633a46b1a890604401602060405180830381865afa158015613506573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c2891906157fb565b80545f90801561355957613543836132fa600184615812565b54600160201b90046001600160e01b0316611c2b565b5f9392505050565b600980546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527fc255828f3e19c78de5df3dd5b6706d49bd5dd58e76275f97bd699878700995209101612ba2565b6001600160a01b0381165f908152601260205260408120549003610f3d576040516282b42960e81b815260040160405180910390fd5b5f805f5b83811015612c325760418082028601602081015191015160ff169350915060018390036136485781306001600160a01b03821603613646576040516308fbb1df60e31b815260040160405180910390fd5b505b6136518161577b565b90506135f5565b5f61366c86868686805190602001206124ed565b9050845186511461368f5760405162461bcd60e51b81526004016103ff90615cbf565b83518651146136b05760405162461bcd60e51b81526004016103ff90615cbf565b5f8651116137005760405162461bcd60e51b815260206004820152601860248201527f476f7665726e6f723a20656d7074792070726f706f73616c000000000000000060448201526064016103ff565b5f81815260036020526040902054600160a01b900464ffffffffff16156137735760405162461bcd60e51b815260206004820152602160248201527f476f7665726e6f723a2070726f706f73616c20616c72656164792065786973746044820152607360f81b60648201526084016103ff565b335f61377e60065490565b613786611ba5565b65ffffffffffff166137989190615bcb565b6040516396d6d2fb60e01b8152600481018290529091505f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906396d6d2fb906024015f604051808303815f87803b1580156137fc575f80fd5b505af192505050801561380d575060015b5060118290556001600160a01b0385165f908152601460205260408120549081810361383b5760075461383d565b815b90506138498185615bcb565b925050506040518060a00160405280846001600160a01b031681526020018364ffffffffff1681526020018264ffffffffff1681526020015f151581526020015f151581525060035f8681526020019081526020015f205f820151815f015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151815f0160146101000a81548164ffffffffff021916908364ffffffffff1602179055506040820151815f0160196101000a81548164ffffffffff021916908364ffffffffff1602179055506060820151815f01601e6101000a81548160ff0219169083151502179055506080820151815f01601f6101000a81548160ff021916908315150217905550905050600e54436139699190615bcb565b5f8381526010602052604090205588517f7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e090859085908c908c906001600160401b038111156139ba576139ba614bb1565b6040519080825280602002602001820160405280156139ed57816020015b60608152602001906001900390816139d85790505b508c88888e604051613a0799989796959493929190615d00565b60405180910390a150505095945050505050565b5f5b815181101561236a5760135f838381518110613a3b57613a3b6156f2565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2054600103613aad57818181518110613a7c57613a7c6156f2565b60200260200101516040516394369fd360e01b81526004016103ff91906001600160a01b0391909116815260200190565b600160135f848481518110613ac457613ac46156f2565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f20819055507ff48d3b938905d7162ca91551f61d4d458d43159e04847eb28ed7d94fbdb3bc2f828281518110613b2257613b226156f2565b6020026020010151604051613b4691906001600160a01b0391909116815260200190565b60405180910390a1613b578161577b565b9050613a1d565b5f5b815181101561236a5760125f838381518110613b7e57613b7e6156f2565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2054600103613bf057818181518110613bbf57613bbf6156f2565b6020026020010151604051630b58d77560e41b81526004016103ff91906001600160a01b0391909116815260200190565b600160125f848481518110613c0757613c076156f2565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2081905550818181518110613c4457613c446156f2565b60200260200101516001600160a01b03167f4149776fc93a7a68120df1638269488e1915cd17b09b0ab741e6bf768a38c46d60405160405180910390a2613c8a8161577b565b9050613b60565b5f8111613cf05760405162461bcd60e51b815260206004820152602760248201527f476f7665726e6f7253657474696e67733a20766f74696e6720706572696f6420604482015266746f6f206c6f7760c81b60648201526084016103ff565b60075460408051918252602082018390527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e8828910160405180910390a1600755565b60085460408051918252602082018390527fccb45da8d5717e6c4544694297c4ba5cf151d455c9bb0ed4fc7a38411bc05461910160405180910390a1600855565b5f6001600160e01b038211156132785760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663234206269747360c81b60648201526084016103ff565b5f80613de785858561440e565b915091505b935093915050565b8154600160801b90819004600f0b5f818152600180860160205260409091209390935583546001600160801b03908116939091011602179055565b60608315613e3e575081611c2b565b611c2b83836145a9565b5f306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148015613ea057507f000000000000000000000000000000000000000000000000000000000000000046145b15613eca57507f000000000000000000000000000000000000000000000000000000000000000090565b611c17604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613fa657505f90506003614025565b604080515f8082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613ff7573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b03811661401f575f60019250925050614025565b91505f90505b94509492505050565b5f8160048111156140415761404161519b565b036140495750565b600181600481111561405d5761405d61519b565b036140aa5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016103ff565b60028160048111156140be576140be61519b565b0361410b5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016103ff565b600381600481111561411f5761411f61519b565b03610f3d5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016103ff565b5f82116141d45760405162461bcd60e51b815260206004820152602560248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a206e6f2077604482015264195a59da1d60da1b60648201526084016103ff565b5f858152600c602090815260408083206001600160a01b03881684529091529020546001600160801b031682116142615760405162461bcd60e51b815260206004820152602b60248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a20616c6c2060448201526a1dd95a59da1d0818d85cdd60aa1b60648201526084016103ff565b5f61426b836145d3565b905081515f03614286576142818686838761463b565b611945565b61194586868385614815565b5f815f036142a157505f919050565b5f60016142ad84614a36565b901c6001901b905060018184816142c6576142c6615b53565b048201901c905060018184816142de576142de615b53565b048201901c905060018184816142f6576142f6615b53565b048201901c9050600181848161430e5761430e615b53565b048201901c9050600181848161432657614326615b53565b048201901c9050600181848161433e5761433e615b53565b048201901c9050600181848161435657614356615b53565b048201901c9050611c2b8182858161437057614370615b53565b04614ac9565b5f5b818310156143c9575f61438b8484614ade565b5f8781526020902090915063ffffffff86169082015463ffffffff1611156143b5578092506143c3565b6143c0816001615bcb565b93505b50614378565b509392505050565b60605f6143dd83614af8565b6040805160208082528183019092529192505f91906020820181803683375050509182525060208101929092525090565b82545f9081908015614551575f61442a876132fa600185615812565b60408051808201909152905463ffffffff808216808452600160201b9092046001600160e01b0316602084015291925090871610156144ab5760405162461bcd60e51b815260206004820152601b60248201527f436865636b706f696e743a2064656372656173696e67206b657973000000000060448201526064016103ff565b805163ffffffff8088169116036144f357846144cc886132fa600186615812565b80546001600160e01b0392909216600160201b0263ffffffff909216919091179055614541565b6040805180820190915263ffffffff80881682526001600160e01b0380881660208085019182528b54600181018d555f8d81529190912094519151909216600160201b029216919091179101555b602001519250839150613dec9050565b50506040805180820190915263ffffffff80851682526001600160e01b0380851660208085019182528854600181018a555f8a815291822095519251909316600160201b029190931617920191909155905081613dec565b8151156145b95781518083602001fd5b8060405162461bcd60e51b81526004016103ff9190614d89565b5f6001600160801b038211156132785760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20316044820152663238206269747360c81b60648201526084016103ff565b5f848152600c602090815260408083206001600160a01b03871684529091529020546001600160801b0316156146835760405162461bcd60e51b81526004016103ff90615dd5565b5f848152600c602090815260408083206001600160a01b0387168452909152902080546001600160801b0319166001600160801b03841617905560ff8116614714575f848152600b6020526040812080548492906146eb9084906001600160801b0316615e29565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555061480f565b5f1960ff82160161474f575f848152600b6020526040902080548391906010906146eb908490600160801b90046001600160801b0316615e29565b60011960ff821601614784575f848152600b6020526040812060010180548492906146eb9084906001600160801b0316615e29565b60405162461bcd60e51b815260206004820152605460248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a20696e766160448201527f6c696420737570706f72742076616c75652c206d75737420626520696e636c7560648201527364656420696e20566f74655479706520656e756d60601b608482015260a4016103ff565b50505050565b805160301461487b5760405162461bcd60e51b815260206004820152602c60248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a20696e766160448201526b6c696420766f74654461746160a01b60648201526084016103ff565b6020818101516040808401515f888152600c85528281206001600160a01b038916825290945290832054608083811c946001600160801b03948516949390911c929091169081836148cc8688615bcb565b6148d69190615bcb565b6148e09190615bcb565b9050866001600160801b031681111561490b5760405162461bcd60e51b81526004016103ff90615dd5565b5f898152600c602090815260408083206001600160a01b038c168452825280832080546001600160801b0319166001600160801b03868116919091179091558c8452600b83529281902081516060808201845282548087168352600160801b900486169482019490945260019190910154909316838201528051918201905281518190614999908990615e29565b6001600160801b031681526020018683602001516149b79190615e29565b6001600160801b031681526020018583604001516149d59190615e29565b6001600160801b039081169091525f9b8c52600b602090815260409c8d90208351918401518316600160801b0291831691909117815591909b01516001909101805491909b166001600160801b031990911617909955505050505050505050565b5f80608083901c15614a4a57608092831c92015b604083901c15614a5c57604092831c92015b602083901c15614a6e57602092831c92015b601083901c15614a8057601092831c92015b600883901c15614a9257600892831c92015b600483901c15614aa457600492831c92015b600283901c15614ab657600292831c92015b600183901c1561126e5760010192915050565b5f818310614ad75781611c2b565b5090919050565b5f614aec6002848418615b67565b611c2b90848416615bcb565b5f60ff8216601f81111561126e57604051632cd44ac360e21b815260040160405180910390fd5b5f60208284031215614b2f575f80fd5b5035919050565b5f60208284031215614b46575f80fd5b81356001600160e01b031981168114611c2b575f80fd5b803560ff8116811461154b575f80fd5b5f8083601f840112614b7d575f80fd5b5081356001600160401b03811115614b93575f80fd5b602083019150836020828501011115614baa575f80fd5b9250929050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b0381118282101715614be857614be8614bb1565b60405290565b604051601f8201601f191681016001600160401b0381118282101715614c1657614c16614bb1565b604052919050565b5f6001600160401b03821115614c3657614c36614bb1565b50601f01601f191660200190565b5f614c56614c5184614c1e565b614bee565b9050828152838383011115614c69575f80fd5b828260208301375f602084830101529392505050565b5f82601f830112614c8e575f80fd5b611c2b83833560208501614c44565b5f805f805f805f8060e0898b031215614cb4575f80fd5b88359750614cc460208a01614b5d565b965060408901356001600160401b0380821115614cdf575f80fd5b614ceb8c838d01614b6d565b909850965060608b0135915080821115614d03575f80fd5b50614d108b828c01614c7f565b945050614d1f60808a01614b5d565b925060a0890135915060c089013590509295985092959890939650565b5f5b83811015614d56578181015183820152602001614d3e565b50505f910152565b5f8151808452614d75816020860160208601614d3c565b601f01601f19169290920160200192915050565b602081525f611c2b6020830184614d5e565b5f8083601f840112614dab575f80fd5b5081356001600160401b03811115614dc1575f80fd5b6020830191508360208260051b8501011115614baa575f80fd5b5f805f805f8060608789031215614df0575f80fd5b86356001600160401b0380821115614e06575f80fd5b614e128a838b01614d9b565b90985096506020890135915080821115614e2a575f80fd5b614e368a838b01614d9b565b90965094506040890135915080821115614e4e575f80fd5b50614e5b89828a01614d9b565b979a9699509497509295939492505050565b5f8151808452602080850194508084015f5b83811015614e9b57815187529582019590820190600101614e7f565b509495945050505050565b602081525f611c2b6020830184614e6d565b80356001600160a01b038116811461154b575f80fd5b5f805f8060808587031215614ee1575f80fd5b614eea85614eb8565b9350614ef860208601614eb8565b92506040850135915060608501356001600160401b03811115614f19575f80fd5b614f2587828801614c7f565b91505092959194509250565b5f60208284031215614f41575f80fd5b611c2b82614eb8565b5f6001600160401b03821115614f6257614f62614bb1565b5060051b60200190565b5f82601f830112614f7b575f80fd5b81356020614f8b614c5183614f4a565b82815260059290921b84018101918181019086841115614fa9575f80fd5b8286015b848110156110ec57614fbe81614eb8565b8352918301918301614fad565b5f82601f830112614fda575f80fd5b81356020614fea614c5183614f4a565b82815260059290921b84018101918181019086841115615008575f80fd5b8286015b848110156110ec578035835291830191830161500c565b5f82601f830112615032575f80fd5b81356020615042614c5183614f4a565b82815260059290921b84018101918181019086841115615060575f80fd5b8286015b848110156110ec5780356001600160401b03811115615082575f8081fd5b6150908986838b0101614c7f565b845250918301918301615064565b5f805f80608085870312156150b1575f80fd5b84356001600160401b03808211156150c7575f80fd5b6150d388838901614f6c565b955060208701359150808211156150e8575f80fd5b6150f488838901614fcb565b94506040870135915080821115615109575f80fd5b5061511687828801615023565b949793965093946060013593505050565b5f8060408385031215615138575f80fd5b8235915061514860208401614eb8565b90509250929050565b5f805f805f60a08688031215615165575f80fd5b8535945061517560208701614b5d565b935061518360408701614b5d565b94979396509394606081013594506080013592915050565b634e487b7160e01b5f52602160045260245ffd5b60208101600883106151c3576151c361519b565b91905290565b5f80604083850312156151da575f80fd5b8235915061514860208401614b5d565b5f80604083850312156151fb575f80fd5b61520483614eb8565b946020939093013593505050565b5f805f805f60808688031215615226575f80fd5b8535945061523660208701614b5d565b935060408601356001600160401b0380821115615251575f80fd5b61525d89838a01614b6d565b90955093506060880135915080821115615275575f80fd5b5061528288828901614c7f565b9150509295509295909350565b5f805f80604085870312156152a2575f80fd5b84356001600160401b03808211156152b8575f80fd5b6152c488838901614d9b565b909650945060208701359150808211156152dc575f80fd5b506152e987828801614d9b565b95989497509550505050565b5f805f8060608587031215615308575f80fd5b8435935061531860208601614b5d565b925060408501356001600160401b03811115615332575f80fd5b6152e987828801614b6d565b5f805f8060808587031215615351575f80fd5b84356001600160401b0380821115615367575f80fd5b61537388838901614f6c565b95506020870135915080821115615388575f80fd5b61539488838901614fcb565b945060408701359150808211156153a9575f80fd5b6153b588838901615023565b935060608701359150808211156153ca575f80fd5b508501601f810187136153db575f80fd5b614f2587823560208401614c44565b60ff60f81b8816815260e060208201525f61540860e0830189614d5e565b828103604084015261541a8189614d5e565b606084018890526001600160a01b038716608085015260a0840186905283810360c08501529050612a5a8185614e6d565b5f806020838503121561545c575f80fd5b82356001600160401b03811115615471575f80fd5b61547d85828601614d9b565b90969095509350505050565b5f805f6060848603121561549b575f80fd5b6154a484614eb8565b92506020840135915060408401356001600160401b038111156154c5575f80fd5b6154d186828701614c7f565b9150509250925092565b5f805f80606085870312156154ee575f80fd5b6154f785614eb8565b935060208501356001600160401b0380821115615512575f80fd5b908601906101408289031215615526575f80fd5b9093506040860135908082111561553b575f80fd5b506152e987828801614b6d565b5f805f6040848603121561555a575f80fd5b61556384614eb8565b925060208401356001600160401b0381111561557d575f80fd5b61558986828701614b6d565b9497909650939450505050565b5f805f805f60a086880312156155aa575f80fd5b6155b386614eb8565b94506155c160208701614eb8565b935060408601356001600160401b03808211156155dc575f80fd5b6155e889838a01614fcb565b945060608801359150808211156155fd575f80fd5b61560989838a01614fcb565b93506080880135915080821115615275575f80fd5b5f805f8060608587031215615631575f80fd5b61563a85614eb8565b93506020850135925060408501356001600160401b03811115615332575f80fd5b5f805f805f60a0868803121561566f575f80fd5b61567886614eb8565b945061568660208701614eb8565b9350604086013592506060860135915060808601356001600160401b038111156156ae575f80fd5b61528288828901614c7f565b600181811c908216806156ce57607f821691505b6020821081036156ec57634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffd5b5f823561013e1983360301811261571b575f80fd5b9190910192915050565b5f808335601e1984360301811261573a575f80fd5b8301803591506001600160401b03821115615753575f80fd5b602001915036819003821315614baa575f80fd5b634e487b7160e01b5f52601160045260245ffd5b5f6001820161578c5761578c615767565b5060010190565b5f602082840312156157a3575f80fd5b81516001600160401b038111156157b8575f80fd5b8201601f810184136157c8575f80fd5b80516157d6614c5182614c1e565b8181528560208385010111156157ea575f80fd5b612d9b826020830160208601614d3c565b5f6020828403121561580b575f80fd5b5051919050565b8181038181111561126e5761126e615767565b5f60208284031215615835575f80fd5b611c2b82614b5d565b5f6020828403121561584e575f80fd5b815165ffffffffffff81168114611c2b575f80fd5b80356002811061154b575f80fd5b5f60208284031215615881575f80fd5b611c2b82615863565b5f610140823603121561589b575f80fd5b6158a3614bc5565b6158ac83614eb8565b81526020830135602082015260408301356001600160401b038111156158d0575f80fd5b6158dc36828601614c7f565b6040830152506158ee60608401615863565b60608201526080830135608082015260a083013560a082015260c083013560c082015261591d60e08401614eb8565b60e0820152610100615930818501614eb8565b9082015261012092830135928101929092525090565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b868152608060208201525f615987608083018789615946565b828103604084015261599a818688615946565b915050826060830152979650505050505050565b600281106159be576159be61519b565b9052565b6001600160a01b038a81168252602082018a9052610140604083018190525f838201526101608301916159f8606085018c6159ae565b60808401999099525060a082019690965260c081019490945291851660e084015290931661010082015261012001919091529392505050565b848152608060208201525f608082015260a060408201525f615a5760a083018587615946565b905082606083015295945050505050565b5f8151808452602080850194508084015f5b83811015614e9b5781516001600160a01b031687529582019590820190600101615a7a565b5f81518084526020808501808196508360051b810191508286015f5b85811015615ae5578284038952615ad3848351614d5e565b98850198935090840190600101615abb565b5091979650505050505050565b608081525f615b046080830187615a68565b8281036020840152615b168187614e6d565b90508281036040840152615b2a8186615a9f565b91505082606083015295945050505050565b808202811582820484141761126e5761126e615767565b634e487b7160e01b5f52601260045260245ffd5b5f82615b8157634e487b7160e01b5f52601260045260245ffd5b500490565b818382375f9101908152919050565b5f6001600160801b03808316818103615bb057615bb0615767565b6001019392505050565b5f825161571b818460208701614d3c565b8082018082111561126e5761126e615767565b6001600160a01b038b81168252602082018b9052610140604083018190525f91615c0a8483018d614d5e565b9250615c19606085018c6159ae565b60808401999099525060a082019690965260c081019490945291851660e08401529093166101008201526101200191909152949350505050565b84815260ff84166020820152826040820152608060608201525f610f046080830184614d5e565b85815260ff8516602082015283604082015260a060608201525f615ca160a0830185614d5e565b8281036080840152615cb38185614d5e565b98975050505050505050565b60208082526021908201527f476f7665726e6f723a20696e76616c69642070726f706f73616c206c656e67746040820152600d60fb1b606082015260800190565b5f6101208b8352602060018060a01b038c1681850152816040850152615d288285018c615a68565b91508382036060850152615d3c828b614e6d565b915083820360808501528189518084528284019150828160051b850101838c015f5b83811015615d8c57601f19878403018552615d7a838351614d5e565b94860194925090850190600101615d5e565b505086810360a0880152615da0818c615a9f565b9450505050508560c08401528460e0840152828103610100840152615dc58185614d5e565b9c9b505050505050505050505050565b60208082526034908201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a20766f7465604082015273081ddbdd5b1908195e18d95959081dd95a59da1d60621b606082015260800190565b6001600160801b03818116838216019080821115615e4957615e49615767565b509291505056fe476f7665726e6f723a2063616c6c20726576657274656420776974686f7574206d657373616765737570706f72743d627261766f2671756f72756d3d616761696e73742c6162737461696e2671756f72756d3d666f722c6162737461696e26706172616d733d6672616374696f6e616ca2646970667358221220af80f8a495daf41067f05498bcb0a99923f9476d7d24e3147f7c56cadbe78bc564736f6c6343000814003300000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000180000000000000000000000000961d4921e1718e633bac8ded88c4a1cae44b785a000000000000000000000000961d4921e1718e633bac8ded88c4a1cae44b785a00000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000fbaa992a9e04e6a4fd1ba52d49c9c12baa0da3c6000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000078ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000005f0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000005f000000000000000000000000000000000000000000000000000000000000001146726178476f7665726e6f724f6d6567610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000fbaa992a9e04e6a4fd1ba52d49c9c12baa0da3c60000000000000000000000007a8a1e6966ac5b67aca3c9308fa798bb56ecac3800000000000000000000000000000000000000000000000000000000000000010000000000000000000000008adb68e26b725af5e4b9c7deefe53d7edaaeec87
Deployed Bytecode
0x6080604052600436106103f8575f3560e01c806384b0196e1161020a578063c28bc2fa1161011e578063e80f1aa7116100a8578063ece40cc111610078578063ece40cc114610dcb578063f23a6e6114610dea578063f8cc2e3c14610e15578063f8ce560a14610e34578063fc0c546a14610e53575f80fd5b8063e80f1aa714610d4f578063ea0217cf14610d6e578063eb9019d414610d8d578063ec2de58b14610dac575f80fd5b8063d914e172116100ee578063d914e17214610c8a578063dd4e2ba514610cb5578063deaaa7cc14610cc9578063df482caf14610cfc578063dfc3c9e714610d30575f80fd5b8063c28bc2fa14610c25578063c3dcf92214610c38578063c59057e414610c57578063ccb8370b14610c76575f80fd5b8063aa75a3c21161019f578063bc197c811161016f578063bc197c8114610b57578063be13109414610b82578063be74baf214610ba1578063c01f9e3714610bb6578063c1de4eed14610bef575f80fd5b8063aa75a3c214610ae6578063b021d2c314610b05578063b12c327714610b24578063b58131b014610b43575f80fd5b806397c3d334116101da57806397c3d33414610a8b5780639a802a6d14610a9e578063a7713a7014610abd578063a89f263814610ad1575f80fd5b806384b0196e146109ef57806386e80e9014610a165780638bb53cd314610a4157806391ddadf414610a60575f80fd5b8063438596321161030c5780635c0855891161029657806364cda3d41161026657806364cda3d41461095457806370b0f6601461097357806377d76602146109925780637b3c71d3146109b15780637d5e81e2146109d0575f80fd5b80635c085589146108c45780635d049c0a146108e35780635f398a141461091657806360c4247f14610935575f80fd5b80634bf5d7e9116102dc5780634bf5d7e9146107fb578063506d1f811461080f578063544ffc9c1461084257806354fd4d501461087c57806356781388146108a5575f80fd5b8063438596321461074657806343ec3e0914610792578063452115d6146107b15780634571969b146107d0575f80fd5b8063150b7a021161038d5780632fe3e2611161035d5780632fe3e2611461067d578063342cfab6146106b05780633932abb1146106e75780633bccf4fd146106fb5780633e4f49e61461071a575f80fd5b8063150b7a02146105dd5780632214a33f146106205780632656227d1461064b5780632d63f6931461065e575f80fd5b806306f3f9e6116103c857806306f3f9e61461052557806306fdde0314610544578063072c8e0d14610565578063143489d014610591575f80fd5b8063013cf08b1461040e57806301ffc9a7146104b957806302a251a3146104e85780630342018114610506575f80fd5b3661040a57005b60405180910390fd5b005b5f80fd5b348015610419575f80fd5b50610473610428366004614b1f565b60036020525f90815260409020546001600160a01b0381169064ffffffffff600160a01b8204811691600160c81b81049091169060ff600160f01b8204811691600160f81b90041685565b604080516001600160a01b03909616865264ffffffffff9485166020870152939092169284019290925290151560608301521515608082015260a0015b60405180910390f35b3480156104c4575f80fd5b506104d86104d3366004614b36565b610e72565b60405190151581526020016104b0565b3480156104f3575f80fd5b506007545b6040519081526020016104b0565b348015610511575f80fd5b506104f8610520366004614c9d565b610f0e565b348015610530575f80fd5b5061040861053f366004614b1f565b610f2c565b34801561054f575f80fd5b50610558610f40565b6040516104b09190614d89565b348015610570575f80fd5b5061058461057f366004614ddb565b610fd0565b6040516104b09190614ea6565b34801561059c575f80fd5b506105c56105ab366004614b1f565b5f908152600360205260409020546001600160a01b031690565b6040516001600160a01b0390911681526020016104b0565b3480156105e8575f80fd5b506106076105f7366004614ece565b630a85bd0160e11b949350505050565b6040516001600160e01b031990911681526020016104b0565b34801561062b575f80fd5b506104f861063a366004614f31565b60146020525f908152604090205481565b6104f861065936600461509e565b6110f7565b348015610669575f80fd5b506104f8610678366004614b1f565b611223565b348015610688575f80fd5b506104f87fb3b3f3b703cd84ce352197dcff232b1b5d3cfb2025ce47cf04742d0651f1af8881565b3480156106bb575f80fd5b506106cf6106ca366004615127565b611242565b6040516001600160801b0390911681526020016104b0565b3480156106f2575f80fd5b506006546104f8565b348015610706575f80fd5b506104f8610715366004615151565b611274565b348015610725575f80fd5b50610739610734366004614b1f565b611307565b6040516104b091906151af565b348015610751575f80fd5b506104d8610760366004615127565b5f918252600c602090815260408084206001600160a01b039390931684529190529020546001600160801b0316151590565b34801561079d575f80fd5b506104086107ac366004614b1f565b611478565b3480156107bc575f80fd5b506104f86107cb36600461509e565b611489565b3480156107db575f80fd5b506104f86107ea366004614f31565b60126020525f908152604090205481565b348015610806575f80fd5b506105586114a6565b34801561081a575f80fd5b506105c57f000000000000000000000000961d4921e1718e633bac8ded88c4a1cae44b785a81565b34801561084d575f80fd5b5061086161085c366004614b1f565b611550565b604080519384526020840192909252908201526060016104b0565b348015610887575f80fd5b506040805180820190915260018152603160f81b6020820152610558565b3480156108b0575f80fd5b506104f86108bf3660046151c9565b611581565b3480156108cf575f80fd5b506104086108de3660046151ea565b6115a8565b3480156108ee575f80fd5b506105c57f000000000000000000000000fbaa992a9e04e6a4fd1ba52d49c9c12baa0da3c681565b348015610921575f80fd5b506104f8610930366004615212565b6117bf565b348015610940575f80fd5b506104f861094f366004614b1f565b611807565b34801561095f575f80fd5b5061040861096e366004614b1f565b6118a4565b34801561097e575f80fd5b5061040861098d366004614b1f565b6118b5565b34801561099d575f80fd5b506104086109ac36600461528f565b6118c6565b3480156109bc575f80fd5b506104f86109cb3660046152f5565b61194d565b3480156109db575f80fd5b506104f86109ea36600461533e565b611993565b3480156109fa575f80fd5b50610a036119ad565b6040516104b097969594939291906153ea565b348015610a21575f80fd5b506104f8610a30366004614f31565b60136020525f908152604090205481565b348015610a4c575f80fd5b50610408610a5b36600461544b565b611a33565b348015610a6b575f80fd5b50610a74611ba5565b60405165ffffffffffff90911681526020016104b0565b348015610a96575f80fd5b5060646104f8565b348015610aa9575f80fd5b506104f8610ab8366004615489565b611c1c565b348015610ac8575f80fd5b506104f8611c32565b348015610adc575f80fd5b506104f8600e5481565b348015610af1575f80fd5b50610408610b00366004614f31565b611c4b565b348015610b10575f80fd5b506104f8610b1f3660046154db565b611c5c565b348015610b2f575f80fd5b50610408610b3e366004615548565b611fb6565b348015610b4e575f80fd5b506104f861231d565b348015610b62575f80fd5b50610607610b71366004615596565b63bc197c8160e01b95945050505050565b348015610b8d575f80fd5b50610408610b9c36600461544b565b612327565b348015610bac575f80fd5b506104f860115481565b348015610bc1575f80fd5b506104f8610bd0366004614b1f565b5f90815260036020526040902054600160c81b900464ffffffffff1690565b348015610bfa575f80fd5b506104f8610c093660046151ea565b601560209081525f928352604080842090915290825290205481565b610408610c3336600461561e565b61236e565b348015610c43575f80fd5b50610408610c5236600461544b565b612387565b348015610c62575f80fd5b506104f8610c7136600461509e565b6124ed565b348015610c81575f80fd5b506104f8612526565b348015610c95575f80fd5b506104f8610ca4366004614b1f565b60106020525f908152604090205481565b348015610cc0575f80fd5b50610558612531565b348015610cd4575f80fd5b506104f87f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f81565b348015610d07575f80fd5b506106cf610d16366004614f31565b600d6020525f90815260409020546001600160801b031681565b348015610d3b575f80fd5b506104f8610d4a366004614b1f565b612551565b348015610d5a575f80fd5b50610408610d6936600461544b565b6125dd565b348015610d79575f80fd5b50610408610d88366004614b1f565b612620565b348015610d98575f80fd5b506104f8610da73660046151ea565b612631565b348015610db7575f80fd5b506104f8610dc6366004614b1f565b612650565b348015610dd6575f80fd5b50610408610de5366004614b1f565b612722565b348015610df5575f80fd5b50610607610e0436600461565b565b63f23a6e6160e01b95945050505050565b348015610e20575f80fd5b50610408610e2f3660046151ea565b612733565b348015610e3f575f80fd5b506104f8610e4e366004614b1f565b6127d2565b348015610e5e575f80fd5b506009546105c5906001600160a01b031681565b5f63288ace0360e11b6318df743f60e31b63bf26d89760e01b6379dd796f60e01b6001600160e01b03198616821480610eb757506001600160e01b0319868116908216145b80610ece57506001600160e01b0319868116908516145b80610ee957506001600160e01b03198616630271189760e51b145b80610f0457506301ffc9a760e01b6001600160e01b03198716145b9695505050505050565b5f610f1f8989898989898989612809565b9998505050505050505050565b610f34612a68565b610f3d81612ab3565b50565b606060028054610f4f906156ba565b80601f0160208091040260200160405190810160405280929190818152602001828054610f7b906156ba565b8015610fc65780601f10610f9d57610100808354040283529160200191610fc6565b820191905f5260205f20905b815481529060010190602001808311610fa957829003601f168201915b5050505050905090565b60608584141580610fe15750858214155b15610fff57604051630a1eb2d160e11b815260040160405180910390fd5b856001600160401b0381111561101757611017614bb1565b604051908082528060200260200182016040528015611040578160200160208202803683370190505b5090505f5b868110156110ec576110bf888883818110611062576110626156f2565b90506020020160208101906110779190614f31565b878784818110611089576110896156f2565b905060200281019061109b9190615706565b8686858181106110ad576110ad6156f2565b9050602002810190610b1f9190615725565b8282815181106110d1576110d16156f2565b60209081029190910101526110e58161577b565b9050611045565b509695505050505050565b5f80611105868686866124ed565b90505f61111182611307565b905060048160078111156111275761112761519b565b1480611144575060058160078111156111425761114261519b565b145b61119a5760405162461bcd60e51b815260206004820152602160248201527f476f7665726e6f723a2070726f706f73616c206e6f74207375636365737366756044820152601b60fa1b60648201526084016103ff565b5f8281526003602052604090819020805460ff60f01b1916600160f01b179055517f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f906111ea9084815260200190565b60405180910390a16111ff8288888888612bae565b61120c8288888888612c39565b6112198288888888612bae565b5095945050505050565b5f90815260036020526040902054600160a01b900464ffffffffff1690565b5f828152600c602090815260408083206001600160a01b03851684529091529020546001600160801b03165b92915050565b604080517f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f602082015290810186905260ff851660608201525f9081906112e0906112d8906080015b60405160208183030381529060405280519060200120612d32565b868686612d5e565b90506112fc87828860405180602001604052805f815250612d7a565b979650505050505050565b5f8181526003602052604081208054600160f01b900460ff161561132e5750600792915050565b8054600160f81b900460ff16156113485750600292915050565b5f61135284611223565b9050805f036113a35760405162461bcd60e51b815260206004820152601d60248201527f476f7665726e6f723a20756e6b6e6f776e2070726f706f73616c20696400000060448201526064016103ff565b5f6113ac611ba5565b65ffffffffffff16905080821015806113d257505f828152601060205260409020544311155b156113e157505f949350505050565b6113ea85612da4565b156113fa57506004949350505050565b61140385612dd2565b1561141357506003949350505050565b5f85815260036020526040902054600160c81b900464ffffffffff168181106114425750600195945050505050565b61144b86612deb565b801561145b575061145b86612e3c565b1561146c5750600395945050505050565b50600495945050505050565b611480612a68565b610f3d81612e70565b5f60405160016205739760e41b0319815260040160405180910390fd5b60095460408051634bf5d7e960e01b815290516060926001600160a01b031691634bf5d7e9916004808301925f9291908290030181865afa92505050801561150f57506040513d5f823e601f3d908101601f1916820160405261150c9190810190615793565b60015b61154b575060408051808201909152601d81527f6d6f64653d626c6f636b6e756d6265722666726f6d3d64656661756c74000000602082015290565b919050565b5f908152600b6020526040902080546001909101546001600160801b0380831693600160801b909304811692911690565b5f803390506115a084828560405180602001604052805f815250612d7a565b949350505050565b6001600160a01b0382165f9081526015602090815260408083208484529091528120549080806115d88685612ef4565b91945092509050600360408051602081019091525f905261161e6107348585857fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706124ed565b600781111561162f5761162f61519b565b1461164d57604051630fd1155b60e41b815260040160405180910390fd5b5f8690505f6116cc826040518061014001604052808b6001600160a01b031681526020015f815260200160405180602001604052805f81525081526020015f600181111561169d5761169d61519b565b81525f6020820181905260408201819052606082018190526080820181905260a082015260c0018a9052613016565b604051631f60ca5d60e21b8152306004820152602481018290529091506001600160a01b03831690637d832974906044016020604051808303815f875af1158015611719573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061173d91906157fb565b60010361176057604051635c0abc6d60e11b8152600481018290526024016103ff565b60405163d4d9bdcd60e01b8152600481018290526001600160a01b0383169063d4d9bdcd906024015f604051808303815f87803b15801561179f575f80fd5b505af11580156117b1573d5f803e3d5ffd5b505050505050505050505050565b5f803390506112fc87828888888080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508a92506130bd915050565b600a80545f91829061181a600184615812565b8154811061182a5761182a6156f2565b5f9182526020918290206040805180820190915291015463ffffffff8116808352600160201b9091046001600160e01b0316928201929092529150841061187f57602001516001600160e01b03169392505050565b61189361188b85613214565b600a9061327c565b6001600160e01b0316949350505050565b6118ac612a68565b610f3d81613329565b6118bd612a68565b610f3d81613367565b828181146118e75760405163a669fc0560e01b815260040160405180910390fd5b5f5b8181101561194557611934868683818110611906576119066156f2565b9050602002013585858481811061191f5761191f6156f2565b90506020020160208101906108bf9190615825565b5061193e8161577b565b90506118e9565b505050505050565b5f80339050610f0486828787878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250612d7a92505050565b5f60405163098bb82f60e01b815260040160405180910390fd5b5f606080828080836119df7f46726178476f7665726e6f724f6d656761000000000000000000000000000011836133a8565b611a0a7f310000000000000000000000000000000000000000000000000000000000000160016133a8565b604080515f80825260208201909252600f60f81b9b939a50919850469750309650945092509050565b611a3b612a68565b5f5b81811015611ba05760135f848484818110611a5a57611a5a6156f2565b9050602002016020810190611a6f9190614f31565b6001600160a01b03166001600160a01b031681526020019081526020015f20545f03611ae157828282818110611aa757611aa76156f2565b9050602002016020810190611abc9190614f31565b604051630ee1e0b360e41b81526001600160a01b0390911660048201526024016103ff565b60135f848484818110611af657611af66156f2565b9050602002016020810190611b0b9190614f31565b6001600160a01b03166001600160a01b031681526020019081526020015f205f90557f3f75b27f9b6f643d57ab0006da862b383ffc26813fc08462f2d56270aaa950c0838383818110611b6057611b606156f2565b9050602002016020810190611b759190614f31565b6040516001600160a01b03909116815260200160405180910390a1611b998161577b565b9050611a3d565b505050565b600954604080516324776b7d60e21b815290515f926001600160a01b0316916391ddadf49160048083019260209291908290030181865afa925050508015611c0a575060408051601f3d908101601f19168201909252611c079181019061583e565b60015b61154b57611c1743613451565b905090565b5f611c288484846134b7565b90505b9392505050565b5f611c3d600a61352a565b6001600160e01b0316905090565b611c53612a68565b610f3d81613561565b5f611c66856135bb565b6001611c786080860160608701615871565b6001811115611c8957611c8961519b565b148015611cc6575060135f611ca16020870187614f31565b6001600160a01b03166001600160a01b031681526020019081526020015f2054600114155b15611cfd57611cd86020850185614f31565b6040516317645e7d60e21b81526001600160a01b0390911660048201526024016103ff565b5f8590505f816001600160a01b031663e75235b86040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d3e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d6291906157fb565b9050611da485858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508592506135f1915050565b6001600160a01b0387165f9081526015602090815260408083206101208a0135845290915290205415611dea57604051639e01d15b60e01b815260040160405180910390fd5b816001600160a01b031663affed0e06040518163ffffffff1660e01b81526004016020604051808303815f875af1158015611e27573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e4b91906157fb565b8661012001351015611e705760405163d9c6386f60e01b815260040160405180910390fd5b5f611e8383611e7e8961588a565b613016565b90506001600160a01b0383166312fb68e082611ea260408b018b615725565b8a8a886040518763ffffffff1660e01b8152600401611ec69695949392919061596e565b5f6040518083038186803b158015611edc575f80fd5b505afa158015611eee573d5f803e3d5ffd5b505050505f805f611eff8b85612ef4565b925092509250611f2083838360405180602001604052805f8152508f613658565b96508360155f8d6001600160a01b03166001600160a01b031681526020019081526020015f205f8c610120013581526020019081526020015f208190555086848c6001600160a01b03167f5ed3fb2763971f1f5e3d1e6f215e92ebe28160b512c2da07f4b12a46021adb0b8d6101200135604051611fa091815260200190565b60405180910390a4505050505050949350505050565b611fbf836135bb565b5f8390505f816001600160a01b031663e75235b86040518163ffffffff1660e01b8152600401602060405180830381865afa158015612000573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061202491906157fb565b905061206684848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508592506135f1915050565b5f826001600160a01b031663affed0e06040518163ffffffff1660e01b81526004016020604051808303815f875af11580156120a4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120c891906157fb565b90505f836001600160a01b031663d8d11f78885f805f805f805f8b6040518a63ffffffff1660e01b8152600401612107999897969594939291906159c2565b602060405180830381865afa158015612122573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061214691906157fb565b6040516297db4760e51b81529091506001600160a01b038516906312fb68e09061217a9084908a908a908990600401615a31565b5f6040518083038186803b158015612190575f80fd5b505afa1580156121a2573d5f803e3d5ffd5b5050506001600160a01b0388165f908152601560209081526040808320868452909152812054915081156122bd575f805f6121dd8c86612ef4565b60408051602081019091525f90529194509250905061221e8383837fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706124ed565b93505f61222a85611307565b905060028160078111156122405761224061519b565b0361225e576040516303ff04cd60e51b815260040160405180910390fd5b5f858152600360205260409081902080546001600160f81b0316600160f81b179055517f789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c906122b09087815260200190565b60405180910390a1505050505b60405163d4d9bdcd60e01b8152600481018490526001600160a01b0387169063d4d9bdcd906024015f604051808303815f87803b1580156122fc575f80fd5b505af115801561230e573d5f803e3d5ffd5b50505050505050505050505050565b5f611c1760085490565b61232f612a68565b61236a8282808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250613a1b92505050565b5050565b604051635adddc5560e01b815260040160405180910390fd5b61238f612a68565b5f5b81811015611ba05760125f8484848181106123ae576123ae6156f2565b90506020020160208101906123c39190614f31565b6001600160a01b03166001600160a01b031681526020019081526020015f20545f03612435578282828181106123fb576123fb6156f2565b90506020020160208101906124109190614f31565b60405163138c2add60e01b81526001600160a01b0390911660048201526024016103ff565b60125f84848481811061244a5761244a6156f2565b905060200201602081019061245f9190614f31565b6001600160a01b03166001600160a01b031681526020019081526020015f205f9055828282818110612493576124936156f2565b90506020020160208101906124a89190614f31565b6001600160a01b03167fe710dd5e6adb3eb2ba468162b8ead4d66e26d337074a5067caab50b676925ab860405160405180910390a26124e68161577b565b9050612391565b5f848484846040516020016125059493929190615af2565b60408051601f19818403018152919052805160209091012095945050505050565b5f611c3d600f61352a565b6060604051806080016040528060498152602001615e7860499139905090565b600f80545f918290612564600184615812565b81548110612574576125746156f2565b5f9182526020918290206040805180820190915291015463ffffffff8116808352600160201b9091046001600160e01b031692820192909252915084106125c957602001516001600160e01b03169392505050565b6118936125d585613214565b600f9061327c565b6125e5612a68565b61236a8282808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250613b5e92505050565b612628612a68565b610f3d81613c91565b5f611c2b838361264b60408051602081019091525f815290565b6134b7565b5f81158061265e5750428210155b1561267c5760405163749c2c6d60e01b815260040160405180910390fd5b606461268783612551565b604051630981b24d60e41b8152600481018590527f000000000000000000000000961d4921e1718e633bac8ded88c4a1cae44b785a6001600160a01b03169063981b24d090602401602060405180830381865afa1580156126ea573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061270e91906157fb565b6127189190615b3c565b61126e9190615b67565b61272a612a68565b610f3d81613d31565b61273b612a68565b6001600160a01b0382165f9081526014602052604090205481810361277357604051631a73bda360e11b815260040160405180910390fd5b6001600160a01b0383165f818152601460209081526040918290208590558151928352820183905281018390527fad48c7f5802308fb2675c0f699237e1a6d39e5170f647470b1d8ed2803262e599060600160405180910390a1505050565b5f8115806127e05750428210155b156127fe5760405163749c2c6d60e01b815260040160405180910390fd5b606461268783611807565b5f84516040148061281957508451155b6128975760405162461bcd60e51b815260206004820152604360248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a20696e766160448201527f6c696420706172616d7320666f72207369676e61747572652d626173656420766064820152626f746560e81b608482015260a4016103ff565b5f6129166112d87fb3b3f3b703cd84ce352197dcff232b1b5d3cfb2025ce47cf04742d0651f1af888c8c8c8c6040516128d1929190615b86565b60405180910390208b805190602001206040516020016112bd959493929190948552602085019390935260ff9190911660408401526060830152608082015260a00190565b90508551604003612a17576040868101516001600160a01b0383165f908152600d60205291909120546001600160801b03918216911681146129c05760405162461bcd60e51b815260206004820152603b60248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a207369676e60448201527f61747572652068617320616c7265616479206265656e2075736564000000000060648201526084016103ff565b6001600160a01b0382165f908152600d6020526040812080546001600160801b0316916129ec83615b95565b91906101000a8154816001600160801b0302191690836001600160801b031602179055505060308752505b612a5a8a828b8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508d92506130bd915050565b9a9950505050505050505050565b336001600160a01b037f000000000000000000000000fbaa992a9e04e6a4fd1ba52d49c9c12baa0da3c61614612ab1576040516362c4ffa560e11b815260040160405180910390fd5b565b6064811115612b365760405162461bcd60e51b815260206004820152604360248201527f476f7665726e6f72566f74657351756f72756d4672616374696f6e3a2071756f60448201527f72756d4e756d657261746f72206f7665722071756f72756d44656e6f6d696e616064820152623a37b960e91b608482015260a4016103ff565b5f612b3f611c32565b9050612b6e612b5c612b4f611ba5565b65ffffffffffff16613214565b612b6584613d72565b600a9190613dda565b505060408051828152602081018490527f0553476bf02ef2726e8ce5ced78d63e26e602e4a2257b1f559418e24b463399791015b60405180910390a15050565b612c32565b845181101561194557306001600160a01b0316858281518110612bd857612bd86156f2565b60200260200101516001600160a01b031603612c2257612c22838281518110612c0357612c036156f2565b6020026020010151805190602001206004613df490919063ffffffff16565b612c2b8161577b565b9050612bb3565b5050505050565b5f604051806060016040528060278152602001615e516027913990505f5b8551811015612d29575f80878381518110612c7457612c746156f2565b60200260200101516001600160a01b0316878481518110612c9757612c976156f2565b6020026020010151878581518110612cb157612cb16156f2565b6020026020010151604051612cc69190615bba565b5f6040518083038185875af1925050503d805f8114612d00576040519150601f19603f3d011682016040523d82523d5f602084013e612d05565b606091505b5091509150612d15828286613e2f565b50505080612d229061577b565b9050612c57565b50505050505050565b5f61126e612d3e613e48565b8360405161190160f01b8152600281019290925260228201526042902090565b5f805f612d6d87878787613f71565b915091506112198161402e565b5f612d9b85858585612d9660408051602081019091525f815290565b6130bd565b95945050505050565b5f80612daf83611550565b509150505f612dbd84611223565b9050612dc881612650565b9091119392505050565b5f80612ddd83611550565b505090505f612dbd84611223565b5f805f80612df885611550565b9250925092505f828411612e0c5782612e0e565b835b90505f612e1a87611223565b9050612e268383615bcb565b612e2f826127d2565b1115979650505050505050565b5f805f612e4884611550565b5091509150815f148015612e5a575080155b15612e6857505f9392505050565b111592915050565b6064811115612e91576040516271e29960e21b815260040160405180910390fd5b5f612e9a612526565b9050612ebc612eaa612b4f611ba5565b612eb384613d72565b600f9190613dda565b505060408051828152602081018490527fdd2b8b2d874e19a344cba53b9fb534ea748ef117ed4b75c67569a794864541939101612ba2565b6040805160018082528183019092526060918291829160208083019080368337505060408051600180825281830190925292955090506020808301908036833701905050604080516001808252818301909252919350816020015b6060815260200190600190039081612f4f57905050905084835f81518110612f7957612f796156f2565b60200260200101906001600160a01b031690816001600160a01b0316815250505f825f81518110612fac57612fac6156f2565b60209081029190910181019190915260408051602480820188905282518083039091018152604490910190915290810180516001600160e01b031663d4d9bdcd60e01b179052815182905f90613004576130046156f2565b60200260200101819052509250925092565b5f826001600160a01b031663d8d11f78835f015184602001518560400151866060015187608001518860a001518960c001518a60e001518b61010001518c61012001516040518b63ffffffff1660e01b815260040161307e9a99989796959493929190615bde565b602060405180830381865afa158015613099573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c2b91906157fb565b5f85815260036020526040812060016130d588611307565b60078111156130e6576130e661519b565b1461313f5760405162461bcd60e51b815260206004820152602360248201527f476f7665726e6f723a20766f7465206e6f742063757272656e746c792061637460448201526269766560e81b60648201526084016103ff565b80545f9061315d908890600160a01b900464ffffffffff16866134b7565b905061316c8888888488614177565b83515f036131c057866001600160a01b03167fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda4898884896040516131b39493929190615c53565b60405180910390a26112fc565b866001600160a01b03167fe2babfbac5889a709b63bb7f598b324e08bc5a4fb9ec647fb3cbc9ec07eb87128988848989604051613201959493929190615c7a565b60405180910390a2979650505050505050565b5f63ffffffff8211156132785760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b60648201526084016103ff565b5090565b81545f90818160058111156132d6575f61329584614292565b61329f9085615812565b5f8881526020902090915081015463ffffffff90811690871610156132c6578091506132d4565b6132d1816001615bcb565b92505b505b5f6132e387878585614376565b9050801561331d57613307876132fa600184615812565b5f91825260209091200190565b54600160201b90046001600160e01b03166112fc565b5f979650505050505050565b600e80549082905560408051828152602081018490527fd3c1cdfd662fbb8e44190410d3a0d46855746182cb8d1e5e41bc84f5afecef4f9101612ba2565b60065460408051918252602082018390527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a93910160405180910390a1600655565b606060ff83146133c2576133bb836143d1565b905061126e565b8180546133ce906156ba565b80601f01602080910402602001604051908101604052809291908181526020018280546133fa906156ba565b80156134455780601f1061341c57610100808354040283529160200191613445565b820191905f5260205f20905b81548152906001019060200180831161342857829003601f168201915b5050505050905061126e565b5f65ffffffffffff8211156132785760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203460448201526538206269747360d01b60648201526084016103ff565b600954604051630748d63560e31b81526001600160a01b038581166004830152602482018590525f921690633a46b1a890604401602060405180830381865afa158015613506573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c2891906157fb565b80545f90801561355957613543836132fa600184615812565b54600160201b90046001600160e01b0316611c2b565b5f9392505050565b600980546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527fc255828f3e19c78de5df3dd5b6706d49bd5dd58e76275f97bd699878700995209101612ba2565b6001600160a01b0381165f908152601260205260408120549003610f3d576040516282b42960e81b815260040160405180910390fd5b5f805f5b83811015612c325760418082028601602081015191015160ff169350915060018390036136485781306001600160a01b03821603613646576040516308fbb1df60e31b815260040160405180910390fd5b505b6136518161577b565b90506135f5565b5f61366c86868686805190602001206124ed565b9050845186511461368f5760405162461bcd60e51b81526004016103ff90615cbf565b83518651146136b05760405162461bcd60e51b81526004016103ff90615cbf565b5f8651116137005760405162461bcd60e51b815260206004820152601860248201527f476f7665726e6f723a20656d7074792070726f706f73616c000000000000000060448201526064016103ff565b5f81815260036020526040902054600160a01b900464ffffffffff16156137735760405162461bcd60e51b815260206004820152602160248201527f476f7665726e6f723a2070726f706f73616c20616c72656164792065786973746044820152607360f81b60648201526084016103ff565b335f61377e60065490565b613786611ba5565b65ffffffffffff166137989190615bcb565b6040516396d6d2fb60e01b8152600481018290529091505f906001600160a01b037f000000000000000000000000961d4921e1718e633bac8ded88c4a1cae44b785a16906396d6d2fb906024015f604051808303815f87803b1580156137fc575f80fd5b505af192505050801561380d575060015b5060118290556001600160a01b0385165f908152601460205260408120549081810361383b5760075461383d565b815b90506138498185615bcb565b925050506040518060a00160405280846001600160a01b031681526020018364ffffffffff1681526020018264ffffffffff1681526020015f151581526020015f151581525060035f8681526020019081526020015f205f820151815f015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151815f0160146101000a81548164ffffffffff021916908364ffffffffff1602179055506040820151815f0160196101000a81548164ffffffffff021916908364ffffffffff1602179055506060820151815f01601e6101000a81548160ff0219169083151502179055506080820151815f01601f6101000a81548160ff021916908315150217905550905050600e54436139699190615bcb565b5f8381526010602052604090205588517f7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e090859085908c908c906001600160401b038111156139ba576139ba614bb1565b6040519080825280602002602001820160405280156139ed57816020015b60608152602001906001900390816139d85790505b508c88888e604051613a0799989796959493929190615d00565b60405180910390a150505095945050505050565b5f5b815181101561236a5760135f838381518110613a3b57613a3b6156f2565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2054600103613aad57818181518110613a7c57613a7c6156f2565b60200260200101516040516394369fd360e01b81526004016103ff91906001600160a01b0391909116815260200190565b600160135f848481518110613ac457613ac46156f2565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f20819055507ff48d3b938905d7162ca91551f61d4d458d43159e04847eb28ed7d94fbdb3bc2f828281518110613b2257613b226156f2565b6020026020010151604051613b4691906001600160a01b0391909116815260200190565b60405180910390a1613b578161577b565b9050613a1d565b5f5b815181101561236a5760125f838381518110613b7e57613b7e6156f2565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2054600103613bf057818181518110613bbf57613bbf6156f2565b6020026020010151604051630b58d77560e41b81526004016103ff91906001600160a01b0391909116815260200190565b600160125f848481518110613c0757613c076156f2565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2081905550818181518110613c4457613c446156f2565b60200260200101516001600160a01b03167f4149776fc93a7a68120df1638269488e1915cd17b09b0ab741e6bf768a38c46d60405160405180910390a2613c8a8161577b565b9050613b60565b5f8111613cf05760405162461bcd60e51b815260206004820152602760248201527f476f7665726e6f7253657474696e67733a20766f74696e6720706572696f6420604482015266746f6f206c6f7760c81b60648201526084016103ff565b60075460408051918252602082018390527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e8828910160405180910390a1600755565b60085460408051918252602082018390527fccb45da8d5717e6c4544694297c4ba5cf151d455c9bb0ed4fc7a38411bc05461910160405180910390a1600855565b5f6001600160e01b038211156132785760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663234206269747360c81b60648201526084016103ff565b5f80613de785858561440e565b915091505b935093915050565b8154600160801b90819004600f0b5f818152600180860160205260409091209390935583546001600160801b03908116939091011602179055565b60608315613e3e575081611c2b565b611c2b83836145a9565b5f306001600160a01b037f000000000000000000000000bcb25d7582d0738a77508096b05488d49181b25516148015613ea057507f000000000000000000000000000000000000000000000000000000000000000146145b15613eca57507f18e45c9fb31a5a64c5309dfee5edd1a39f1985a326c9af56738d3ce72494894990565b611c17604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f620ac8ea4a3c475715e3a262a03da2938e289791e878a009589871e19bdbc67d918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613fa657505f90506003614025565b604080515f8082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613ff7573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b03811661401f575f60019250925050614025565b91505f90505b94509492505050565b5f8160048111156140415761404161519b565b036140495750565b600181600481111561405d5761405d61519b565b036140aa5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016103ff565b60028160048111156140be576140be61519b565b0361410b5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016103ff565b600381600481111561411f5761411f61519b565b03610f3d5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016103ff565b5f82116141d45760405162461bcd60e51b815260206004820152602560248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a206e6f2077604482015264195a59da1d60da1b60648201526084016103ff565b5f858152600c602090815260408083206001600160a01b03881684529091529020546001600160801b031682116142615760405162461bcd60e51b815260206004820152602b60248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a20616c6c2060448201526a1dd95a59da1d0818d85cdd60aa1b60648201526084016103ff565b5f61426b836145d3565b905081515f03614286576142818686838761463b565b611945565b61194586868385614815565b5f815f036142a157505f919050565b5f60016142ad84614a36565b901c6001901b905060018184816142c6576142c6615b53565b048201901c905060018184816142de576142de615b53565b048201901c905060018184816142f6576142f6615b53565b048201901c9050600181848161430e5761430e615b53565b048201901c9050600181848161432657614326615b53565b048201901c9050600181848161433e5761433e615b53565b048201901c9050600181848161435657614356615b53565b048201901c9050611c2b8182858161437057614370615b53565b04614ac9565b5f5b818310156143c9575f61438b8484614ade565b5f8781526020902090915063ffffffff86169082015463ffffffff1611156143b5578092506143c3565b6143c0816001615bcb565b93505b50614378565b509392505050565b60605f6143dd83614af8565b6040805160208082528183019092529192505f91906020820181803683375050509182525060208101929092525090565b82545f9081908015614551575f61442a876132fa600185615812565b60408051808201909152905463ffffffff808216808452600160201b9092046001600160e01b0316602084015291925090871610156144ab5760405162461bcd60e51b815260206004820152601b60248201527f436865636b706f696e743a2064656372656173696e67206b657973000000000060448201526064016103ff565b805163ffffffff8088169116036144f357846144cc886132fa600186615812565b80546001600160e01b0392909216600160201b0263ffffffff909216919091179055614541565b6040805180820190915263ffffffff80881682526001600160e01b0380881660208085019182528b54600181018d555f8d81529190912094519151909216600160201b029216919091179101555b602001519250839150613dec9050565b50506040805180820190915263ffffffff80851682526001600160e01b0380851660208085019182528854600181018a555f8a815291822095519251909316600160201b029190931617920191909155905081613dec565b8151156145b95781518083602001fd5b8060405162461bcd60e51b81526004016103ff9190614d89565b5f6001600160801b038211156132785760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20316044820152663238206269747360c81b60648201526084016103ff565b5f848152600c602090815260408083206001600160a01b03871684529091529020546001600160801b0316156146835760405162461bcd60e51b81526004016103ff90615dd5565b5f848152600c602090815260408083206001600160a01b0387168452909152902080546001600160801b0319166001600160801b03841617905560ff8116614714575f848152600b6020526040812080548492906146eb9084906001600160801b0316615e29565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555061480f565b5f1960ff82160161474f575f848152600b6020526040902080548391906010906146eb908490600160801b90046001600160801b0316615e29565b60011960ff821601614784575f848152600b6020526040812060010180548492906146eb9084906001600160801b0316615e29565b60405162461bcd60e51b815260206004820152605460248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a20696e766160448201527f6c696420737570706f72742076616c75652c206d75737420626520696e636c7560648201527364656420696e20566f74655479706520656e756d60601b608482015260a4016103ff565b50505050565b805160301461487b5760405162461bcd60e51b815260206004820152602c60248201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a20696e766160448201526b6c696420766f74654461746160a01b60648201526084016103ff565b6020818101516040808401515f888152600c85528281206001600160a01b038916825290945290832054608083811c946001600160801b03948516949390911c929091169081836148cc8688615bcb565b6148d69190615bcb565b6148e09190615bcb565b9050866001600160801b031681111561490b5760405162461bcd60e51b81526004016103ff90615dd5565b5f898152600c602090815260408083206001600160a01b038c168452825280832080546001600160801b0319166001600160801b03868116919091179091558c8452600b83529281902081516060808201845282548087168352600160801b900486169482019490945260019190910154909316838201528051918201905281518190614999908990615e29565b6001600160801b031681526020018683602001516149b79190615e29565b6001600160801b031681526020018583604001516149d59190615e29565b6001600160801b039081169091525f9b8c52600b602090815260409c8d90208351918401518316600160801b0291831691909117815591909b01516001909101805491909b166001600160801b031990911617909955505050505050505050565b5f80608083901c15614a4a57608092831c92015b604083901c15614a5c57604092831c92015b602083901c15614a6e57602092831c92015b601083901c15614a8057601092831c92015b600883901c15614a9257600892831c92015b600483901c15614aa457600492831c92015b600283901c15614ab657600292831c92015b600183901c1561126e5760010192915050565b5f818310614ad75781611c2b565b5090919050565b5f614aec6002848418615b67565b611c2b90848416615bcb565b5f60ff8216601f81111561126e57604051632cd44ac360e21b815260040160405180910390fd5b5f60208284031215614b2f575f80fd5b5035919050565b5f60208284031215614b46575f80fd5b81356001600160e01b031981168114611c2b575f80fd5b803560ff8116811461154b575f80fd5b5f8083601f840112614b7d575f80fd5b5081356001600160401b03811115614b93575f80fd5b602083019150836020828501011115614baa575f80fd5b9250929050565b634e487b7160e01b5f52604160045260245ffd5b60405161014081016001600160401b0381118282101715614be857614be8614bb1565b60405290565b604051601f8201601f191681016001600160401b0381118282101715614c1657614c16614bb1565b604052919050565b5f6001600160401b03821115614c3657614c36614bb1565b50601f01601f191660200190565b5f614c56614c5184614c1e565b614bee565b9050828152838383011115614c69575f80fd5b828260208301375f602084830101529392505050565b5f82601f830112614c8e575f80fd5b611c2b83833560208501614c44565b5f805f805f805f8060e0898b031215614cb4575f80fd5b88359750614cc460208a01614b5d565b965060408901356001600160401b0380821115614cdf575f80fd5b614ceb8c838d01614b6d565b909850965060608b0135915080821115614d03575f80fd5b50614d108b828c01614c7f565b945050614d1f60808a01614b5d565b925060a0890135915060c089013590509295985092959890939650565b5f5b83811015614d56578181015183820152602001614d3e565b50505f910152565b5f8151808452614d75816020860160208601614d3c565b601f01601f19169290920160200192915050565b602081525f611c2b6020830184614d5e565b5f8083601f840112614dab575f80fd5b5081356001600160401b03811115614dc1575f80fd5b6020830191508360208260051b8501011115614baa575f80fd5b5f805f805f8060608789031215614df0575f80fd5b86356001600160401b0380821115614e06575f80fd5b614e128a838b01614d9b565b90985096506020890135915080821115614e2a575f80fd5b614e368a838b01614d9b565b90965094506040890135915080821115614e4e575f80fd5b50614e5b89828a01614d9b565b979a9699509497509295939492505050565b5f8151808452602080850194508084015f5b83811015614e9b57815187529582019590820190600101614e7f565b509495945050505050565b602081525f611c2b6020830184614e6d565b80356001600160a01b038116811461154b575f80fd5b5f805f8060808587031215614ee1575f80fd5b614eea85614eb8565b9350614ef860208601614eb8565b92506040850135915060608501356001600160401b03811115614f19575f80fd5b614f2587828801614c7f565b91505092959194509250565b5f60208284031215614f41575f80fd5b611c2b82614eb8565b5f6001600160401b03821115614f6257614f62614bb1565b5060051b60200190565b5f82601f830112614f7b575f80fd5b81356020614f8b614c5183614f4a565b82815260059290921b84018101918181019086841115614fa9575f80fd5b8286015b848110156110ec57614fbe81614eb8565b8352918301918301614fad565b5f82601f830112614fda575f80fd5b81356020614fea614c5183614f4a565b82815260059290921b84018101918181019086841115615008575f80fd5b8286015b848110156110ec578035835291830191830161500c565b5f82601f830112615032575f80fd5b81356020615042614c5183614f4a565b82815260059290921b84018101918181019086841115615060575f80fd5b8286015b848110156110ec5780356001600160401b03811115615082575f8081fd5b6150908986838b0101614c7f565b845250918301918301615064565b5f805f80608085870312156150b1575f80fd5b84356001600160401b03808211156150c7575f80fd5b6150d388838901614f6c565b955060208701359150808211156150e8575f80fd5b6150f488838901614fcb565b94506040870135915080821115615109575f80fd5b5061511687828801615023565b949793965093946060013593505050565b5f8060408385031215615138575f80fd5b8235915061514860208401614eb8565b90509250929050565b5f805f805f60a08688031215615165575f80fd5b8535945061517560208701614b5d565b935061518360408701614b5d565b94979396509394606081013594506080013592915050565b634e487b7160e01b5f52602160045260245ffd5b60208101600883106151c3576151c361519b565b91905290565b5f80604083850312156151da575f80fd5b8235915061514860208401614b5d565b5f80604083850312156151fb575f80fd5b61520483614eb8565b946020939093013593505050565b5f805f805f60808688031215615226575f80fd5b8535945061523660208701614b5d565b935060408601356001600160401b0380821115615251575f80fd5b61525d89838a01614b6d565b90955093506060880135915080821115615275575f80fd5b5061528288828901614c7f565b9150509295509295909350565b5f805f80604085870312156152a2575f80fd5b84356001600160401b03808211156152b8575f80fd5b6152c488838901614d9b565b909650945060208701359150808211156152dc575f80fd5b506152e987828801614d9b565b95989497509550505050565b5f805f8060608587031215615308575f80fd5b8435935061531860208601614b5d565b925060408501356001600160401b03811115615332575f80fd5b6152e987828801614b6d565b5f805f8060808587031215615351575f80fd5b84356001600160401b0380821115615367575f80fd5b61537388838901614f6c565b95506020870135915080821115615388575f80fd5b61539488838901614fcb565b945060408701359150808211156153a9575f80fd5b6153b588838901615023565b935060608701359150808211156153ca575f80fd5b508501601f810187136153db575f80fd5b614f2587823560208401614c44565b60ff60f81b8816815260e060208201525f61540860e0830189614d5e565b828103604084015261541a8189614d5e565b606084018890526001600160a01b038716608085015260a0840186905283810360c08501529050612a5a8185614e6d565b5f806020838503121561545c575f80fd5b82356001600160401b03811115615471575f80fd5b61547d85828601614d9b565b90969095509350505050565b5f805f6060848603121561549b575f80fd5b6154a484614eb8565b92506020840135915060408401356001600160401b038111156154c5575f80fd5b6154d186828701614c7f565b9150509250925092565b5f805f80606085870312156154ee575f80fd5b6154f785614eb8565b935060208501356001600160401b0380821115615512575f80fd5b908601906101408289031215615526575f80fd5b9093506040860135908082111561553b575f80fd5b506152e987828801614b6d565b5f805f6040848603121561555a575f80fd5b61556384614eb8565b925060208401356001600160401b0381111561557d575f80fd5b61558986828701614b6d565b9497909650939450505050565b5f805f805f60a086880312156155aa575f80fd5b6155b386614eb8565b94506155c160208701614eb8565b935060408601356001600160401b03808211156155dc575f80fd5b6155e889838a01614fcb565b945060608801359150808211156155fd575f80fd5b61560989838a01614fcb565b93506080880135915080821115615275575f80fd5b5f805f8060608587031215615631575f80fd5b61563a85614eb8565b93506020850135925060408501356001600160401b03811115615332575f80fd5b5f805f805f60a0868803121561566f575f80fd5b61567886614eb8565b945061568660208701614eb8565b9350604086013592506060860135915060808601356001600160401b038111156156ae575f80fd5b61528288828901614c7f565b600181811c908216806156ce57607f821691505b6020821081036156ec57634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffd5b5f823561013e1983360301811261571b575f80fd5b9190910192915050565b5f808335601e1984360301811261573a575f80fd5b8301803591506001600160401b03821115615753575f80fd5b602001915036819003821315614baa575f80fd5b634e487b7160e01b5f52601160045260245ffd5b5f6001820161578c5761578c615767565b5060010190565b5f602082840312156157a3575f80fd5b81516001600160401b038111156157b8575f80fd5b8201601f810184136157c8575f80fd5b80516157d6614c5182614c1e565b8181528560208385010111156157ea575f80fd5b612d9b826020830160208601614d3c565b5f6020828403121561580b575f80fd5b5051919050565b8181038181111561126e5761126e615767565b5f60208284031215615835575f80fd5b611c2b82614b5d565b5f6020828403121561584e575f80fd5b815165ffffffffffff81168114611c2b575f80fd5b80356002811061154b575f80fd5b5f60208284031215615881575f80fd5b611c2b82615863565b5f610140823603121561589b575f80fd5b6158a3614bc5565b6158ac83614eb8565b81526020830135602082015260408301356001600160401b038111156158d0575f80fd5b6158dc36828601614c7f565b6040830152506158ee60608401615863565b60608201526080830135608082015260a083013560a082015260c083013560c082015261591d60e08401614eb8565b60e0820152610100615930818501614eb8565b9082015261012092830135928101929092525090565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b868152608060208201525f615987608083018789615946565b828103604084015261599a818688615946565b915050826060830152979650505050505050565b600281106159be576159be61519b565b9052565b6001600160a01b038a81168252602082018a9052610140604083018190525f838201526101608301916159f8606085018c6159ae565b60808401999099525060a082019690965260c081019490945291851660e084015290931661010082015261012001919091529392505050565b848152608060208201525f608082015260a060408201525f615a5760a083018587615946565b905082606083015295945050505050565b5f8151808452602080850194508084015f5b83811015614e9b5781516001600160a01b031687529582019590820190600101615a7a565b5f81518084526020808501808196508360051b810191508286015f5b85811015615ae5578284038952615ad3848351614d5e565b98850198935090840190600101615abb565b5091979650505050505050565b608081525f615b046080830187615a68565b8281036020840152615b168187614e6d565b90508281036040840152615b2a8186615a9f565b91505082606083015295945050505050565b808202811582820484141761126e5761126e615767565b634e487b7160e01b5f52601260045260245ffd5b5f82615b8157634e487b7160e01b5f52601260045260245ffd5b500490565b818382375f9101908152919050565b5f6001600160801b03808316818103615bb057615bb0615767565b6001019392505050565b5f825161571b818460208701614d3c565b8082018082111561126e5761126e615767565b6001600160a01b038b81168252602082018b9052610140604083018190525f91615c0a8483018d614d5e565b9250615c19606085018c6159ae565b60808401999099525060a082019690965260c081019490945291851660e08401529093166101008201526101200191909152949350505050565b84815260ff84166020820152826040820152608060608201525f610f046080830184614d5e565b85815260ff8516602082015283604082015260a060608201525f615ca160a0830185614d5e565b8281036080840152615cb38185614d5e565b98975050505050505050565b60208082526021908201527f476f7665726e6f723a20696e76616c69642070726f706f73616c206c656e67746040820152600d60fb1b606082015260800190565b5f6101208b8352602060018060a01b038c1681850152816040850152615d288285018c615a68565b91508382036060850152615d3c828b614e6d565b915083820360808501528189518084528284019150828160051b850101838c015f5b83811015615d8c57601f19878403018552615d7a838351614d5e565b94860194925090850190600101615d5e565b505086810360a0880152615da0818c615a9f565b9450505050508560c08401528460e0840152828103610100840152615dc58185614d5e565b9c9b505050505050505050505050565b60208082526034908201527f476f7665726e6f72436f756e74696e674672616374696f6e616c3a20766f7465604082015273081ddbdd5b1908195e18d95959081dd95a59da1d60621b606082015260800190565b6001600160801b03818116838216019080821115615e4957615e49615767565b509291505056fe476f7665726e6f723a2063616c6c20726576657274656420776974686f7574206d657373616765737570706f72743d627261766f2671756f72756d3d616761696e73742c6162737461696e2671756f72756d3d666f722c6162737461696e26706172616d733d6672616374696f6e616ca2646970667358221220af80f8a495daf41067f05498bcb0a99923f9476d7d24e3147f7c56cadbe78bc564736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000180000000000000000000000000961d4921e1718e633bac8ded88c4a1cae44b785a000000000000000000000000961d4921e1718e633bac8ded88c4a1cae44b785a00000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000fbaa992a9e04e6a4fd1ba52d49c9c12baa0da3c6000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000078ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000005f0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000005f000000000000000000000000000000000000000000000000000000000000001146726178476f7665726e6f724f6d6567610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000fbaa992a9e04e6a4fd1ba52d49c9c12baa0da3c60000000000000000000000007a8a1e6966ac5b67aca3c9308fa798bb56ecac3800000000000000000000000000000000000000000000000000000000000000010000000000000000000000008adb68e26b725af5e4b9c7deefe53d7edaaeec87
-----Decoded View---------------
Arg [0] : params (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
-----Encoded View---------------
20 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000180
Arg [2] : 000000000000000000000000961d4921e1718e633bac8ded88c4a1cae44b785a
Arg [3] : 000000000000000000000000961d4921e1718e633bac8ded88c4a1cae44b785a
Arg [4] : 00000000000000000000000000000000000000000000000000000000000001c0
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000220
Arg [6] : 000000000000000000000000fbaa992a9e04e6a4fd1ba52d49c9c12baa0da3c6
Arg [7] : 000000000000000000000000000000000000000000000000000000000000003c
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000078
Arg [9] : ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Arg [10] : 000000000000000000000000000000000000000000000000000000000000005f
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [12] : 000000000000000000000000000000000000000000000000000000000000005f
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000011
Arg [14] : 46726178476f7665726e6f724f6d656761000000000000000000000000000000
Arg [15] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [16] : 000000000000000000000000fbaa992a9e04e6a4fd1ba52d49c9c12baa0da3c6
Arg [17] : 0000000000000000000000007a8a1e6966ac5b67aca3c9308fa798bb56ecac38
Arg [18] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [19] : 0000000000000000000000008adb68e26b725af5e4b9c7deefe53d7edaaeec87
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
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.