Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 11 from a total of 11 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Sub Delegate | 17131489 | 650 days ago | IN | 0 ETH | 0.00276322 | ||||
Sub Delegate | 17125814 | 651 days ago | IN | 0 ETH | 0.00297294 | ||||
Sub Delegate | 17125454 | 651 days ago | IN | 0 ETH | 0.00195454 | ||||
Sub Delegate | 17118239 | 652 days ago | IN | 0 ETH | 0.01899599 | ||||
Sub Delegate | 17078648 | 657 days ago | IN | 0 ETH | 0.01412856 | ||||
Sub Delegate | 17068396 | 659 days ago | IN | 0 ETH | 0.00961045 | ||||
Sub Delegate | 17048804 | 662 days ago | IN | 0 ETH | 0.00148381 | ||||
Sub Delegate | 17031774 | 664 days ago | IN | 0 ETH | 0.00611573 | ||||
Create | 16936344 | 678 days ago | IN | 0 ETH | 0.02011652 | ||||
Create | 16801196 | 697 days ago | IN | 0 ETH | 0.02506945 | ||||
Transfer Ownersh... | 16801105 | 697 days ago | IN | 0 ETH | 0.00114424 |
Latest 6 internal transactions
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
17118239 | 652 days ago | Contract Creation | 0 ETH | |||
17097994 | 655 days ago | Contract Creation | 0 ETH | |||
17078648 | 657 days ago | Contract Creation | 0 ETH | |||
17068396 | 659 days ago | Contract Creation | 0 ETH | |||
17031774 | 664 days ago | Contract Creation | 0 ETH | |||
16801196 | 697 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
Alligator
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; import {Proxy} from "./Proxy.sol"; import {ENSHelper} from "./utils/ENSHelper.sol"; import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import {INounsDAOV2} from "./interfaces/INounsDAOV2.sol"; import {IRule} from "./interfaces/IRule.sol"; import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {Pausable} from "@openzeppelin/contracts/security/Pausable.sol"; import "./interfaces/IAlligator.sol"; contract Alligator is IAlligator, ENSHelper, Ownable, Pausable { // ============================================================= // ERRORS // ============================================================= error BadSignature(); error NotDelegated(address from, address to, uint256 requiredPermissions); error TooManyRedelegations(address from, address to); error NotValidYet(address from, address to, uint256 willBeValidFrom); error NotValidAnymore(address from, address to, uint256 wasValidUntil); error TooEarly(address from, address to, uint256 blocksBeforeVoteCloses); error InvalidCustomRule(address from, address to, address customRule); // ============================================================= // IMMUTABLE STORAGE // ============================================================= INounsDAOV2 public immutable governor; uint8 internal constant PERMISSION_VOTE = 1; uint8 internal constant PERMISSION_SIGN = 1 << 1; uint8 internal constant PERMISSION_PROPOSE = 1 << 2; bytes32 internal constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)"); bytes32 internal constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)"); /// @notice The maximum priority fee used to cap gas refunds in `castRefundableVote` uint256 public constant MAX_REFUND_PRIORITY_FEE = 2 gwei; /// @notice The vote refund gas overhead, including 7K for ETH transfer and 29K for general transaction overhead uint256 public constant REFUND_BASE_GAS = 36000; /// @notice The maximum gas units the DAO will refund voters on; supports about 9,190 characters uint256 public constant MAX_REFUND_GAS_USED = 200_000; /// @notice The maximum basefee the DAO will refund voters on uint256 public constant MAX_REFUND_BASE_FEE = 200 gwei; // ============================================================= // MUTABLE STORAGE // ============================================================= // From => To => Rules mapping(address => mapping(address => Rules)) public subDelegations; // Proxy address => hash => valid boolean mapping(address => mapping(bytes32 => bool)) internal validSignatures; // ============================================================= // CONSTRUCTOR // ============================================================= constructor(INounsDAOV2 _governor, string memory _ensName, bytes32 _ensNameHash) ENSHelper(_ensName, _ensNameHash) { governor = _governor; } // ============================================================= // WRITE FUNCTIONS // ============================================================= /** * @notice Deploy a new Proxy for an owner deterministically. * * @param owner The owner of the Proxy. * @param registerEnsName Whether to register the ENS name for the Proxy. * * @return endpoint Address of the Proxy */ function create(address owner, bool registerEnsName) public returns (address endpoint) { endpoint = address(new Proxy{salt: bytes32(uint256(uint160(owner)))}(address(governor))); emit ProxyDeployed(owner, endpoint); if (registerEnsName) { if (ensNameHash != 0) { string memory reverseName = registerDeployment(endpoint); Proxy(payable(endpoint)).setENSReverseRecord(reverseName); } } } /** * @notice Register ENS name for an already deployed Proxy. * * @param owner The owner of the Proxy. * * @dev Reverts if the ENS name is already set. */ function registerProxyDeployment(address owner) public { if (ensNameHash != 0) { address proxy = proxyAddress(owner); string memory reverseName = registerDeployment(proxy); Proxy(payable(proxy)).setENSReverseRecord(reverseName); } } /** * @notice Validate subdelegation rules and make a proposal to the governor. * * @param authority The authority chain to validate against. * @param targets Target addresses for proposal calls * @param values Eth values for proposal calls * @param signatures Function signatures for proposal calls * @param calldatas Calldatas for proposal calls * @param description String description of the proposal * * @return proposalId Proposal id of new proposal */ function propose( address[] calldata authority, address[] calldata targets, uint256[] calldata values, string[] calldata signatures, bytes[] calldata calldatas, string calldata description ) external whenNotPaused returns (uint256 proposalId) { address proxy = proxyAddress(authority[0]); // Create a proposal first so the custom rules can validate it proposalId = INounsDAOV2(proxy).propose(targets, values, signatures, calldatas, description); validate(msg.sender, authority, PERMISSION_PROPOSE, proposalId, 0xFF); } /** * @notice Validate subdelegation rules and cast a vote on the governor. * * @param authority The authority chain to validate against. * @param proposalId The id of the proposal to vote on * @param support The support value for the vote. 0=against, 1=for, 2=abstain */ function castVote(address[] calldata authority, uint256 proposalId, uint8 support) external whenNotPaused { validate(msg.sender, authority, PERMISSION_VOTE, proposalId, support); address proxy = proxyAddress(authority[0]); INounsDAOV2(proxy).castVote(proposalId, support); emit VoteCast(proxy, msg.sender, authority, proposalId, support); } /** * @notice Validate subdelegation rules and cast a vote with reason on the governor. * * @param authority The authority chain to validate against. * @param proposalId The id of the proposal to vote on * @param support The support value for the vote. 0=against, 1=for, 2=abstain * @param reason The reason given for the vote by the voter */ function castVoteWithReason( address[] calldata authority, uint256 proposalId, uint8 support, string calldata reason ) public whenNotPaused { validate(msg.sender, authority, PERMISSION_VOTE, proposalId, support); address proxy = proxyAddress(authority[0]); INounsDAOV2(proxy).castVoteWithReason(proposalId, support, reason); emit VoteCast(proxy, msg.sender, authority, proposalId, support); } /** * @notice Validate subdelegation rules and cast multiple votes with reason on the governor. * * @param authorities The authority chains to validate against. * @param proposalId The id of the proposal to vote on * @param support The support value for the vote. 0=against, 1=for, 2=abstain * @param reason The reason given for the vote by the voter */ function castVotesWithReasonBatched( address[][] calldata authorities, uint256 proposalId, uint8 support, string calldata reason ) public whenNotPaused { address[] memory proxies = new address[](authorities.length); address[] memory authority; for (uint256 i; i < authorities.length; ) { authority = authorities[i]; validate(msg.sender, authority, PERMISSION_VOTE, proposalId, support); proxies[i] = proxyAddress(authority[0]); INounsDAOV2(proxies[i]).castVoteWithReason(proposalId, support, reason); unchecked { ++i; } } emit VotesCast(proxies, msg.sender, authorities, proposalId, support); } /** * @notice Validate subdelegation rules and cast multiple votes with reason on the governor. * Refunds the gas used to cast the votes, if possible. * * @param authorities The authority chains to validate against. * @param proposalId The id of the proposal to vote on * @param support The support value for the vote. 0=against, 1=for, 2=abstain * @param reason The reason given for the vote by the voter */ function castRefundableVotesWithReasonBatched( address[][] calldata authorities, uint256 proposalId, uint8 support, string calldata reason ) external whenNotPaused { uint256 startGas = gasleft(); castVotesWithReasonBatched(authorities, proposalId, support, reason); _refundGas(startGas); } /** * @notice Validate subdelegation rules and cast a vote by signature on the governor. * * @param authority The authority chain to validate against. * @param proposalId The id of the proposal to vote on * @param support The support value for the vote. 0=against, 1=for, 2=abstain */ function castVoteBySig( address[] calldata authority, uint256 proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s ) external whenNotPaused { bytes32 domainSeparator = keccak256( abi.encode(DOMAIN_TYPEHASH, keccak256("Alligator"), block.chainid, address(this)) ); bytes32 structHash = keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support)); bytes32 digest = keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); address signatory = ecrecover(digest, v, r, s); if (signatory == address(0)) { revert BadSignature(); } validate(signatory, authority, PERMISSION_VOTE, proposalId, support); address proxy = proxyAddress(authority[0]); INounsDAOV2(proxy).castVote(proposalId, support); emit VoteCast(proxy, signatory, authority, proposalId, support); } /** * @notice Validate subdelegation rules and sign a hash. * * @param authority The authority chain to validate against. * @param hash The hash to sign. */ function sign(address[] calldata authority, bytes32 hash) external whenNotPaused { validate(msg.sender, authority, PERMISSION_SIGN, 0, 0xFE); address proxy = proxyAddress(authority[0]); validSignatures[proxy][hash] = true; emit Signed(proxy, authority, hash); } /** * @notice Subdelegate an address with rules. * * @param to The address to subdelegate to. * @param rules The rules to apply to the subdelegation. * @param createProxy Whether to create a Proxy for the sender, if one doesn't exist. */ function subDelegate(address to, Rules calldata rules, bool createProxy) external { if (createProxy) { if (proxyAddress(msg.sender).code.length == 0) { create(msg.sender, false); } } subDelegations[msg.sender][to] = rules; emit SubDelegation(msg.sender, to, rules); } /** * @notice Subdelegate multiple addresses with rules. * * @param targets The addresses to subdelegate to. * @param rules The rules to apply to the subdelegations. * @param createProxy Whether to create a Proxy for the sender, if one doesn't exist. */ function subDelegateBatched(address[] calldata targets, Rules[] calldata rules, bool createProxy) external { require(targets.length == rules.length); if (createProxy) { if (proxyAddress(msg.sender).code.length == 0) { create(msg.sender, false); } } for (uint256 i; i < targets.length; ) { subDelegations[msg.sender][targets[i]] = rules[i]; unchecked { ++i; } } emit SubDelegations(msg.sender, targets, rules); } /** * @notice Pauses and unpauses propose, vote and sign operations. * * @dev Only contract owner can toggle pause. */ function _togglePause() external onlyOwner { if (!paused()) { _pause(); } else { _unpause(); } } // Refill Alligator's balance for gas refunds receive() external payable {} // ============================================================= // VIEW FUNCTIONS // ============================================================= /** * @notice Validate subdelegation rules. * * @param sender The sender address to validate. * @param authority The authority chain to validate against. * @param permissions The permissions to validate. * @param proposalId The id of the proposal for which validation is being performed. * @param support The support value for the vote. 0=against, 1=for, 2=abstain, 0xFF=proposal */ function validate( address sender, address[] memory authority, uint256 permissions, uint256 proposalId, uint256 support ) public view { address from = authority[0]; if (from == sender) { return; } uint256 authorityLength = authority.length; address to; Rules memory rules; /// @dev maxRedelegations would hit block size limit before overflowing /// @dev block.number + rules.blocksBeforeVoteCloses fits in uint256 unchecked { for (uint256 i = 1; i < authorityLength; ++i) { to = authority[i]; rules = subDelegations[from][to]; if ((rules.permissions & permissions) != permissions) { revert NotDelegated(from, to, permissions); } if (rules.maxRedelegations + i + 1 < authorityLength) { revert TooManyRedelegations(from, to); } if (block.timestamp < rules.notValidBefore) { revert NotValidYet(from, to, rules.notValidBefore); } if (rules.notValidAfter != 0) { if (block.timestamp > rules.notValidAfter) revert NotValidAnymore(from, to, rules.notValidAfter); } if (rules.blocksBeforeVoteCloses != 0) { INounsDAOV2.ProposalCondensed memory proposal = governor.proposals(proposalId); if (proposal.endBlock > block.number + rules.blocksBeforeVoteCloses) { revert TooEarly(from, to, rules.blocksBeforeVoteCloses); } } if (rules.customRule != address(0)) { if ( IRule(rules.customRule).validate(address(governor), sender, proposalId, uint8(support)) != IRule.validate.selector ) { revert InvalidCustomRule(from, to, rules.customRule); } } from = to; } } if (from == sender) { return; } revert NotDelegated(from, sender, permissions); } /** * @notice Checks if proxy signature is valid. * * @param proxy The address of the proxy contract. * @param hash The hash to validate. * @param data The data to validate. * * @return magicValue `IERC1271.isValidSignature` if signature is valid, or 0 if not. */ function isValidProxySignature( address proxy, bytes32 hash, bytes calldata data ) public view returns (bytes4 magicValue) { if (data.length > 0) { (address[] memory authority, bytes memory signature) = abi.decode(data, (address[], bytes)); address signer = ECDSA.recover(hash, signature); validate(signer, authority, PERMISSION_SIGN, 0, 0xFE); return IERC1271.isValidSignature.selector; } return validSignatures[proxy][hash] ? IERC1271.isValidSignature.selector : bytes4(0); } /** * @notice Returns the address of the proxy contract for a given owner * * @param owner The owner of the Proxy. * * @return endpoint The address of the Proxy. */ function proxyAddress(address owner) public view returns (address endpoint) { endpoint = address( uint160( uint256( keccak256( abi.encodePacked( bytes1(0xff), address(this), bytes32(uint256(uint160(owner))), // salt keccak256(abi.encodePacked(type(Proxy).creationCode, abi.encode(address(governor)))) ) ) ) ) ); } // ============================================================= // INTERNAL FUNCTIONS // ============================================================= function _refundGas(uint256 startGas) internal { unchecked { uint256 balance = address(this).balance; if (balance == 0) { return; } uint256 basefee = min(block.basefee, MAX_REFUND_BASE_FEE); uint256 gasPrice = min(tx.gasprice, basefee + MAX_REFUND_PRIORITY_FEE); uint256 gasUsed = min(startGas - gasleft() + REFUND_BASE_GAS, MAX_REFUND_GAS_USED); uint256 refundAmount = min(gasPrice * gasUsed, balance); (bool refundSent, ) = msg.sender.call{value: refundAmount}(""); emit RefundableVote(msg.sender, refundAmount, refundSent); } } function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } }
pragma solidity >=0.8.4; interface ENS { // Logged when the owner of a node assigns a new owner to a subnode. event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner); // Logged when the owner of a node transfers ownership to a new account. event Transfer(bytes32 indexed node, address owner); // Logged when the resolver for a node changes. event NewResolver(bytes32 indexed node, address resolver); // Logged when the TTL of a node changes event NewTTL(bytes32 indexed node, uint64 ttl); // Logged when an operator is added or removed. event ApprovalForAll( address indexed owner, address indexed operator, bool approved ); function setRecord( bytes32 node, address owner, address resolver, uint64 ttl ) external; function setSubnodeRecord( bytes32 node, bytes32 label, address owner, address resolver, uint64 ttl ) external; function setSubnodeOwner( bytes32 node, bytes32 label, address owner ) external returns (bytes32); function setResolver(bytes32 node, address resolver) external; function setOwner(bytes32 node, address owner) external; function setTTL(bytes32 node, uint64 ttl) external; function setApprovalForAll(address operator, bool approved) external; function owner(bytes32 node) external view returns (address); function resolver(bytes32 node) external view returns (address); function ttl(bytes32 node) external view returns (uint64); function recordExists(bytes32 node) external view returns (bool); function isApprovedForAll( address owner, address operator ) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; /** * Interface for the legacy (ETH-only) addr function. */ interface IAddrResolver { event AddrChanged(bytes32 indexed node, address a); /** * Returns the address associated with an ENS node. * @param node The ENS node to query. * @return The associated address. */ function addr(bytes32 node) external view returns (address payable); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC1271 standard signature validation method for * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271]. * * _Available since v4.1._ */ interface IERC1271 { /** * @dev Should return whether the signature provided is valid for the provided data * @param hash Hash of the data to be signed * @param signature Signature byte array associated with _data */ function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// 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.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.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 `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); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.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) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @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) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } }
// 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.8.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) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 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 10, 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 * 8) < value ? 1 : 0); } } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; import {IAlligator} from "./interfaces/IAlligator.sol"; import {IENSReverseRegistrar} from "./interfaces/IENSReverseRegistrar.sol"; import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol"; contract Proxy is IERC1271 { address internal immutable alligator; address internal immutable governor; constructor(address _governor) { alligator = msg.sender; governor = _governor; } function isValidSignature(bytes32 hash, bytes calldata signature) external view override returns (bytes4) { return IAlligator(alligator).isValidProxySignature(address(this), hash, signature); } function setENSReverseRecord(string calldata name) external { require(msg.sender == alligator); IENSReverseRegistrar(0x084b1c3C81545d370f3634392De611CaaBFf8148).setName(name); } fallback() external payable { require(msg.sender == alligator); address addr = governor; assembly { calldatacopy(0, 0, calldatasize()) let result := call(gas(), addr, callvalue(), 0, calldatasize(), 0, 0) returndatacopy(0, 0, returndatasize()) switch result case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } // `receive` is omitted to minimize contract size }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; import "../structs/Rules.sol"; interface IAlligator { // ============================================================= // EVENTS // ============================================================= event ProxyDeployed(address indexed owner, address proxy); event SubDelegation(address indexed from, address indexed to, Rules rules); event SubDelegations(address indexed from, address[] to, Rules[] rules); event VoteCast( address indexed proxy, address indexed voter, address[] authority, uint256 proposalId, uint8 support ); event VotesCast( address[] proxies, address indexed voter, address[][] authorities, uint256 proposalId, uint8 support ); event Signed(address indexed proxy, address[] authority, bytes32 messageHash); event RefundableVote(address indexed voter, uint256 refundAmount, bool refundSent); // ============================================================= // WRITE FUNCTIONS // ============================================================= function create(address owner, bool registerEnsName) external returns (address endpoint); function registerProxyDeployment(address owner) external; function propose( address[] calldata authority, address[] calldata targets, uint256[] calldata values, string[] calldata signatures, bytes[] calldata calldatas, string calldata description ) external returns (uint256 proposalId); function castVote(address[] calldata authority, uint256 proposalId, uint8 support) external; function castVoteWithReason( address[] calldata authority, uint256 proposalId, uint8 support, string calldata reason ) external; function castVotesWithReasonBatched( address[][] calldata authorities, uint256 proposalId, uint8 support, string calldata reason ) external; function castRefundableVotesWithReasonBatched( address[][] calldata authorities, uint256 proposalId, uint8 support, string calldata reason ) external; function castVoteBySig( address[] calldata authority, uint256 proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s ) external; function sign(address[] calldata authority, bytes32 hash) external; function subDelegate(address to, Rules calldata rules, bool createProxy) external; function subDelegateBatched(address[] calldata targets, Rules[] calldata rules, bool createProxy) external; function _togglePause() external; // // ============================================================= // // VIEW FUNCTIONS // // ============================================================= function validate( address sender, address[] memory authority, uint256 permissions, uint256 proposalId, uint256 support ) external view; function isValidProxySignature( address proxy, bytes32 hash, bytes calldata data ) external view returns (bytes4 magicValue); function proxyAddress(address owner) external view returns (address endpoint); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; interface IENSReverseRegistrar { function setName(string memory name) external returns (bytes32 node); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; interface IGovernorBravo { function quorumVotes() external view returns (uint256); function votingDelay() external view returns (uint256); function votingPeriod() external view returns (uint256); function propose( address[] memory targets, uint256[] memory values, string[] memory signatures, bytes[] memory calldatas, string memory description ) external returns (uint256); function castVote(uint256 proposalId, uint8 support) external; function queue(uint256 proposalId) external; function execute(uint256 proposalId) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; import {IGovernorBravo} from "./IGovernorBravo.sol"; interface INounsDAOV2 is IGovernorBravo { struct ProposalCondensed { /// @notice Unique id for looking up a proposal uint256 id; /// @notice Creator of the proposal address proposer; /// @notice The number of votes needed to create a proposal at the time of proposal creation. *DIFFERS from GovernerBravo uint256 proposalThreshold; /// @notice The minimum number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed at the time of proposal creation. *DIFFERS from GovernerBravo uint256 quorumVotes; /// @notice The timestamp that the proposal will be available for execution, set once the vote succeeds uint256 eta; /// @notice The block at which voting begins: holders must delegate their votes prior to this block uint256 startBlock; /// @notice The block at which voting ends: votes must be cast prior to this block uint256 endBlock; /// @notice Current number of votes in favor of this proposal uint256 forVotes; /// @notice Current number of votes in opposition to this proposal uint256 againstVotes; /// @notice Current number of votes for abstaining for this proposal uint256 abstainVotes; /// @notice Flag marking whether the proposal has been canceled bool canceled; /// @notice Flag marking whether the proposal has been vetoed bool vetoed; /// @notice Flag marking whether the proposal has been executed bool executed; /// @notice The total supply at the time of proposal creation uint256 totalSupply; /// @notice The block at which this proposal was created uint256 creationBlock; } function castRefundableVote(uint256 proposalId, uint8 support) external; function castRefundableVoteWithReason(uint256 proposalId, uint8 support, string calldata reason) external; function castVoteWithReason(uint256 proposalId, uint8 support, string calldata reason) external; function castVoteBySig(uint256 proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s) external; function proposals(uint256 proposalId) external view returns (ProposalCondensed memory); function getActions( uint256 proposalId ) external view returns ( address[] memory targets, uint256[] memory values, string[] memory signatures, bytes[] memory calldatas ); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; interface IRule { /** * @notice A custom rule that validates that the voter can cast a vote or propose a proposal * @param governor The address of the GovernorBravo contract * @param voter The final delegatee that's casting the vote * @param proposalId The id of the proposal to vote on * @param support The support value for the vote. 0=against, 1=for, 2=abstain, 0xff=propose * @return IRule.validate.selector */ function validate( address governor, address voter, uint256 proposalId, uint8 support ) external view returns (bytes4); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; struct Rules { uint8 permissions; uint8 maxRedelegations; uint32 notValidBefore; uint32 notValidAfter; uint16 blocksBeforeVoteCloses; address customRule; }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import {IAddrResolver} from "ens-contracts/resolvers/profiles/IAddrResolver.sol"; import {ENS} from "ens-contracts/registry/ENS.sol"; contract ENSHelper is IERC165, IAddrResolver { error AlreadyRegistered(); string public ensName; bytes32 internal immutable ensNameHash; uint256 internal numberOfProxiesDeployed; mapping(bytes32 => address) public nodehashToAddress; mapping(address => bool) public registeredProxyAddresses; constructor(string memory _ensName, bytes32 _ensNameHash) { ensNameHash = _ensNameHash; ensName = _ensName; } function registerDeployment(address _addr) internal returns (string memory reverseENSName) { if (registeredProxyAddresses[_addr]) { revert AlreadyRegistered(); } /// @dev Cannot overflow uint256 counter by incrementing 1 at a time unchecked { ++numberOfProxiesDeployed; } string memory subdomain = Strings.toString(numberOfProxiesDeployed); reverseENSName = string.concat(subdomain, ".", ensName); bytes32 label = keccak256(abi.encodePacked(subdomain)); bytes32 namehash = keccak256(abi.encodePacked(ensNameHash, label)); nodehashToAddress[namehash] = _addr; registeredProxyAddresses[_addr] = true; ENS(0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e).setSubnodeRecord( ensNameHash, label, address(this), address(this), 0 ); } function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAddrResolver).interfaceId || interfaceId == type(IERC165).interfaceId; } function addr(bytes32 node) public view virtual override returns (address payable) { return payable(nodehashToAddress[node]); } }
{ "remappings": [ "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "base64-sol/=lib/base64/", "base64/=lib/base64/", "ds-test/=lib/forge-std/lib/ds-test/src/", "ens-contracts/=lib/ens-contracts/contracts/", "forge-std/=lib/forge-std/src/", "noun-contracts/=lib/nouns-monorepo/packages/nouns-contracts/contracts/", "nouns-monorepo/=lib/nouns-monorepo/", "openzeppelin-contracts/=lib/openzeppelin-contracts/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract INounsDAOV2","name":"_governor","type":"address"},{"internalType":"string","name":"_ensName","type":"string"},{"internalType":"bytes32","name":"_ensNameHash","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyRegistered","type":"error"},{"inputs":[],"name":"BadSignature","type":"error"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"customRule","type":"address"}],"name":"InvalidCustomRule","type":"error"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"requiredPermissions","type":"uint256"}],"name":"NotDelegated","type":"error"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"wasValidUntil","type":"uint256"}],"name":"NotValidAnymore","type":"error"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"willBeValidFrom","type":"uint256"}],"name":"NotValidYet","type":"error"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"blocksBeforeVoteCloses","type":"uint256"}],"name":"TooEarly","type":"error"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"TooManyRedelegations","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"address","name":"a","type":"address"}],"name":"AddrChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"proxy","type":"address"}],"name":"ProxyDeployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"uint256","name":"refundAmount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"refundSent","type":"bool"}],"name":"RefundableVote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"proxy","type":"address"},{"indexed":false,"internalType":"address[]","name":"authority","type":"address[]"},{"indexed":false,"internalType":"bytes32","name":"messageHash","type":"bytes32"}],"name":"Signed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"components":[{"internalType":"uint8","name":"permissions","type":"uint8"},{"internalType":"uint8","name":"maxRedelegations","type":"uint8"},{"internalType":"uint32","name":"notValidBefore","type":"uint32"},{"internalType":"uint32","name":"notValidAfter","type":"uint32"},{"internalType":"uint16","name":"blocksBeforeVoteCloses","type":"uint16"},{"internalType":"address","name":"customRule","type":"address"}],"indexed":false,"internalType":"struct Rules","name":"rules","type":"tuple"}],"name":"SubDelegation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address[]","name":"to","type":"address[]"},{"components":[{"internalType":"uint8","name":"permissions","type":"uint8"},{"internalType":"uint8","name":"maxRedelegations","type":"uint8"},{"internalType":"uint32","name":"notValidBefore","type":"uint32"},{"internalType":"uint32","name":"notValidAfter","type":"uint32"},{"internalType":"uint16","name":"blocksBeforeVoteCloses","type":"uint16"},{"internalType":"address","name":"customRule","type":"address"}],"indexed":false,"internalType":"struct Rules[]","name":"rules","type":"tuple[]"}],"name":"SubDelegations","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"proxy","type":"address"},{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"address[]","name":"authority","type":"address[]"},{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"support","type":"uint8"}],"name":"VoteCast","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"proxies","type":"address[]"},{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"address[][]","name":"authorities","type":"address[][]"},{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"support","type":"uint8"}],"name":"VotesCast","type":"event"},{"inputs":[],"name":"MAX_REFUND_BASE_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_REFUND_GAS_USED","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_REFUND_PRIORITY_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REFUND_BASE_GAS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_togglePause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"addr","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[][]","name":"authorities","type":"address[][]"},{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"string","name":"reason","type":"string"}],"name":"castRefundableVotesWithReasonBatched","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"authority","type":"address[]"},{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"}],"name":"castVote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"authority","type":"address[]"},{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"castVoteBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"authority","type":"address[]"},{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"string","name":"reason","type":"string"}],"name":"castVoteWithReason","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[][]","name":"authorities","type":"address[][]"},{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"string","name":"reason","type":"string"}],"name":"castVotesWithReasonBatched","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"bool","name":"registerEnsName","type":"bool"}],"name":"create","outputs":[{"internalType":"address","name":"endpoint","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"ensName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governor","outputs":[{"internalType":"contract INounsDAOV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"proxy","type":"address"},{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"isValidProxySignature","outputs":[{"internalType":"bytes4","name":"magicValue","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"nodehashToAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"authority","type":"address[]"},{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"string[]","name":"signatures","type":"string[]"},{"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"internalType":"string","name":"description","type":"string"}],"name":"propose","outputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"proxyAddress","outputs":[{"internalType":"address","name":"endpoint","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"registerProxyDeployment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"registeredProxyAddresses","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"authority","type":"address[]"},{"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"sign","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"components":[{"internalType":"uint8","name":"permissions","type":"uint8"},{"internalType":"uint8","name":"maxRedelegations","type":"uint8"},{"internalType":"uint32","name":"notValidBefore","type":"uint32"},{"internalType":"uint32","name":"notValidAfter","type":"uint32"},{"internalType":"uint16","name":"blocksBeforeVoteCloses","type":"uint16"},{"internalType":"address","name":"customRule","type":"address"}],"internalType":"struct Rules","name":"rules","type":"tuple"},{"internalType":"bool","name":"createProxy","type":"bool"}],"name":"subDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"components":[{"internalType":"uint8","name":"permissions","type":"uint8"},{"internalType":"uint8","name":"maxRedelegations","type":"uint8"},{"internalType":"uint32","name":"notValidBefore","type":"uint32"},{"internalType":"uint32","name":"notValidAfter","type":"uint32"},{"internalType":"uint16","name":"blocksBeforeVoteCloses","type":"uint16"},{"internalType":"address","name":"customRule","type":"address"}],"internalType":"struct Rules[]","name":"rules","type":"tuple[]"},{"internalType":"bool","name":"createProxy","type":"bool"}],"name":"subDelegateBatched","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"subDelegations","outputs":[{"internalType":"uint8","name":"permissions","type":"uint8"},{"internalType":"uint8","name":"maxRedelegations","type":"uint8"},{"internalType":"uint32","name":"notValidBefore","type":"uint32"},{"internalType":"uint32","name":"notValidAfter","type":"uint32"},{"internalType":"uint16","name":"blocksBeforeVoteCloses","type":"uint16"},{"internalType":"address","name":"customRule","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address[]","name":"authority","type":"address[]"},{"internalType":"uint256","name":"permissions","type":"uint256"},{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint256","name":"support","type":"uint256"}],"name":"validate","outputs":[],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60c06040523480156200001157600080fd5b5060405162004065380380620040658339810160408190526200003491620000f3565b60808190528181600062000049838262000281565b50505062000066620000606200008760201b60201c565b6200008b565b50506004805460ff60a01b191690556001600160a01b031660a0526200034d565b3390565b600480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052604160045260246000fd5b6000806000606084860312156200010957600080fd5b83516001600160a01b03811681146200012157600080fd5b602085810151919450906001600160401b03808211156200014157600080fd5b818701915087601f8301126200015657600080fd5b8151818111156200016b576200016b620000dd565b604051601f8201601f19908116603f01168101908382118183101715620001965762000196620000dd565b816040528281528a86848701011115620001af57600080fd5b600093505b82841015620001d35784840186015181850187015292850192620001b4565b6000868483010152809750505050505050604084015190509250925092565b600181811c908216806200020757607f821691505b6020821081036200022857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200027c57600081815260208120601f850160051c81016020861015620002575750805b601f850160051c820191505b81811015620002785782815560010162000263565b5050505b505050565b81516001600160401b038111156200029d576200029d620000dd565b620002b581620002ae8454620001f2565b846200022e565b602080601f831160018114620002ed5760008415620002d45750858301515b600019600386901b1c1916600185901b17855562000278565b600085815260208120601f198616915b828110156200031e57888601518255948401946001909101908401620002fd565b50858210156200033d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a051613cc1620003a4600039600081816102a1015281816108eb01528181610cc601528181610dc60152611ad30152600081816109970152818161172d01528181611dc60152611e620152613cc16000f3fe608060405260043610620001f75760003560e01c80635c975abb116200010b578063bc4cd08411620000a1578063f2fde38b116200006c578063f2fde38b14620006ce578063faa9efe314620006f3578063fbfee8761462000718578063fe5f8fce146200073257600080fd5b8063bc4cd084146200062a578063bd7abaf51462000645578063df827947146200066a578063e2f57fb0146200068f57600080fd5b8063763dc22011620000e2578063763dc22014620005845780638da5cb5b14620005a95780638ef71b8d14620005c9578063b9ffe88e14620005f057600080fd5b80635c975abb1462000526578063715018a61462000547578063730f05b4146200055f57600080fd5b80633b3b57de116200018d5780633dff8de211620001585780633dff8de2146200049f578063405b4c3614620004c45780634ad3822214620004dc578063510e318a146200050157600080fd5b80633b3b57de14620003f45780633b75f7ba146200042e5780633be8ef3f14620004535780633d2d1fa3146200046b57600080fd5b80630c340a2411620001ce5780630c340a24146200028d5780630d6384d014620002dc578063319e909014620003aa578063375d02fa14620003cf57600080fd5b806301ffc9a7146200020457806303a3e6fb146200023e578063042bc3de146200026557600080fd5b36620001ff57005b600080fd5b3480156200021157600080fd5b506200022962000223366004620025e0565b62000757565b60405190151581526020015b60405180910390f35b3480156200024b57600080fd5b50620002636200025d3660046200269b565b6200078f565b005b3480156200027257600080fd5b506200027e62030d4081565b60405190815260200162000235565b3480156200029a57600080fd5b50620002c37f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200162000235565b348015620002e957600080fd5b5062000360620002fb36600462002747565b600560209081526000928352604080842090915290825290205460ff8082169161010081049091169063ffffffff620100008204811691660100000000000081049091169061ffff600160501b820416906001600160a01b03600160601b9091041686565b6040805160ff978816815296909516602087015263ffffffff938416948601949094529116606084015261ffff1660808301526001600160a01b031660a082015260c00162000235565b348015620003b757600080fd5b50620002c3620003c9366004620027a6565b620008da565b348015620003dc57600080fd5b5062000263620003ee366004620028e1565b62000a35565b3480156200040157600080fd5b50620002c36200041336600462002951565b6000908152600260205260409020546001600160a01b031690565b3480156200043b57600080fd5b50620002636200044d3660046200296b565b62000f0e565b3480156200046057600080fd5b506200027e618ca081565b3480156200047857600080fd5b50620002296200048a366004620029cf565b60036020526000908152604090205460ff1681565b348015620004ac57600080fd5b5062000263620004be3660046200269b565b6200103d565b348015620004d157600080fd5b506200026362001255565b348015620004e957600080fd5b5062000263620004fb366004620029ef565b62001287565b3480156200050e57600080fd5b50620002636200052036600462002a7c565b62001552565b3480156200053357600080fd5b50600454600160a01b900460ff1662000229565b3480156200055457600080fd5b50620002636200160b565b3480156200056c57600080fd5b506200027e6200057e36600462002ad8565b62001621565b3480156200059157600080fd5b5062000263620005a3366004620029cf565b6200172b565b348015620005b657600080fd5b506004546001600160a01b0316620002c3565b348015620005d657600080fd5b50620005e1620017d9565b60405162000235919062002c4e565b348015620005fd57600080fd5b50620002c36200060f36600462002951565b6002602052600090815260409020546001600160a01b031681565b3480156200063757600080fd5b506200027e642e90edd00081565b3480156200065257600080fd5b5062000263620006643660046200269b565b6200186f565b3480156200067757600080fd5b50620002636200068936600462002c83565b62001899565b3480156200069c57600080fd5b50620006b4620006ae36600462002cd2565b62001979565b6040516001600160e01b0319909116815260200162000235565b348015620006db57600080fd5b5062000263620006ed366004620029cf565b62001a15565b3480156200070057600080fd5b50620002c362000712366004620029cf565b62001a91565b3480156200072557600080fd5b506200027e637735940081565b3480156200073f57600080fd5b50620002636200075136600462002d33565b62001b9d565b60006001600160e01b03198216631d9dabef60e11b14806200078957506001600160e01b031982166301ffc9a760e01b145b92915050565b6200079962001cc7565b620007e033878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250600192508991505060ff881662000a35565b60006200081387876000818110620007fc57620007fc62002ded565b9050602002016020810190620007129190620029cf565b604051637b3c71d360e01b81529091506001600160a01b03821690637b3c71d3906200084a90889088908890889060040162002e2c565b600060405180830381600087803b1580156200086557600080fd5b505af11580156200087a573d6000803e3d6000fd5b50505050336001600160a01b0316816001600160a01b03167f06ef67f52c465c176e4d3ee623ffe1051cdb317e1604d4726aa8b6b332236d5b89898989604051620008c9949392919062002ea8565b60405180910390a350505050505050565b6000826001600160a01b031660001b7f00000000000000000000000000000000000000000000000000000000000000006040516200091890620025bb565b6001600160a01b0390911681526020018190604051809103906000f590508015801562000949573d6000803e3d6000fd5b506040516001600160a01b038083168252919250908416907f3d2489efb661e8b1c3679865db649ca1de61d76a71184a1234de2e55786a6aad9060200160405180910390a2811562000789577f00000000000000000000000000000000000000000000000000000000000000001562000789576000620009c98262001d16565b60405163a2c0625b60e01b81529091506001600160a01b0383169063a2c0625b90620009fa90849060040162002c4e565b600060405180830381600087803b15801562000a1557600080fd5b505af115801562000a2a573d6000803e3d6000fd5b505050505092915050565b60008460008151811062000a4d5762000a4d62002ded565b60200260200101519050856001600160a01b0316816001600160a01b03160362000a78575062000f07565b84516040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260015b8381101562000eae5788818151811062000acc5762000acc62002ded565b6020908102919091018101516001600160a01b0380881660009081526005845260408082208385168352855290819020815160c081018352905460ff8082168352610100820481169683019690965263ffffffff62010000820481169383019390935266010000000000008104909216606082015261ffff600160501b8304166080820152600160601b820490921660a08301529195509350891616881462000ba75760405163171d38a560e31b81526001600160a01b03808716600483015284166024820152604481018990526064015b60405180910390fd5b8381836020015160ff1601600101101562000be957604051635b58eeaf60e11b81526001600160a01b0380871660048301528416602482015260440162000b9e565b816040015163ffffffff1642101562000c3b576040808301519051633a7fae6b60e21b81526001600160a01b0380881660048301528516602482015263ffffffff909116604482015260640162000b9e565b606082015163ffffffff161562000c9e57816060015163ffffffff1642111562000c9e57606082015160405163345761bb60e21b81526001600160a01b0380881660048301528516602482015263ffffffff909116604482015260640162000b9e565b608082015161ffff161562000d955760405163013cf08b60e01b8152600481018890526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063013cf08b906024016101e060405180830381865afa15801562000d17573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d3d919062002ef2565b9050826080015161ffff1643018160c00151111562000d935760808301516040516307672a3160e11b81526001600160a01b0380891660048301528616602482015261ffff909116604482015260640162000b9e565b505b60a08201516001600160a01b03161562000ea05760a082015160405163c6306e0960e01b8082526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048401528d81166024840152604483018b905260ff8a1660648401529092169063c6306e0990608401602060405180830381865afa15801562000e2f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e55919062002fd6565b6001600160e01b0319161462000ea05760a082015160405163b8ec230160e01b81526001600160a01b0380881660048301528086166024830152909116604482015260640162000b9e565b919350839160010162000aae565b50886001600160a01b0316846001600160a01b03160362000ed3575050505062000f07565b60405163171d38a560e31b81526001600160a01b0380861660048301528a1660248201526044810188905260640162000b9e565b5050505050565b62000f1862001cc7565b62000f5f33858580806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250600192508791505060ff861662000a35565b600062000f7b85856000818110620007fc57620007fc62002ded565b604051630acf027160e31b81526004810185905260ff841660248201529091506001600160a01b03821690635678138890604401600060405180830381600087803b15801562000fca57600080fd5b505af115801562000fdf573d6000803e3d6000fd5b50505050336001600160a01b0316816001600160a01b03167f06ef67f52c465c176e4d3ee623ffe1051cdb317e1604d4726aa8b6b332236d5b878787876040516200102e949392919062002ea8565b60405180910390a35050505050565b6200104762001cc7565b6000856001600160401b03811115620010645762001064620027d9565b6040519080825280602002602001820160405280156200108e578160200160208202803683370190505b509050606060005b87811015620011ff57888882818110620010b457620010b462002ded565b9050602002810190620010c8919062002ff6565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092945062001112925033915084905060018a60ff8b1662000a35565b6200113a826000815181106200112c576200112c62002ded565b602002602001015162001a91565b8382815181106200114f576200114f62002ded565b60200260200101906001600160a01b031690816001600160a01b03168152505082818151811062001184576200118462002ded565b60200260200101516001600160a01b0316637b3c71d3888888886040518563ffffffff1660e01b8152600401620011bf949392919062002e2c565b600060405180830381600087803b158015620011da57600080fd5b505af1158015620011ef573d6000803e3d6000fd5b5050505080600101905062001096565b50336001600160a01b03167ff155d545bf480c6d3cdc5d24c9f9364e30d161c58059bcced24aa6e5e3738eb8838a8a8a8a6040516200124395949392919062003042565b60405180910390a25050505050505050565b6200125f62001ef7565b600454600160a01b900460ff166200127d576200127b62001f53565b565b6200127b62001fb6565b6200129162001cc7565b604080517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a8666020808301919091527f862db59105a1338741f3c46ee49a3dc764d93a40b2bbba404e37282178ba316382840152466060830152306080808401919091528351808403909101815260a0830184528051908201207f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f60c084015260e0830189905260ff8816610100808501919091528451808503909101815261012084019094528351939091019290922061190160f01b61014083015261014282018390526101628201819052906000906101820160408051601f198184030181528282528051602091820120600080855291840180845281905260ff8a169284019290925260608301889052608083018790529092509060019060a0016020604051602081039080840390855afa158015620013f1573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166200142657604051635cd5d23360e01b815260040160405180910390fd5b6200146d818c8c80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250600192508e91505060ff8d1662000a35565b6000620014898c8c6000818110620007fc57620007fc62002ded565b604051630acf027160e31b8152600481018c905260ff8b1660248201529091506001600160a01b03821690635678138890604401600060405180830381600087803b158015620014d857600080fd5b505af1158015620014ed573d6000803e3d6000fd5b50505050816001600160a01b0316816001600160a01b03167f06ef67f52c465c176e4d3ee623ffe1051cdb317e1604d4726aa8b6b332236d5b8e8e8e8e6040516200153c949392919062002ea8565b60405180910390a3505050505050505050505050565b80156200158557620015643362001a91565b6001600160a01b03163b600003620015855762001583336000620008da565b505b3360009081526005602090815260408083206001600160a01b038716845290915290208290620015b682826200318b565b905050826001600160a01b0316336001600160a01b03167f5a522316a2409724571357d08b150ddc1b9788dfb0171301e40591e9b4f8b09084604051620015fe919062003347565b60405180910390a3505050565b6200161562001ef7565b6200127b600062001ff5565b60006200162d62001cc7565b6000620016498e8e6000818110620007fc57620007fc62002ded565b604051636d4ab48d60e11b81529091506001600160a01b0382169063da95691a906200168c908f908f908f908f908f908f908f908f908f908f9060040162003405565b6020604051808303816000875af1158015620016ac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620016d29190620034f7565b91506200171a338f8f808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506004925087915060ff905062000a35565b509c9b505050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000015620017d65760006200175f8262001a91565b905060006200176e8262001d16565b60405163a2c0625b60e01b81529091506001600160a01b0383169063a2c0625b906200179f90849060040162002c4e565b600060405180830381600087803b158015620017ba57600080fd5b505af1158015620017cf573d6000803e3d6000fd5b5050505050505b50565b60008054620017e89062003511565b80601f0160208091040260200160405190810160405280929190818152602001828054620018169062003511565b8015620018675780601f106200183b5761010080835404028352916020019162001867565b820191906000526020600020905b8154815290600101906020018083116200184957829003601f168201915b505050505081565b6200187962001cc7565b60005a90506200188e8787878787876200103d565b620017cf8162002047565b620018a362001cc7565b620018e733848480806020026020016040519081016040528093929190818152602001838360200280828437600092018290525060029350915060fe905062000a35565b60006200190384846000818110620007fc57620007fc62002ded565b6001600160a01b038116600081815260066020908152604080832087845290915290819020805460ff1916600117905551919250907f98686f9e3e1d53509f68f7099a7561989e030ede5d7a4f89e63d50b859da9e38906200196b908790879087906200354d565b60405180910390a250505050565b60008115620019cd57600080620019938486018662003573565b915091506000620019a5878362002140565b9050620019b981846002600060fe62000a35565b50630b135d3f60e11b925062001a0d915050565b6001600160a01b038516600090815260066020908152604080832087845290915290205460ff1662001a0157600062001a0a565b630b135d3f60e11b5b90505b949350505050565b62001a1f62001ef7565b6001600160a01b03811662001a865760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000b9e565b620017d68162001ff5565b6040516000906001600160f81b03199030906001600160a01b0385169062001abc60208201620025bb565b601f1982820381018352601f9091011660408181527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031660208301520160408051601f198184030181529082905262001b21929160200162003635565b6040516020818303038152906040528051906020012060405160200162001b7f94939291906001600160f81b031994909416845260609290921b6bffffffffffffffffffffffff191660018401526015830152603582015260550190565b60408051601f19818403018152919052805160209091012092915050565b83821462001baa57600080fd5b801562001bdd5762001bbc3362001a91565b6001600160a01b03163b60000362001bdd5762001bdb336000620008da565b505b60005b8481101562001c765783838281811062001bfe5762001bfe62002ded565b33600090815260056020526040812060c0909202939093019290915088888581811062001c2f5762001c2f62002ded565b905060200201602081019062001c469190620029cf565b6001600160a01b03168152602081019190915260400160002062001c6b82826200318b565b505060010162001be0565b50336001600160a01b03167f9c0c1ce513ac44df340d0f04a9c6044a96f1509d359a48b5da21992b72d568a48686868660405162001cb8949392919062003668565b60405180910390a25050505050565b600454600160a01b900460ff16156200127b5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640162000b9e565b6001600160a01b03811660009081526003602052604090205460609060ff161562001d5457604051630ea075bf60e21b815260040160405180910390fd5b6001805481019081905560009062001d6c9062002168565b905080600060405160200162001d84929190620036c8565b604051602081830303815290604052915060008160405160200162001daa919062003795565b60405160208183030381529060405280519060200120905060007f00000000000000000000000000000000000000000000000000000000000000008260405160200162001e01929190918252602082015260400190565b60408051808303601f19018152828252805160209182012060008181526002835283812080546001600160a01b0319166001600160a01b038c1690811790915581526003909252918120805460ff191660011790556305ef2c7f60e41b83527f000000000000000000000000000000000000000000000000000000000000000060048401526024830185905230604484018190526064840152608483015291506e0c2e074ec69a0dfb2997ba6c7d2e1e90635ef2c7f09060a401600060405180830381600087803b15801562001ed657600080fd5b505af115801562001eeb573d6000803e3d6000fd5b50505050505050919050565b6004546001600160a01b031633146200127b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000b9e565b62001f5d62001cc7565b6004805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25862001f993390565b6040516001600160a01b03909116815260200160405180910390a1565b62001fc062002201565b6004805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa3362001f99565b600480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b47600081900362002056575050565b60006200206948642e90edd00062002253565b905060006200207f3a6377359400840162002253565b9050600062002098618ca05a87030162030d4062002253565b90506000620020aa8284028662002253565b604051909150600090339083908381818185875af1925050503d8060008114620020f1576040519150601f19603f3d011682016040523d82523d6000602084013e620020f6565b606091505b505060408051848152821515602082015291925033917ffabef36fd46c4c3a6ad676521be5367a4dfdbf3faa68d8e826003b1752d68f4f910160405180910390a250505050505050565b60008060006200215185856200226d565b915091506200216081620022b6565b509392505050565b60606000620021778362002413565b60010190506000816001600160401b03811115620021995762002199620027d9565b6040519080825280601f01601f191660200182016040528015620021c4576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084620021ce57509392505050565b600454600160a01b900460ff166200127b5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640162000b9e565b600081831062002264578162002266565b825b9392505050565b6000808251604103620022a75760208301516040840151606085015160001a6200229a87828585620024f2565b94509450505050620022af565b506000905060025b9250929050565b6000816004811115620022cd57620022cd620037b3565b03620022d65750565b6001816004811115620022ed57620022ed620037b3565b036200233c5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640162000b9e565b6002816004811115620023535762002353620037b3565b03620023a25760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640162000b9e565b6003816004811115620023b957620023b9620037b3565b03620017d65760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840162000b9e565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310620024535772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831062002480576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106200249f57662386f26fc10000830492506010015b6305f5e1008310620024b8576305f5e100830492506008015b6127108310620024cd57612710830492506004015b60648310620024e0576064830492506002015b600a8310620007895760010192915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156200252b5750600090506003620025b2565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801562002580573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116620025ab57600060019250925050620025b2565b9150600090505b94509492505050565b6104c280620037ca83390190565b6001600160e01b031981168114620017d657600080fd5b600060208284031215620025f357600080fd5b81356200226681620025c9565b60008083601f8401126200261357600080fd5b5081356001600160401b038111156200262b57600080fd5b6020830191508360208260051b8501011115620022af57600080fd5b60ff81168114620017d657600080fd5b60008083601f8401126200266a57600080fd5b5081356001600160401b038111156200268257600080fd5b602083019150836020828501011115620022af57600080fd5b60008060008060008060808789031215620026b557600080fd5b86356001600160401b0380821115620026cd57600080fd5b620026db8a838b0162002600565b90985096506020890135955060408901359150620026f98262002647565b909350606088013590808211156200271057600080fd5b506200271f89828a0162002657565b979a9699509497509295939492505050565b6001600160a01b0381168114620017d657600080fd5b600080604083850312156200275b57600080fd5b8235620027688162002731565b915060208301356200277a8162002731565b809150509250929050565b8015158114620017d657600080fd5b8035620027a18162002785565b919050565b60008060408385031215620027ba57600080fd5b8235620027c78162002731565b915060208301356200277a8162002785565b634e487b7160e01b600052604160045260246000fd5b6040516101e081016001600160401b0381118282101715620028155762002815620027d9565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620028465762002846620027d9565b604052919050565b600082601f8301126200286057600080fd5b813560206001600160401b038211156200287e576200287e620027d9565b8160051b6200288f8282016200281b565b9283528481018201928281019087851115620028aa57600080fd5b83870192505b84831015620028d6578235620028c68162002731565b82529183019190830190620028b0565b979650505050505050565b600080600080600060a08688031215620028fa57600080fd5b8535620029078162002731565b945060208601356001600160401b038111156200292357600080fd5b62002931888289016200284e565b959895975050505060408401359360608101359360809091013592509050565b6000602082840312156200296457600080fd5b5035919050565b600080600080606085870312156200298257600080fd5b84356001600160401b038111156200299957600080fd5b620029a78782880162002600565b909550935050602085013591506040850135620029c48162002647565b939692955090935050565b600060208284031215620029e257600080fd5b8135620022668162002731565b600080600080600080600060c0888a03121562002a0b57600080fd5b87356001600160401b0381111562002a2257600080fd5b62002a308a828b0162002600565b90985096505060208801359450604088013562002a4d8162002647565b9350606088013562002a5f8162002647565b969995985093969295946080840135945060a09093013592915050565b600080600083850361010081121562002a9457600080fd5b843562002aa18162002731565b935060c0601f198201121562002ab657600080fd5b5060208401915060e084013562002acd8162002785565b809150509250925092565b60008060008060008060008060008060008060c08d8f03121562002afb57600080fd5b6001600160401b038d35111562002b1157600080fd5b62002b208e8e358f0162002600565b909c509a506001600160401b0360208e0135111562002b3e57600080fd5b62002b508e60208f01358f0162002600565b909a5098506001600160401b0360408e0135111562002b6e57600080fd5b62002b808e60408f01358f0162002600565b90985096506001600160401b0360608e0135111562002b9e57600080fd5b62002bb08e60608f01358f0162002600565b90965094506001600160401b0360808e0135111562002bce57600080fd5b62002be08e60808f01358f0162002600565b90945092506001600160401b0360a08e0135111562002bfe57600080fd5b62002c108e60a08f01358f0162002657565b81935080925050509295989b509295989b509295989b565b60005b8381101562002c4557818101518382015260200162002c2b565b50506000910152565b602081526000825180602084015262002c6f81604085016020870162002c28565b601f01601f19169190910160400192915050565b60008060006040848603121562002c9957600080fd5b83356001600160401b0381111562002cb057600080fd5b62002cbe8682870162002600565b909790965060209590950135949350505050565b6000806000806060858703121562002ce957600080fd5b843562002cf68162002731565b93506020850135925060408501356001600160401b0381111562002d1957600080fd5b62002d278782880162002657565b95989497509550505050565b60008060008060006060868803121562002d4c57600080fd5b85356001600160401b038082111562002d6457600080fd5b62002d7289838a0162002600565b9097509550602088013591508082111562002d8c57600080fd5b818801915088601f83011262002da157600080fd5b81358181111562002db157600080fd5b89602060c08302850101111562002dc757600080fd5b60208301955080945050505062002de16040870162002794565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b84815260ff8416602082015260606040820152600062002e5160608301848662002e03565b9695505050505050565b8183526000602080850194508260005b8581101562002e9d57813562002e818162002731565b6001600160a01b03168752958201959082019060010162002e6b565b509495945050505050565b60608152600062002ebe60608301868862002e5b565b905083602083015260ff8316604083015295945050505050565b8051620027a18162002731565b8051620027a18162002785565b60006101e0828403121562002f0657600080fd5b62002f10620027ef565b8251815262002f226020840162002ed8565b602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e082015261010080840151818301525061012080840151818301525061014062002f8b81850162002ee5565b9082015261016062002f9f84820162002ee5565b9082015261018062002fb384820162002ee5565b908201526101a083810151908201526101c0928301519281019290925250919050565b60006020828403121562002fe957600080fd5b81516200226681620025c9565b6000808335601e198436030181126200300e57600080fd5b8301803591506001600160401b038211156200302957600080fd5b6020019150600581901b3603821315620022af57600080fd5b6080808252865190820181905260009060209060a0840190828a01845b82811015620030865781516001600160a01b0316845292840192908401906001016200305f565b50505083810382850152868152818101600588811b830184018a60005b8b8110156200311b57858303601f190185528135368e9003601e19018112620030cb57600080fd5b8d0187810190356001600160401b03811115620030e757600080fd5b80861b3603821315620030f957600080fd5b6200310685828462002e5b565b968901969450505090860190600101620030a3565b50506040870189905260ff88166060880152945062002e519350505050565b63ffffffff81168114620017d657600080fd5b6000813562000789816200313a565b61ffff81168114620017d657600080fd5b6000813562000789816200315c565b60008135620007898162002731565b8135620031988162002647565b60ff8116905081548160ff1982161783556020840135620031b98162002647565b61ff008160081b169050808361ffff198416171784556040850135620031df816200313a565b65ffffffff00008160101b168465ffffffffffff198516178317178555505050506200323862003212606084016200314d565b825469ffffffff000000000000191660309190911b69ffffffff00000000000016178255565b6200326a6200324a608084016200316d565b82805461ffff60501b191660509290921b61ffff60501b16919091179055565b620032a66200327c60a084016200317c565b82546bffffffffffffffffffffffff1660609190911b6bffffffffffffffffffffffff1916178255565b5050565b8035620032b78162002647565b60ff1682526020810135620032cc8162002647565b60ff1660208301526040810135620032e4816200313a565b63ffffffff908116604084015260608201359062003302826200313a565b166060830152608081013562003318816200315c565b61ffff16608083015260a0810135620033318162002731565b6001600160a01b031660a0929092019190915250565b60c08101620007898284620032aa565b6000808335601e198436030181126200336f57600080fd5b83016020810192503590506001600160401b038111156200338f57600080fd5b803603821315620022af57600080fd5b60008383855260208086019550808560051b8301018460005b87811015620033f857848303601f19018952620033d6828862003357565b620033e385828462002e03565b9a86019a9450505090830190600101620033b8565b5090979650505050505050565b60a0815260006200341b60a083018c8e62002e5b565b8281036020848101919091528a82526001600160fb1b038b11156200343f57600080fd5b8a60051b808d8385013780830192505080820181858403016040860152808a825260408401905060408b60051b85010191508b60005b8c811015620034b557858403603f1901835262003493828f62003357565b620034a086828462002e03565b95505050918401919084019060010162003475565b5050508481036060860152620034cd81898b6200339f565b925050508281036080840152620034e681858762002e03565b9d9c50505050505050505050505050565b6000602082840312156200350a57600080fd5b5051919050565b600181811c908216806200352657607f821691505b6020821081036200354757634e487b7160e01b600052602260045260246000fd5b50919050565b6040815260006200356360408301858762002e5b565b9050826020830152949350505050565b600080604083850312156200358757600080fd5b82356001600160401b03808211156200359f57600080fd5b620035ad868387016200284e565b9350602091508185013581811115620035c557600080fd5b8501601f81018713620035d757600080fd5b803582811115620035ec57620035ec620027d9565b62003600601f8201601f191685016200281b565b925080835287848284010111156200361757600080fd5b80848301858501376000848285010152505080925050509250929050565b600083516200364981846020880162002c28565b8351908301906200365f81836020880162002c28565b01949350505050565b6040815260006200367e60408301868862002e5b565b82810360208085019190915284825285910160005b85811015620036bc57620036a88284620032aa565b60c092830192919091019060010162003693565b50979650505050505050565b600083516020620036dd828583890162002c28565b601760f91b918401918252845460019060009080831c818416806200370357607f821691505b85821081036200372157634e487b7160e01b84526022600452602484fd5b808015620037385760018114620037525762003785565b60ff19841688870152821515830288018601945062003785565b60008b81526020902060005b848110156200377b5781548a82018901529087019088016200375e565b5050858389010194505b50929a9950505050505050505050565b60008251620037a981846020870162002c28565b9190910192915050565b634e487b7160e01b600052602160045260246000fdfe60c060405234801561001057600080fd5b506040516104c23803806104c283398101604081905261002f91610044565b336080526001600160a01b031660a052610074565b60006020828403121561005657600080fd5b81516001600160a01b038116811461006d57600080fd5b9392505050565b60805160a05161041d6100a56000396000606001526000818160340152818161011d01526101ac015261041d6000f3fe6080604052600436106100295760003560e01c80631626ba7e146100a6578063a2c0625b146100e3575b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461005e57600080fd5b7f0000000000000000000000000000000000000000000000000000000000000000366000803760008036600034855af13d6000803e80801561009f573d6000f35b3d6000fd5b005b3480156100b257600080fd5b506100c66100c13660046102a0565b610103565b6040516001600160e01b0319909116815260200160405180910390f35b3480156100ef57600080fd5b506100a46100fe3660046102ec565b6101a1565b604051630e2f57fb60e41b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063e2f57fb090610158903090889088908890600401610357565b602060405180830381865afa158015610175573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101999190610389565b949350505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146101d657600080fd5b60405163c47f002760e01b815273084b1c3c81545d370f3634392de611caabff81489063c47f00279061020f90859085906004016103ba565b6020604051808303816000875af115801561022e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025291906103ce565b505050565b60008083601f84011261026957600080fd5b50813567ffffffffffffffff81111561028157600080fd5b60208301915083602082850101111561029957600080fd5b9250929050565b6000806000604084860312156102b557600080fd5b83359250602084013567ffffffffffffffff8111156102d357600080fd5b6102df86828701610257565b9497909650939450505050565b600080602083850312156102ff57600080fd5b823567ffffffffffffffff81111561031657600080fd5b61032285828601610257565b90969095509350505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60018060a01b038516815283602082015260606040820152600061037f60608301848661032e565b9695505050505050565b60006020828403121561039b57600080fd5b81516001600160e01b0319811681146103b357600080fd5b9392505050565b60208152600061019960208301848661032e565b6000602082840312156103e057600080fd5b505191905056fea2646970667358221220f713c761976839ac402290f1ee034e850f179aea67c3319fd22b579944fe7c0564736f6c63430008130033a2646970667358221220b623416f3cab1defcc1541d99e98a31dbabe9b006c764adb8b06e77d6250c60d64736f6c634300081300330000000000000000000000006f3e6272a167e8accb32072d08e0957f9c79223d0000000000000000000000000000000000000000000000000000000000000060b52b0c2d79e4e1940250202dea36651ff7f690bfef59e3077f41248e7b99299700000000000000000000000000000000000000000000000000000000000000136e6f756e732e766f746561676f72612e65746800000000000000000000000000
Deployed Bytecode
0x608060405260043610620001f75760003560e01c80635c975abb116200010b578063bc4cd08411620000a1578063f2fde38b116200006c578063f2fde38b14620006ce578063faa9efe314620006f3578063fbfee8761462000718578063fe5f8fce146200073257600080fd5b8063bc4cd084146200062a578063bd7abaf51462000645578063df827947146200066a578063e2f57fb0146200068f57600080fd5b8063763dc22011620000e2578063763dc22014620005845780638da5cb5b14620005a95780638ef71b8d14620005c9578063b9ffe88e14620005f057600080fd5b80635c975abb1462000526578063715018a61462000547578063730f05b4146200055f57600080fd5b80633b3b57de116200018d5780633dff8de211620001585780633dff8de2146200049f578063405b4c3614620004c45780634ad3822214620004dc578063510e318a146200050157600080fd5b80633b3b57de14620003f45780633b75f7ba146200042e5780633be8ef3f14620004535780633d2d1fa3146200046b57600080fd5b80630c340a2411620001ce5780630c340a24146200028d5780630d6384d014620002dc578063319e909014620003aa578063375d02fa14620003cf57600080fd5b806301ffc9a7146200020457806303a3e6fb146200023e578063042bc3de146200026557600080fd5b36620001ff57005b600080fd5b3480156200021157600080fd5b506200022962000223366004620025e0565b62000757565b60405190151581526020015b60405180910390f35b3480156200024b57600080fd5b50620002636200025d3660046200269b565b6200078f565b005b3480156200027257600080fd5b506200027e62030d4081565b60405190815260200162000235565b3480156200029a57600080fd5b50620002c37f0000000000000000000000006f3e6272a167e8accb32072d08e0957f9c79223d81565b6040516001600160a01b03909116815260200162000235565b348015620002e957600080fd5b5062000360620002fb36600462002747565b600560209081526000928352604080842090915290825290205460ff8082169161010081049091169063ffffffff620100008204811691660100000000000081049091169061ffff600160501b820416906001600160a01b03600160601b9091041686565b6040805160ff978816815296909516602087015263ffffffff938416948601949094529116606084015261ffff1660808301526001600160a01b031660a082015260c00162000235565b348015620003b757600080fd5b50620002c3620003c9366004620027a6565b620008da565b348015620003dc57600080fd5b5062000263620003ee366004620028e1565b62000a35565b3480156200040157600080fd5b50620002c36200041336600462002951565b6000908152600260205260409020546001600160a01b031690565b3480156200043b57600080fd5b50620002636200044d3660046200296b565b62000f0e565b3480156200046057600080fd5b506200027e618ca081565b3480156200047857600080fd5b50620002296200048a366004620029cf565b60036020526000908152604090205460ff1681565b348015620004ac57600080fd5b5062000263620004be3660046200269b565b6200103d565b348015620004d157600080fd5b506200026362001255565b348015620004e957600080fd5b5062000263620004fb366004620029ef565b62001287565b3480156200050e57600080fd5b50620002636200052036600462002a7c565b62001552565b3480156200053357600080fd5b50600454600160a01b900460ff1662000229565b3480156200055457600080fd5b50620002636200160b565b3480156200056c57600080fd5b506200027e6200057e36600462002ad8565b62001621565b3480156200059157600080fd5b5062000263620005a3366004620029cf565b6200172b565b348015620005b657600080fd5b506004546001600160a01b0316620002c3565b348015620005d657600080fd5b50620005e1620017d9565b60405162000235919062002c4e565b348015620005fd57600080fd5b50620002c36200060f36600462002951565b6002602052600090815260409020546001600160a01b031681565b3480156200063757600080fd5b506200027e642e90edd00081565b3480156200065257600080fd5b5062000263620006643660046200269b565b6200186f565b3480156200067757600080fd5b50620002636200068936600462002c83565b62001899565b3480156200069c57600080fd5b50620006b4620006ae36600462002cd2565b62001979565b6040516001600160e01b0319909116815260200162000235565b348015620006db57600080fd5b5062000263620006ed366004620029cf565b62001a15565b3480156200070057600080fd5b50620002c362000712366004620029cf565b62001a91565b3480156200072557600080fd5b506200027e637735940081565b3480156200073f57600080fd5b50620002636200075136600462002d33565b62001b9d565b60006001600160e01b03198216631d9dabef60e11b14806200078957506001600160e01b031982166301ffc9a760e01b145b92915050565b6200079962001cc7565b620007e033878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250600192508991505060ff881662000a35565b60006200081387876000818110620007fc57620007fc62002ded565b9050602002016020810190620007129190620029cf565b604051637b3c71d360e01b81529091506001600160a01b03821690637b3c71d3906200084a90889088908890889060040162002e2c565b600060405180830381600087803b1580156200086557600080fd5b505af11580156200087a573d6000803e3d6000fd5b50505050336001600160a01b0316816001600160a01b03167f06ef67f52c465c176e4d3ee623ffe1051cdb317e1604d4726aa8b6b332236d5b89898989604051620008c9949392919062002ea8565b60405180910390a350505050505050565b6000826001600160a01b031660001b7f0000000000000000000000006f3e6272a167e8accb32072d08e0957f9c79223d6040516200091890620025bb565b6001600160a01b0390911681526020018190604051809103906000f590508015801562000949573d6000803e3d6000fd5b506040516001600160a01b038083168252919250908416907f3d2489efb661e8b1c3679865db649ca1de61d76a71184a1234de2e55786a6aad9060200160405180910390a2811562000789577fb52b0c2d79e4e1940250202dea36651ff7f690bfef59e3077f41248e7b9929971562000789576000620009c98262001d16565b60405163a2c0625b60e01b81529091506001600160a01b0383169063a2c0625b90620009fa90849060040162002c4e565b600060405180830381600087803b15801562000a1557600080fd5b505af115801562000a2a573d6000803e3d6000fd5b505050505092915050565b60008460008151811062000a4d5762000a4d62002ded565b60200260200101519050856001600160a01b0316816001600160a01b03160362000a78575062000f07565b84516040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260015b8381101562000eae5788818151811062000acc5762000acc62002ded565b6020908102919091018101516001600160a01b0380881660009081526005845260408082208385168352855290819020815160c081018352905460ff8082168352610100820481169683019690965263ffffffff62010000820481169383019390935266010000000000008104909216606082015261ffff600160501b8304166080820152600160601b820490921660a08301529195509350891616881462000ba75760405163171d38a560e31b81526001600160a01b03808716600483015284166024820152604481018990526064015b60405180910390fd5b8381836020015160ff1601600101101562000be957604051635b58eeaf60e11b81526001600160a01b0380871660048301528416602482015260440162000b9e565b816040015163ffffffff1642101562000c3b576040808301519051633a7fae6b60e21b81526001600160a01b0380881660048301528516602482015263ffffffff909116604482015260640162000b9e565b606082015163ffffffff161562000c9e57816060015163ffffffff1642111562000c9e57606082015160405163345761bb60e21b81526001600160a01b0380881660048301528516602482015263ffffffff909116604482015260640162000b9e565b608082015161ffff161562000d955760405163013cf08b60e01b8152600481018890526000907f0000000000000000000000006f3e6272a167e8accb32072d08e0957f9c79223d6001600160a01b03169063013cf08b906024016101e060405180830381865afa15801562000d17573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d3d919062002ef2565b9050826080015161ffff1643018160c00151111562000d935760808301516040516307672a3160e11b81526001600160a01b0380891660048301528616602482015261ffff909116604482015260640162000b9e565b505b60a08201516001600160a01b03161562000ea05760a082015160405163c6306e0960e01b8082526001600160a01b037f0000000000000000000000006f3e6272a167e8accb32072d08e0957f9c79223d811660048401528d81166024840152604483018b905260ff8a1660648401529092169063c6306e0990608401602060405180830381865afa15801562000e2f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e55919062002fd6565b6001600160e01b0319161462000ea05760a082015160405163b8ec230160e01b81526001600160a01b0380881660048301528086166024830152909116604482015260640162000b9e565b919350839160010162000aae565b50886001600160a01b0316846001600160a01b03160362000ed3575050505062000f07565b60405163171d38a560e31b81526001600160a01b0380861660048301528a1660248201526044810188905260640162000b9e565b5050505050565b62000f1862001cc7565b62000f5f33858580806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250600192508791505060ff861662000a35565b600062000f7b85856000818110620007fc57620007fc62002ded565b604051630acf027160e31b81526004810185905260ff841660248201529091506001600160a01b03821690635678138890604401600060405180830381600087803b15801562000fca57600080fd5b505af115801562000fdf573d6000803e3d6000fd5b50505050336001600160a01b0316816001600160a01b03167f06ef67f52c465c176e4d3ee623ffe1051cdb317e1604d4726aa8b6b332236d5b878787876040516200102e949392919062002ea8565b60405180910390a35050505050565b6200104762001cc7565b6000856001600160401b03811115620010645762001064620027d9565b6040519080825280602002602001820160405280156200108e578160200160208202803683370190505b509050606060005b87811015620011ff57888882818110620010b457620010b462002ded565b9050602002810190620010c8919062002ff6565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092945062001112925033915084905060018a60ff8b1662000a35565b6200113a826000815181106200112c576200112c62002ded565b602002602001015162001a91565b8382815181106200114f576200114f62002ded565b60200260200101906001600160a01b031690816001600160a01b03168152505082818151811062001184576200118462002ded565b60200260200101516001600160a01b0316637b3c71d3888888886040518563ffffffff1660e01b8152600401620011bf949392919062002e2c565b600060405180830381600087803b158015620011da57600080fd5b505af1158015620011ef573d6000803e3d6000fd5b5050505080600101905062001096565b50336001600160a01b03167ff155d545bf480c6d3cdc5d24c9f9364e30d161c58059bcced24aa6e5e3738eb8838a8a8a8a6040516200124395949392919062003042565b60405180910390a25050505050505050565b6200125f62001ef7565b600454600160a01b900460ff166200127d576200127b62001f53565b565b6200127b62001fb6565b6200129162001cc7565b604080517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a8666020808301919091527f862db59105a1338741f3c46ee49a3dc764d93a40b2bbba404e37282178ba316382840152466060830152306080808401919091528351808403909101815260a0830184528051908201207f150214d74d59b7d1e90c73fc22ef3d991dd0a76b046543d4d80ab92d2a50328f60c084015260e0830189905260ff8816610100808501919091528451808503909101815261012084019094528351939091019290922061190160f01b61014083015261014282018390526101628201819052906000906101820160408051601f198184030181528282528051602091820120600080855291840180845281905260ff8a169284019290925260608301889052608083018790529092509060019060a0016020604051602081039080840390855afa158015620013f1573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166200142657604051635cd5d23360e01b815260040160405180910390fd5b6200146d818c8c80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250600192508e91505060ff8d1662000a35565b6000620014898c8c6000818110620007fc57620007fc62002ded565b604051630acf027160e31b8152600481018c905260ff8b1660248201529091506001600160a01b03821690635678138890604401600060405180830381600087803b158015620014d857600080fd5b505af1158015620014ed573d6000803e3d6000fd5b50505050816001600160a01b0316816001600160a01b03167f06ef67f52c465c176e4d3ee623ffe1051cdb317e1604d4726aa8b6b332236d5b8e8e8e8e6040516200153c949392919062002ea8565b60405180910390a3505050505050505050505050565b80156200158557620015643362001a91565b6001600160a01b03163b600003620015855762001583336000620008da565b505b3360009081526005602090815260408083206001600160a01b038716845290915290208290620015b682826200318b565b905050826001600160a01b0316336001600160a01b03167f5a522316a2409724571357d08b150ddc1b9788dfb0171301e40591e9b4f8b09084604051620015fe919062003347565b60405180910390a3505050565b6200161562001ef7565b6200127b600062001ff5565b60006200162d62001cc7565b6000620016498e8e6000818110620007fc57620007fc62002ded565b604051636d4ab48d60e11b81529091506001600160a01b0382169063da95691a906200168c908f908f908f908f908f908f908f908f908f908f9060040162003405565b6020604051808303816000875af1158015620016ac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620016d29190620034f7565b91506200171a338f8f808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506004925087915060ff905062000a35565b509c9b505050505050505050505050565b7fb52b0c2d79e4e1940250202dea36651ff7f690bfef59e3077f41248e7b99299715620017d65760006200175f8262001a91565b905060006200176e8262001d16565b60405163a2c0625b60e01b81529091506001600160a01b0383169063a2c0625b906200179f90849060040162002c4e565b600060405180830381600087803b158015620017ba57600080fd5b505af1158015620017cf573d6000803e3d6000fd5b5050505050505b50565b60008054620017e89062003511565b80601f0160208091040260200160405190810160405280929190818152602001828054620018169062003511565b8015620018675780601f106200183b5761010080835404028352916020019162001867565b820191906000526020600020905b8154815290600101906020018083116200184957829003601f168201915b505050505081565b6200187962001cc7565b60005a90506200188e8787878787876200103d565b620017cf8162002047565b620018a362001cc7565b620018e733848480806020026020016040519081016040528093929190818152602001838360200280828437600092018290525060029350915060fe905062000a35565b60006200190384846000818110620007fc57620007fc62002ded565b6001600160a01b038116600081815260066020908152604080832087845290915290819020805460ff1916600117905551919250907f98686f9e3e1d53509f68f7099a7561989e030ede5d7a4f89e63d50b859da9e38906200196b908790879087906200354d565b60405180910390a250505050565b60008115620019cd57600080620019938486018662003573565b915091506000620019a5878362002140565b9050620019b981846002600060fe62000a35565b50630b135d3f60e11b925062001a0d915050565b6001600160a01b038516600090815260066020908152604080832087845290915290205460ff1662001a0157600062001a0a565b630b135d3f60e11b5b90505b949350505050565b62001a1f62001ef7565b6001600160a01b03811662001a865760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000b9e565b620017d68162001ff5565b6040516000906001600160f81b03199030906001600160a01b0385169062001abc60208201620025bb565b601f1982820381018352601f9091011660408181527f0000000000000000000000006f3e6272a167e8accb32072d08e0957f9c79223d6001600160a01b031660208301520160408051601f198184030181529082905262001b21929160200162003635565b6040516020818303038152906040528051906020012060405160200162001b7f94939291906001600160f81b031994909416845260609290921b6bffffffffffffffffffffffff191660018401526015830152603582015260550190565b60408051601f19818403018152919052805160209091012092915050565b83821462001baa57600080fd5b801562001bdd5762001bbc3362001a91565b6001600160a01b03163b60000362001bdd5762001bdb336000620008da565b505b60005b8481101562001c765783838281811062001bfe5762001bfe62002ded565b33600090815260056020526040812060c0909202939093019290915088888581811062001c2f5762001c2f62002ded565b905060200201602081019062001c469190620029cf565b6001600160a01b03168152602081019190915260400160002062001c6b82826200318b565b505060010162001be0565b50336001600160a01b03167f9c0c1ce513ac44df340d0f04a9c6044a96f1509d359a48b5da21992b72d568a48686868660405162001cb8949392919062003668565b60405180910390a25050505050565b600454600160a01b900460ff16156200127b5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640162000b9e565b6001600160a01b03811660009081526003602052604090205460609060ff161562001d5457604051630ea075bf60e21b815260040160405180910390fd5b6001805481019081905560009062001d6c9062002168565b905080600060405160200162001d84929190620036c8565b604051602081830303815290604052915060008160405160200162001daa919062003795565b60405160208183030381529060405280519060200120905060007fb52b0c2d79e4e1940250202dea36651ff7f690bfef59e3077f41248e7b9929978260405160200162001e01929190918252602082015260400190565b60408051808303601f19018152828252805160209182012060008181526002835283812080546001600160a01b0319166001600160a01b038c1690811790915581526003909252918120805460ff191660011790556305ef2c7f60e41b83527fb52b0c2d79e4e1940250202dea36651ff7f690bfef59e3077f41248e7b99299760048401526024830185905230604484018190526064840152608483015291506e0c2e074ec69a0dfb2997ba6c7d2e1e90635ef2c7f09060a401600060405180830381600087803b15801562001ed657600080fd5b505af115801562001eeb573d6000803e3d6000fd5b50505050505050919050565b6004546001600160a01b031633146200127b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000b9e565b62001f5d62001cc7565b6004805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25862001f993390565b6040516001600160a01b03909116815260200160405180910390a1565b62001fc062002201565b6004805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa3362001f99565b600480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b47600081900362002056575050565b60006200206948642e90edd00062002253565b905060006200207f3a6377359400840162002253565b9050600062002098618ca05a87030162030d4062002253565b90506000620020aa8284028662002253565b604051909150600090339083908381818185875af1925050503d8060008114620020f1576040519150601f19603f3d011682016040523d82523d6000602084013e620020f6565b606091505b505060408051848152821515602082015291925033917ffabef36fd46c4c3a6ad676521be5367a4dfdbf3faa68d8e826003b1752d68f4f910160405180910390a250505050505050565b60008060006200215185856200226d565b915091506200216081620022b6565b509392505050565b60606000620021778362002413565b60010190506000816001600160401b03811115620021995762002199620027d9565b6040519080825280601f01601f191660200182016040528015620021c4576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084620021ce57509392505050565b600454600160a01b900460ff166200127b5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640162000b9e565b600081831062002264578162002266565b825b9392505050565b6000808251604103620022a75760208301516040840151606085015160001a6200229a87828585620024f2565b94509450505050620022af565b506000905060025b9250929050565b6000816004811115620022cd57620022cd620037b3565b03620022d65750565b6001816004811115620022ed57620022ed620037b3565b036200233c5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640162000b9e565b6002816004811115620023535762002353620037b3565b03620023a25760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640162000b9e565b6003816004811115620023b957620023b9620037b3565b03620017d65760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840162000b9e565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310620024535772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831062002480576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106200249f57662386f26fc10000830492506010015b6305f5e1008310620024b8576305f5e100830492506008015b6127108310620024cd57612710830492506004015b60648310620024e0576064830492506002015b600a8310620007895760010192915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156200252b5750600090506003620025b2565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801562002580573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116620025ab57600060019250925050620025b2565b9150600090505b94509492505050565b6104c280620037ca83390190565b6001600160e01b031981168114620017d657600080fd5b600060208284031215620025f357600080fd5b81356200226681620025c9565b60008083601f8401126200261357600080fd5b5081356001600160401b038111156200262b57600080fd5b6020830191508360208260051b8501011115620022af57600080fd5b60ff81168114620017d657600080fd5b60008083601f8401126200266a57600080fd5b5081356001600160401b038111156200268257600080fd5b602083019150836020828501011115620022af57600080fd5b60008060008060008060808789031215620026b557600080fd5b86356001600160401b0380821115620026cd57600080fd5b620026db8a838b0162002600565b90985096506020890135955060408901359150620026f98262002647565b909350606088013590808211156200271057600080fd5b506200271f89828a0162002657565b979a9699509497509295939492505050565b6001600160a01b0381168114620017d657600080fd5b600080604083850312156200275b57600080fd5b8235620027688162002731565b915060208301356200277a8162002731565b809150509250929050565b8015158114620017d657600080fd5b8035620027a18162002785565b919050565b60008060408385031215620027ba57600080fd5b8235620027c78162002731565b915060208301356200277a8162002785565b634e487b7160e01b600052604160045260246000fd5b6040516101e081016001600160401b0381118282101715620028155762002815620027d9565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620028465762002846620027d9565b604052919050565b600082601f8301126200286057600080fd5b813560206001600160401b038211156200287e576200287e620027d9565b8160051b6200288f8282016200281b565b9283528481018201928281019087851115620028aa57600080fd5b83870192505b84831015620028d6578235620028c68162002731565b82529183019190830190620028b0565b979650505050505050565b600080600080600060a08688031215620028fa57600080fd5b8535620029078162002731565b945060208601356001600160401b038111156200292357600080fd5b62002931888289016200284e565b959895975050505060408401359360608101359360809091013592509050565b6000602082840312156200296457600080fd5b5035919050565b600080600080606085870312156200298257600080fd5b84356001600160401b038111156200299957600080fd5b620029a78782880162002600565b909550935050602085013591506040850135620029c48162002647565b939692955090935050565b600060208284031215620029e257600080fd5b8135620022668162002731565b600080600080600080600060c0888a03121562002a0b57600080fd5b87356001600160401b0381111562002a2257600080fd5b62002a308a828b0162002600565b90985096505060208801359450604088013562002a4d8162002647565b9350606088013562002a5f8162002647565b969995985093969295946080840135945060a09093013592915050565b600080600083850361010081121562002a9457600080fd5b843562002aa18162002731565b935060c0601f198201121562002ab657600080fd5b5060208401915060e084013562002acd8162002785565b809150509250925092565b60008060008060008060008060008060008060c08d8f03121562002afb57600080fd5b6001600160401b038d35111562002b1157600080fd5b62002b208e8e358f0162002600565b909c509a506001600160401b0360208e0135111562002b3e57600080fd5b62002b508e60208f01358f0162002600565b909a5098506001600160401b0360408e0135111562002b6e57600080fd5b62002b808e60408f01358f0162002600565b90985096506001600160401b0360608e0135111562002b9e57600080fd5b62002bb08e60608f01358f0162002600565b90965094506001600160401b0360808e0135111562002bce57600080fd5b62002be08e60808f01358f0162002600565b90945092506001600160401b0360a08e0135111562002bfe57600080fd5b62002c108e60a08f01358f0162002657565b81935080925050509295989b509295989b509295989b565b60005b8381101562002c4557818101518382015260200162002c2b565b50506000910152565b602081526000825180602084015262002c6f81604085016020870162002c28565b601f01601f19169190910160400192915050565b60008060006040848603121562002c9957600080fd5b83356001600160401b0381111562002cb057600080fd5b62002cbe8682870162002600565b909790965060209590950135949350505050565b6000806000806060858703121562002ce957600080fd5b843562002cf68162002731565b93506020850135925060408501356001600160401b0381111562002d1957600080fd5b62002d278782880162002657565b95989497509550505050565b60008060008060006060868803121562002d4c57600080fd5b85356001600160401b038082111562002d6457600080fd5b62002d7289838a0162002600565b9097509550602088013591508082111562002d8c57600080fd5b818801915088601f83011262002da157600080fd5b81358181111562002db157600080fd5b89602060c08302850101111562002dc757600080fd5b60208301955080945050505062002de16040870162002794565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b84815260ff8416602082015260606040820152600062002e5160608301848662002e03565b9695505050505050565b8183526000602080850194508260005b8581101562002e9d57813562002e818162002731565b6001600160a01b03168752958201959082019060010162002e6b565b509495945050505050565b60608152600062002ebe60608301868862002e5b565b905083602083015260ff8316604083015295945050505050565b8051620027a18162002731565b8051620027a18162002785565b60006101e0828403121562002f0657600080fd5b62002f10620027ef565b8251815262002f226020840162002ed8565b602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e082015261010080840151818301525061012080840151818301525061014062002f8b81850162002ee5565b9082015261016062002f9f84820162002ee5565b9082015261018062002fb384820162002ee5565b908201526101a083810151908201526101c0928301519281019290925250919050565b60006020828403121562002fe957600080fd5b81516200226681620025c9565b6000808335601e198436030181126200300e57600080fd5b8301803591506001600160401b038211156200302957600080fd5b6020019150600581901b3603821315620022af57600080fd5b6080808252865190820181905260009060209060a0840190828a01845b82811015620030865781516001600160a01b0316845292840192908401906001016200305f565b50505083810382850152868152818101600588811b830184018a60005b8b8110156200311b57858303601f190185528135368e9003601e19018112620030cb57600080fd5b8d0187810190356001600160401b03811115620030e757600080fd5b80861b3603821315620030f957600080fd5b6200310685828462002e5b565b968901969450505090860190600101620030a3565b50506040870189905260ff88166060880152945062002e519350505050565b63ffffffff81168114620017d657600080fd5b6000813562000789816200313a565b61ffff81168114620017d657600080fd5b6000813562000789816200315c565b60008135620007898162002731565b8135620031988162002647565b60ff8116905081548160ff1982161783556020840135620031b98162002647565b61ff008160081b169050808361ffff198416171784556040850135620031df816200313a565b65ffffffff00008160101b168465ffffffffffff198516178317178555505050506200323862003212606084016200314d565b825469ffffffff000000000000191660309190911b69ffffffff00000000000016178255565b6200326a6200324a608084016200316d565b82805461ffff60501b191660509290921b61ffff60501b16919091179055565b620032a66200327c60a084016200317c565b82546bffffffffffffffffffffffff1660609190911b6bffffffffffffffffffffffff1916178255565b5050565b8035620032b78162002647565b60ff1682526020810135620032cc8162002647565b60ff1660208301526040810135620032e4816200313a565b63ffffffff908116604084015260608201359062003302826200313a565b166060830152608081013562003318816200315c565b61ffff16608083015260a0810135620033318162002731565b6001600160a01b031660a0929092019190915250565b60c08101620007898284620032aa565b6000808335601e198436030181126200336f57600080fd5b83016020810192503590506001600160401b038111156200338f57600080fd5b803603821315620022af57600080fd5b60008383855260208086019550808560051b8301018460005b87811015620033f857848303601f19018952620033d6828862003357565b620033e385828462002e03565b9a86019a9450505090830190600101620033b8565b5090979650505050505050565b60a0815260006200341b60a083018c8e62002e5b565b8281036020848101919091528a82526001600160fb1b038b11156200343f57600080fd5b8a60051b808d8385013780830192505080820181858403016040860152808a825260408401905060408b60051b85010191508b60005b8c811015620034b557858403603f1901835262003493828f62003357565b620034a086828462002e03565b95505050918401919084019060010162003475565b5050508481036060860152620034cd81898b6200339f565b925050508281036080840152620034e681858762002e03565b9d9c50505050505050505050505050565b6000602082840312156200350a57600080fd5b5051919050565b600181811c908216806200352657607f821691505b6020821081036200354757634e487b7160e01b600052602260045260246000fd5b50919050565b6040815260006200356360408301858762002e5b565b9050826020830152949350505050565b600080604083850312156200358757600080fd5b82356001600160401b03808211156200359f57600080fd5b620035ad868387016200284e565b9350602091508185013581811115620035c557600080fd5b8501601f81018713620035d757600080fd5b803582811115620035ec57620035ec620027d9565b62003600601f8201601f191685016200281b565b925080835287848284010111156200361757600080fd5b80848301858501376000848285010152505080925050509250929050565b600083516200364981846020880162002c28565b8351908301906200365f81836020880162002c28565b01949350505050565b6040815260006200367e60408301868862002e5b565b82810360208085019190915284825285910160005b85811015620036bc57620036a88284620032aa565b60c092830192919091019060010162003693565b50979650505050505050565b600083516020620036dd828583890162002c28565b601760f91b918401918252845460019060009080831c818416806200370357607f821691505b85821081036200372157634e487b7160e01b84526022600452602484fd5b808015620037385760018114620037525762003785565b60ff19841688870152821515830288018601945062003785565b60008b81526020902060005b848110156200377b5781548a82018901529087019088016200375e565b5050858389010194505b50929a9950505050505050505050565b60008251620037a981846020870162002c28565b9190910192915050565b634e487b7160e01b600052602160045260246000fdfe60c060405234801561001057600080fd5b506040516104c23803806104c283398101604081905261002f91610044565b336080526001600160a01b031660a052610074565b60006020828403121561005657600080fd5b81516001600160a01b038116811461006d57600080fd5b9392505050565b60805160a05161041d6100a56000396000606001526000818160340152818161011d01526101ac015261041d6000f3fe6080604052600436106100295760003560e01c80631626ba7e146100a6578063a2c0625b146100e3575b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461005e57600080fd5b7f0000000000000000000000000000000000000000000000000000000000000000366000803760008036600034855af13d6000803e80801561009f573d6000f35b3d6000fd5b005b3480156100b257600080fd5b506100c66100c13660046102a0565b610103565b6040516001600160e01b0319909116815260200160405180910390f35b3480156100ef57600080fd5b506100a46100fe3660046102ec565b6101a1565b604051630e2f57fb60e41b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063e2f57fb090610158903090889088908890600401610357565b602060405180830381865afa158015610175573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101999190610389565b949350505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146101d657600080fd5b60405163c47f002760e01b815273084b1c3c81545d370f3634392de611caabff81489063c47f00279061020f90859085906004016103ba565b6020604051808303816000875af115801561022e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025291906103ce565b505050565b60008083601f84011261026957600080fd5b50813567ffffffffffffffff81111561028157600080fd5b60208301915083602082850101111561029957600080fd5b9250929050565b6000806000604084860312156102b557600080fd5b83359250602084013567ffffffffffffffff8111156102d357600080fd5b6102df86828701610257565b9497909650939450505050565b600080602083850312156102ff57600080fd5b823567ffffffffffffffff81111561031657600080fd5b61032285828601610257565b90969095509350505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60018060a01b038516815283602082015260606040820152600061037f60608301848661032e565b9695505050505050565b60006020828403121561039b57600080fd5b81516001600160e01b0319811681146103b357600080fd5b9392505050565b60208152600061019960208301848661032e565b6000602082840312156103e057600080fd5b505191905056fea2646970667358221220f713c761976839ac402290f1ee034e850f179aea67c3319fd22b579944fe7c0564736f6c63430008130033a2646970667358221220b623416f3cab1defcc1541d99e98a31dbabe9b006c764adb8b06e77d6250c60d64736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006f3e6272a167e8accb32072d08e0957f9c79223d0000000000000000000000000000000000000000000000000000000000000060b52b0c2d79e4e1940250202dea36651ff7f690bfef59e3077f41248e7b99299700000000000000000000000000000000000000000000000000000000000000136e6f756e732e766f746561676f72612e65746800000000000000000000000000
-----Decoded View---------------
Arg [0] : _governor (address): 0x6f3E6272A167e8AcCb32072d08E0957F9c79223d
Arg [1] : _ensName (string): nouns.voteagora.eth
Arg [2] : _ensNameHash (bytes32): 0xb52b0c2d79e4e1940250202dea36651ff7f690bfef59e3077f41248e7b992997
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000006f3e6272a167e8accb32072d08e0957f9c79223d
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [2] : b52b0c2d79e4e1940250202dea36651ff7f690bfef59e3077f41248e7b992997
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000013
Arg [4] : 6e6f756e732e766f746561676f72612e65746800000000000000000000000000
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ 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.