Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 262 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Register With Ac... | 14151007 | 929 days ago | IN | 0 ETH | 0.01062281 | ||||
Register With Ac... | 14089283 | 939 days ago | IN | 0 ETH | 0.04024534 | ||||
Register With Ac... | 14073856 | 941 days ago | IN | 0 ETH | 0.01358814 | ||||
Register With Ac... | 14049615 | 945 days ago | IN | 0 ETH | 0.04163986 | ||||
Register With Ac... | 14037920 | 947 days ago | IN | 0 ETH | 0.02664313 | ||||
Register With Ac... | 14037461 | 947 days ago | IN | 0 ETH | 0.05767802 | ||||
Register With Ac... | 14035467 | 947 days ago | IN | 0 ETH | 0.01304966 | ||||
Register With Ac... | 14022287 | 949 days ago | IN | 0 ETH | 0.01757592 | ||||
Register With Ac... | 14015559 | 950 days ago | IN | 0 ETH | 0.01932647 | ||||
Register With Ac... | 13995857 | 953 days ago | IN | 0 ETH | 0.02881651 | ||||
Register With Ac... | 13967015 | 958 days ago | IN | 0 ETH | 0.03489826 | ||||
Register With Ac... | 13964491 | 958 days ago | IN | 0 ETH | 0.01770799 | ||||
Register With Ac... | 13964054 | 958 days ago | IN | 0 ETH | 0.01168372 | ||||
Register With Ac... | 13962773 | 958 days ago | IN | 0 ETH | 0.02118315 | ||||
Register With Ac... | 13961078 | 959 days ago | IN | 0 ETH | 0.03091531 | ||||
Register With Ac... | 13960939 | 959 days ago | IN | 0 ETH | 0.02541957 | ||||
Register With Ac... | 13960651 | 959 days ago | IN | 0 ETH | 0.02370606 | ||||
Register With Ac... | 13960090 | 959 days ago | IN | 0 ETH | 0.05859287 | ||||
Register With Ac... | 13959542 | 959 days ago | IN | 0 ETH | 0.02375188 | ||||
Register With Ac... | 13954965 | 959 days ago | IN | 0 ETH | 0.03304674 | ||||
Register With Ac... | 13954886 | 959 days ago | IN | 0 ETH | 0.01794448 | ||||
Register With Ac... | 13954593 | 960 days ago | IN | 0 ETH | 0.0243492 | ||||
Register With Ac... | 13954425 | 960 days ago | IN | 0 ETH | 0.0261417 | ||||
Register With Ac... | 13953616 | 960 days ago | IN | 0 ETH | 0.02954232 | ||||
Register With Ac... | 13952872 | 960 days ago | IN | 0 ETH | 0.03098278 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
SismoSDaoRegistrar
Compiler Version
v0.8.4+commit.c7e474f2
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity >=0.8.4; import {PublicResolver} from '@ensdomains/ens-contracts/contracts/resolvers/PublicResolver.sol'; import {ENS} from '@ensdomains/ens-contracts/contracts/registry/ENS.sol'; import {SDaoRegistrar} from '@sismo-core/ens-sdao/contracts/sdao/SDaoRegistrar.sol'; import {SDaoRegistrarLimited} from '@sismo-core/ens-sdao/contracts/sdao/extensions/SDaoRegistrarLimited.sol'; import {SDaoRegistrarReserved} from '@sismo-core/ens-sdao/contracts/sdao/extensions/SDaoRegistrarReserved.sol'; import {SDaoRegistrarERC1155Generator, IERC1155Minter} from '@sismo-core/ens-sdao/contracts/sdao/extensions/SDaoRegistrarERC1155Generator.sol'; import {SDaoRegistrarCodeAccessible} from '@sismo-core/ens-sdao/contracts/sdao/extensions/SDaoRegistrarCodeAccessible.sol'; contract SismoSDaoRegistrar is SDaoRegistrar, SDaoRegistrarLimited, SDaoRegistrarReserved, SDaoRegistrarERC1155Generator, SDaoRegistrarCodeAccessible { uint256 public _groupId; uint256 public _gen; uint256 public _maxGenReached; bytes public _tokenData; event GroupIdUpdated(uint256 groupId); event GenUpdated(uint256 gen); event TokenDataUpdated(bytes tokenData); /** * @dev Constructor. * @param ensAddr The address of the ENS registry. * @param resolver The address of the Resolver. * @param erc1155Token The address of the ERC1155 Token. * @param node The node that this registrar administers. * @param owner The owner of the contract. * @param reservationDuration The duration of the reservation period. * @param registrationLimit The limit of registration number. * @param groupId The initial group ID. * @param codeSigner The address of the code signer. */ constructor( ENS ensAddr, PublicResolver resolver, IERC1155Minter erc1155Token, bytes32 node, address owner, uint256 reservationDuration, uint256 registrationLimit, uint256 groupId, address codeSigner ) SDaoRegistrarCodeAccessible('Sismo', '1.0', codeSigner) SDaoRegistrarERC1155Generator(erc1155Token) SDaoRegistrarLimited(registrationLimit) SDaoRegistrarReserved(reservationDuration) SDaoRegistrar(ensAddr, resolver, node, owner) { _groupId = groupId; _tokenData = bytes(''); _gen = 1; _maxGenReached = 1; } /** * @notice Transit to a new generation. * @dev Can only be called by the owner. * @param registrationLimit The new registration limit. * @param gen The new generation. * @param groupId The new group ID. * @param tokenData The new token data. */ function transitToGeneration( uint256 registrationLimit, uint256 gen, uint256 groupId, bytes calldata tokenData ) external onlyOwner { _updateGeneration(gen); _updateRegistrationLimit(registrationLimit); _setGroupId(groupId); _updateTokenData(tokenData); } /** * @notice Add a generation. * @dev Can only be called by the owner. * @param gen The new generation. */ function updateGeneration(uint256 gen) external onlyOwner { _updateGeneration(gen); } /** * @notice Update the group ID. * @dev Can only be called by the owner. * @param groupId The new group ID. */ function updateGroupId(uint256 groupId) external onlyOwner { _setGroupId(groupId); } /** * @notice Update the token data. * @dev Can only be called by the owner. * @param tokenData The new token data. */ function updateTokenData(bytes calldata tokenData) external onlyOwner { _updateTokenData(tokenData); } /** * @dev Update the token data. * @param tokenData The new token data. */ function _updateTokenData(bytes memory tokenData) internal { _tokenData = tokenData; emit TokenDataUpdated(tokenData); } /** * @dev Get the current group ID. * @return The current group ID. */ function _getCurrentGroupId() internal view override returns (uint256) { return _groupId; } /** * @dev Get token ID and data. The token ID is the current generation. * @return The ID and the data of the token */ function _getToken(address, bytes32) internal view override returns (uint256, bytes memory) { return (_gen, _tokenData); } /** * @dev Get the total balance of an account over the generations. * @param account The address for which the balance is needed. * @return The total balance of an account over the generations. */ function _balanceOf(address account) internal view override returns (uint256) { address[] memory accounts = new address[](_maxGenReached); uint256[] memory gens = new uint256[](_maxGenReached); for (uint256 index = 0; index < _maxGenReached; index++) { accounts[index] = account; gens[index] = index + 1; } uint256[] memory balances = ERC1155_MINTER.balanceOfBatch(accounts, gens); uint256 sum = 0; for (uint256 index = 0; index < _maxGenReached; index++) { sum += balances[index]; } return sum; } function _setGroupId(uint256 groupId) internal { _groupId = groupId; emit GroupIdUpdated(groupId); } /** * @dev Add a new generation. * @param gen The new generation. */ function _updateGeneration(uint256 gen) internal { _gen = gen; if (gen > _maxGenReached) { _maxGenReached = gen; } emit GenUpdated(gen); } function _beforeRegistration(address account, bytes32 labelHash) internal virtual override( SDaoRegistrar, SDaoRegistrarReserved, SDaoRegistrarLimited, SDaoRegistrarERC1155Generator ) { super._beforeRegistration(account, labelHash); } function _afterRegistration(address account, bytes32 labelHash) internal virtual override(SDaoRegistrar, SDaoRegistrarLimited, SDaoRegistrarERC1155Generator) { super._afterRegistration(account, labelHash); } }
pragma solidity >=0.8.4; import "../registry/ENS.sol"; import "./profiles/ABIResolver.sol"; import "./profiles/AddrResolver.sol"; import "./profiles/ContentHashResolver.sol"; import "./profiles/DNSResolver.sol"; import "./profiles/InterfaceResolver.sol"; import "./profiles/NameResolver.sol"; import "./profiles/PubkeyResolver.sol"; import "./profiles/TextResolver.sol"; interface INameWrapper { function ownerOf(uint256 id) external view returns (address); } /** * A simple resolver anyone can use; only allows the owner of a node to set its * address. */ contract PublicResolver is ABIResolver, AddrResolver, ContentHashResolver, DNSResolver, InterfaceResolver, NameResolver, PubkeyResolver, TextResolver { ENS ens; INameWrapper nameWrapper; /** * A mapping of operators. An address that is authorised for an address * may make any changes to the name that the owner could, but may not update * the set of authorisations. * (owner, operator) => approved */ mapping(address => mapping(address => bool)) private _operatorApprovals; // Logged when an operator is added or removed. event ApprovalForAll(address indexed owner, address indexed operator, bool approved); constructor(ENS _ens, INameWrapper wrapperAddress){ ens = _ens; nameWrapper = wrapperAddress; } /** * @dev See {IERC1155-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) external{ require( msg.sender != operator, "ERC1155: setting approval status for self" ); _operatorApprovals[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } function isAuthorised(bytes32 node) internal override view returns(bool) { address owner = ens.owner(node); if(owner == address(nameWrapper) ){ owner = nameWrapper.ownerOf(uint256(node)); } return owner == msg.sender || isApprovedForAll(owner, msg.sender); } /** * @dev See {IERC1155-isApprovedForAll}. */ function isApprovedForAll(address account, address operator) public view returns (bool){ return _operatorApprovals[account][operator]; } function multicall(bytes[] calldata data) external returns(bytes[] memory results) { results = new bytes[](data.length); for(uint i = 0; i < data.length; i++) { (bool success, bytes memory result) = address(this).delegatecall(data[i]); require(success); results[i] = result; } return results; } function supportsInterface(bytes4 interfaceID) virtual override(ABIResolver, AddrResolver, ContentHashResolver, DNSResolver, InterfaceResolver, NameResolver, PubkeyResolver, TextResolver) public pure returns(bool) { return super.supportsInterface(interfaceID); } }
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 virtual; function setSubnodeRecord(bytes32 node, bytes32 label, address owner, address resolver, uint64 ttl) external virtual; function setSubnodeOwner(bytes32 node, bytes32 label, address owner) external virtual returns(bytes32); function setResolver(bytes32 node, address resolver) external virtual; function setOwner(bytes32 node, address owner) external virtual; function setTTL(bytes32 node, uint64 ttl) external virtual; function setApprovalForAll(address operator, bool approved) external virtual; function owner(bytes32 node) external virtual view returns (address); function resolver(bytes32 node) external virtual view returns (address); function ttl(bytes32 node) external virtual view returns (uint64); function recordExists(bytes32 node) external virtual view returns (bool); function isApprovedForAll(address owner, address operator) external virtual view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import '@openzeppelin/contracts/access/Ownable.sol'; import '@openzeppelin/contracts/token/ERC721/ERC721.sol'; import '@ensdomains/ens-contracts/contracts/registry/ENS.sol'; import {PublicResolver} from '@ensdomains/ens-contracts/contracts/resolvers/PublicResolver.sol'; import {ISDaoRegistrar} from './ISDaoRegistrar.sol'; /** * @title SDaoRegistrar contract. * @dev Implementation of the {ISDaoRegistrar}. */ contract SDaoRegistrar is Ownable, ISDaoRegistrar { PublicResolver public immutable RESOLVER; ENS public immutable ENS_REGISTRY; bytes32 public immutable ROOT_NODE; bool public _restricted = false; /** * @dev Constructor. * @param ensAddr The address of the ENS registry. * @param resolver The address of the Resolver. * @param node The node that this registrar administers. * @param owner The owner of the contract. */ constructor( ENS ensAddr, PublicResolver resolver, bytes32 node, address owner ) { ENS_REGISTRY = ensAddr; RESOLVER = resolver; ROOT_NODE = node; transferOwnership(owner); } modifier onlyUnrestricted() { require(!_restricted, 'SDAO_REGISTRAR: RESTRICTED_REGISTRATION'); _; } /** * @notice Register a name. * @dev Can only be called if and only if the subdomain of the root node is free * @param label The label to register. */ function register(string memory label) public virtual override onlyUnrestricted { _register(_msgSender(), label); } /** * @notice Transfer the root domain ownership of the SDAO Registrar to a new owner. * @dev Can be called by the owner of the registrar. */ function transferDomainOwnership(address newDomainOwner) public override onlyOwner { ENS_REGISTRY.setOwner(ROOT_NODE, newDomainOwner); emit DomainOwnershipTransferred(newDomainOwner); } /** * @notice Restrict registration. * @dev Can only be called by the owner. */ function restrictRegistration() public override onlyOwner { _restricted = true; emit Restricted(); } /** * @notice Open registration. * @dev Can only be called by the owner. */ function openRegistration() public override onlyOwner { _restricted = false; emit Unrestricted(); } /** * @dev Register a name and mint a DAO token. * Can only be called if and only if the subdomain is free to be registered. * @param account The address that will receive the subdomain. * @param label The label to register. */ function _register(address account, string memory label) internal { bytes32 labelHash = keccak256(bytes(label)); _beforeRegistration(account, labelHash); bytes32 childNode = keccak256(abi.encodePacked(ROOT_NODE, labelHash)); address subdomainOwner = ENS_REGISTRY.owner( keccak256(abi.encodePacked(ROOT_NODE, labelHash)) ); require( subdomainOwner == address(0x0), 'SDAO_REGISTRAR: SUBDOMAIN_ALREADY_REGISTERED' ); // Set ownership to SDAO, so that the contract can set resolver ENS_REGISTRY.setSubnodeRecord( ROOT_NODE, labelHash, address(this), address(RESOLVER), 0 ); // Setting the resolver for the user RESOLVER.setAddr(childNode, account); // Giving back the ownership to the user ENS_REGISTRY.setSubnodeOwner(ROOT_NODE, labelHash, account); _afterRegistration(account, labelHash); emit NameRegistered(uint256(childNode), label, account, _msgSender()); } /** * @dev Hook that is called before any registration. * * @param account The address for which the registration is made. * @param labelHash The hash of the label to register. */ function _beforeRegistration(address account, bytes32 labelHash) internal virtual {} /** * @dev Hook that is called after any registration. * * @param account The address for which the registration is made. * @param labelHash The hash of the label to register. */ function _afterRegistration(address account, bytes32 labelHash) internal virtual {} }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import {SDaoRegistrar} from '../SDaoRegistrar.sol'; import {ISDaoRegistrarLimited} from './interfaces/ISDaoRegistrarLimited.sol'; /** * @title SDaoRegistrarLimited contract. * @dev Implementation of the {ISDaoRegistrarLimited}. */ abstract contract SDaoRegistrarLimited is SDaoRegistrar, ISDaoRegistrarLimited { uint256 public _registrationLimit; uint256 public _counter; /** * @dev Constructor. * @param registrationLimit The limit of registration number. */ constructor(uint256 registrationLimit) { _registrationLimit = registrationLimit; } /** * @notice Update limit registration number. * @dev Can only be called by owner. * @param registrationLimit The limit of registration number. */ function updateRegistrationLimit(uint256 registrationLimit) public override onlyOwner { _updateRegistrationLimit(registrationLimit); } /** * @dev Update limit registration number. * @param registrationLimit The limit of registration number. */ function _updateRegistrationLimit(uint256 registrationLimit) internal { require( registrationLimit >= _counter, 'SDAO_REGISTRAR_LIMITED: NEW_REGISTRATION_LIMIT_TOO_LOW' ); _registrationLimit = registrationLimit; emit RegistrationLimitUpdated(registrationLimit); } /** * @dev Hook that is called before any registration. * * It will pass if and only if the number of registration is lower than the limit. * * @param account The address for which the registration is made. * @param labelHash The hash of the label to register. */ function _beforeRegistration(address account, bytes32 labelHash) internal virtual override { super._beforeRegistration(account, labelHash); require( _counter < _registrationLimit, 'SDAO_REGISTRAR_LIMITED: REGISTRATION_LIMIT_REACHED' ); } /** * @dev Hook that is called after any registration. * * Counter of registration is increased by 1. * * @param account The address for which the registration is made. * @param labelHash The hash of the label to register. */ function _afterRegistration(address account, bytes32 labelHash) internal virtual override { super._afterRegistration(account, labelHash); _counter += 1; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import {SDaoRegistrar} from '../SDaoRegistrar.sol'; import {ISDaoRegistrarReserved} from './interfaces/ISDaoRegistrarReserved.sol'; /** * @title SDaoRegistrarReserved contract. * @dev Implementation of the {ISDaoRegistrarReserved}. */ abstract contract SDaoRegistrarReserved is SDaoRegistrar, ISDaoRegistrarReserved { bytes32 public constant ETH_NODE = keccak256(abi.encodePacked(bytes32(0), keccak256('eth'))); uint256 public immutable DAO_BIRTH_DATE; uint256 public _reservationDuration; /** * @dev Constructor. * @param reservationDuration The duration of the reservation period. */ constructor(uint256 reservationDuration) { DAO_BIRTH_DATE = block.timestamp; _reservationDuration = reservationDuration; } /** * @notice Update reservation period duration. * @dev Can only be called by owner. * @param reservationDuration The new reservation duration. */ function updateReservationDuration(uint256 reservationDuration) public override onlyOwner { require( block.timestamp - DAO_BIRTH_DATE >= reservationDuration, 'SDAO_REGISTRAR_RESERVED: NEW_RESERVATION_DURATION_TOO_SHORT' ); _reservationDuration = reservationDuration; emit ReservationDurationUpdated(reservationDuration); } /** * @dev Hook that is called before any registration. * * It will pass if and only if one of the two following conditions is met: * - the reservation period is not over AND (the associated .eth subdomain is free OR owned by the sender), * - the reservation period is over. * * @param account The address for which the reservation is made. * @param labelHash The hash of the label to register. */ function _beforeRegistration(address account, bytes32 labelHash) internal virtual override { super._beforeRegistration(account, labelHash); if (block.timestamp - DAO_BIRTH_DATE <= _reservationDuration) { address dotEthSubdomainOwner = ENS_REGISTRY.owner( keccak256(abi.encodePacked(ETH_NODE, labelHash)) ); require( dotEthSubdomainOwner == address(0x0) || dotEthSubdomainOwner == _msgSender(), 'SDAO_REGISTRAR_RESERVED: SUBDOMAIN_RESERVED' ); } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import '@openzeppelin/contracts/token/ERC1155/IERC1155.sol'; import {SDaoRegistrar} from '../SDaoRegistrar.sol'; interface IERC1155Minter is IERC1155 { function mint( address to, uint256 id, uint256 amount, bytes memory data ) external; } /** * @title SDaoRegistrarERC1155Generator contract. * @dev Implementation of the {ISDaoRegistrarERC1155Generator}. * A token is minted for each registration. * Only one token is allowed by account. */ abstract contract SDaoRegistrarERC1155Generator is SDaoRegistrar { IERC1155Minter public immutable ERC1155_MINTER; /** * @dev Constructor. * @param erc1155Minter The address of the ERC1155 Minter. */ constructor(IERC1155Minter erc1155Minter) { require( address(erc1155Minter) != address(0), 'SDAO_REGISTRAR_ERC1155_GENERATOR: INVALID_ERC721_ADDRESS' ); ERC1155_MINTER = erc1155Minter; } /** * @dev Hook that is called before any registration. * * It will pass if and only if the balance of the account is zero or the account is the owner. * Balance is computed based on a function which is implemented in the implementation contract. * * @param account The address for which the registration is made. * @param labelHash The hash of the label to register. */ function _beforeRegistration(address account, bytes32 labelHash) internal virtual override { super._beforeRegistration(account, labelHash); require( _balanceOf(account) == 0 || account == owner(), 'SDAO_REGISTRAR_ERC1155_GENERATOR: ALREADY_TOKEN_OWNER' ); } /** * @dev Hook that is called after any registration. * * One ERC1155 token is minted and given to the account. * * @param account The address for which the registration is made. * @param labelHash The hash of the label to register. */ function _afterRegistration(address account, bytes32 labelHash) internal virtual override { super._afterRegistration(account, labelHash); (uint256 id, bytes memory data) = _getToken(account, labelHash); ERC1155_MINTER.mint(account, id, 1, data); } /** * @dev Get token ID and token data. * @param account The address for which the registration is made. * @param labelHash The hash of the label to register. * @return The ID and the data of the token. */ function _getToken(address account, bytes32 labelHash) internal view virtual returns (uint256, bytes memory); /** * @dev Get balance of an address. * @param account The address for which the registration is made. * @return The ID and the data of the token. */ function _balanceOf(address account) internal virtual returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import {SDaoRegistrar} from '../SDaoRegistrar.sol'; import {ISDaoRegistrarCodeAccessible} from './interfaces/ISDaoRegistrarCodeAccessible.sol'; import '@openzeppelin/contracts/utils/cryptography/ECDSA.sol'; /** * @title SDaoRegistrarCodeAccessible contract. * @dev Implementation of the {ISDaoRegistrarCodeAccessible}. */ abstract contract SDaoRegistrarCodeAccessible is SDaoRegistrar, ISDaoRegistrarCodeAccessible { using ECDSA for bytes32; mapping(bytes32 => bool) public _consumed; address public _codeSigner; struct EIP712Domain { string name; string version; uint256 chainId; address verifyingContract; } struct CodeOrigin { address recipient; uint256 groupId; } bytes32 constant EIP712DOMAIN_TYPEHASH = keccak256( 'EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)' ); bytes32 constant CODE_ORIGIN_TYPEHASH = keccak256('CodeOrigin(address recipient,uint256 groupId)'); bytes32 immutable DOMAIN_SEPARATOR; /** * @dev Constructor. * @param name The name field of the EIP712 Domain. * @param version The version field of the EIP712 Domain. * @param codeSigner The address of the code signer. */ constructor( string memory name, string memory version, address codeSigner ) { DOMAIN_SEPARATOR = _hash( EIP712Domain({ name: name, version: version, chainId: block.chainid, verifyingContract: address(this) }) ); _restricted = true; _codeSigner = codeSigner; } /** * @notice Register a name and mints a DAO token using an access code. * @dev Can only be called by the recipient of the access code generated by the code signer. * @param label The label to register. * @param label Address of the recipient of the registration. * @param accessCode The EIP712 signature corresponding to a groupId and the recipient address. */ function registerWithAccessCode( string memory label, address recipient, bytes memory accessCode ) external override { uint256 groupId = _getCurrentGroupId(); CodeOrigin memory codeOrigin = CodeOrigin({ recipient: recipient, groupId: groupId }); bytes32 digest = DOMAIN_SEPARATOR.toTypedDataHash(_hash(codeOrigin)); require( !_consumed[digest], 'SDAO_REGISTRAR_LIMITED_CODE_ACCESSIBLE: ACCESS_CODE_ALREADY_CONSUMED' ); require( digest.recover(accessCode) == _codeSigner, 'SDAO_REGISTRAR_LIMITED_CODE_ACCESSIBLE: INVALID_ACCESS_CODE OR INVALID_SENDER' ); _register(recipient, label); _consumed[digest] = true; emit AccessCodeConsumed(groupId, accessCode); } /** * @notice Update the code signer. * @dev Can only be called by the owner. * @param codeSigner The address of the code signer. */ function updateCodeSigner(address codeSigner) public override onlyOwner { _codeSigner = codeSigner; emit CodeSignerUpdated(codeSigner); } /** * @dev Encode and hash an EIP712Domain structure. * @return The hash of the encoding of the EIP712Domain structure. */ function _hash(EIP712Domain memory eip712Domain) internal pure returns (bytes32) { return keccak256( abi.encode( EIP712DOMAIN_TYPEHASH, keccak256(bytes(eip712Domain.name)), keccak256(bytes(eip712Domain.version)), eip712Domain.chainId, eip712Domain.verifyingContract ) ); } /** * @dev Encode and hash an CodeOrigin structure. * @return The hash of the encoding of the CodeOrigin structure. */ function _hash(CodeOrigin memory codeOrigin) internal pure returns (bytes32) { return keccak256( abi.encode( CODE_ORIGIN_TYPEHASH, codeOrigin.recipient, codeOrigin.groupId ) ); } /** * @dev Get the current group ID. * @return The current group ID. */ function _getCurrentGroupId() internal virtual returns (uint256); }
pragma solidity >=0.8.4; import "../ResolverBase.sol"; abstract contract ABIResolver is ResolverBase { bytes4 constant private ABI_INTERFACE_ID = 0x2203ab56; event ABIChanged(bytes32 indexed node, uint256 indexed contentType); mapping(bytes32=>mapping(uint256=>bytes)) abis; /** * Sets the ABI associated with an ENS node. * Nodes may have one ABI of each content type. To remove an ABI, set it to * the empty string. * @param node The node to update. * @param contentType The content type of the ABI * @param data The ABI data. */ function setABI(bytes32 node, uint256 contentType, bytes calldata data) external authorised(node) { // Content types must be powers of 2 require(((contentType - 1) & contentType) == 0); abis[node][contentType] = data; emit ABIChanged(node, contentType); } /** * Returns the ABI associated with an ENS node. * Defined in EIP205. * @param node The ENS node to query * @param contentTypes A bitwise OR of the ABI formats accepted by the caller. * @return contentType The content type of the return value * @return data The ABI data */ function ABI(bytes32 node, uint256 contentTypes) external view returns (uint256, bytes memory) { mapping(uint256=>bytes) storage abiset = abis[node]; for (uint256 contentType = 1; contentType <= contentTypes; contentType <<= 1) { if ((contentType & contentTypes) != 0 && abiset[contentType].length > 0) { return (contentType, abiset[contentType]); } } return (0, bytes("")); } function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) { return interfaceID == ABI_INTERFACE_ID || super.supportsInterface(interfaceID); } }
pragma solidity >=0.8.4; import "../ResolverBase.sol"; abstract contract AddrResolver is ResolverBase { bytes4 constant private ADDR_INTERFACE_ID = 0x3b3b57de; bytes4 constant private ADDRESS_INTERFACE_ID = 0xf1cb7e06; uint constant private COIN_TYPE_ETH = 60; event AddrChanged(bytes32 indexed node, address a); event AddressChanged(bytes32 indexed node, uint coinType, bytes newAddress); mapping(bytes32=>mapping(uint=>bytes)) _addresses; /** * Sets the address associated with an ENS node. * May only be called by the owner of that node in the ENS registry. * @param node The node to update. * @param a The address to set. */ function setAddr(bytes32 node, address a) external authorised(node) { setAddr(node, COIN_TYPE_ETH, addressToBytes(a)); } /** * Returns the address associated with an ENS node. * @param node The ENS node to query. * @return The associated address. */ function addr(bytes32 node) public view returns (address payable) { bytes memory a = addr(node, COIN_TYPE_ETH); if(a.length == 0) { return payable(0); } return bytesToAddress(a); } function setAddr(bytes32 node, uint coinType, bytes memory a) public authorised(node) { emit AddressChanged(node, coinType, a); if(coinType == COIN_TYPE_ETH) { emit AddrChanged(node, bytesToAddress(a)); } _addresses[node][coinType] = a; } function addr(bytes32 node, uint coinType) public view returns(bytes memory) { return _addresses[node][coinType]; } function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) { return interfaceID == ADDR_INTERFACE_ID || interfaceID == ADDRESS_INTERFACE_ID || super.supportsInterface(interfaceID); } }
pragma solidity >=0.8.4; import "../ResolverBase.sol"; abstract contract ContentHashResolver is ResolverBase { bytes4 constant private CONTENT_HASH_INTERFACE_ID = 0xbc1c58d1; event ContenthashChanged(bytes32 indexed node, bytes hash); mapping(bytes32=>bytes) hashes; /** * Sets the contenthash associated with an ENS node. * May only be called by the owner of that node in the ENS registry. * @param node The node to update. * @param hash The contenthash to set */ function setContenthash(bytes32 node, bytes calldata hash) external authorised(node) { hashes[node] = hash; emit ContenthashChanged(node, hash); } /** * Returns the contenthash associated with an ENS node. * @param node The ENS node to query. * @return The associated contenthash. */ function contenthash(bytes32 node) external view returns (bytes memory) { return hashes[node]; } function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) { return interfaceID == CONTENT_HASH_INTERFACE_ID || super.supportsInterface(interfaceID); } }
pragma solidity >=0.8.4; import "../ResolverBase.sol"; import "../../dnssec-oracle/RRUtils.sol"; abstract contract DNSResolver is ResolverBase { using RRUtils for *; using BytesUtils for bytes; bytes4 constant private DNS_RECORD_INTERFACE_ID = 0xa8fa5682; bytes4 constant private DNS_ZONE_INTERFACE_ID = 0x5c47637c; // DNSRecordChanged is emitted whenever a given node/name/resource's RRSET is updated. event DNSRecordChanged(bytes32 indexed node, bytes name, uint16 resource, bytes record); // DNSRecordDeleted is emitted whenever a given node/name/resource's RRSET is deleted. event DNSRecordDeleted(bytes32 indexed node, bytes name, uint16 resource); // DNSZoneCleared is emitted whenever a given node's zone information is cleared. event DNSZoneCleared(bytes32 indexed node); // DNSZonehashChanged is emitted whenever a given node's zone hash is updated. event DNSZonehashChanged(bytes32 indexed node, bytes lastzonehash, bytes zonehash); // Zone hashes for the domains. // A zone hash is an EIP-1577 content hash in binary format that should point to a // resource containing a single zonefile. // node => contenthash mapping(bytes32=>bytes) private zonehashes; // Version the mapping for each zone. This allows users who have lost // track of their entries to effectively delete an entire zone by bumping // the version number. // node => version mapping(bytes32=>uint256) private versions; // The records themselves. Stored as binary RRSETs // node => version => name => resource => data mapping(bytes32=>mapping(uint256=>mapping(bytes32=>mapping(uint16=>bytes)))) private records; // Count of number of entries for a given name. Required for DNS resolvers // when resolving wildcards. // node => version => name => number of records mapping(bytes32=>mapping(uint256=>mapping(bytes32=>uint16))) private nameEntriesCount; /** * Set one or more DNS records. Records are supplied in wire-format. * Records with the same node/name/resource must be supplied one after the * other to ensure the data is updated correctly. For example, if the data * was supplied: * a.example.com IN A 1.2.3.4 * a.example.com IN A 5.6.7.8 * www.example.com IN CNAME a.example.com. * then this would store the two A records for a.example.com correctly as a * single RRSET, however if the data was supplied: * a.example.com IN A 1.2.3.4 * www.example.com IN CNAME a.example.com. * a.example.com IN A 5.6.7.8 * then this would store the first A record, the CNAME, then the second A * record which would overwrite the first. * * @param node the namehash of the node for which to set the records * @param data the DNS wire format records to set */ function setDNSRecords(bytes32 node, bytes calldata data) external authorised(node) { uint16 resource = 0; uint256 offset = 0; bytes memory name; bytes memory value; bytes32 nameHash; // Iterate over the data to add the resource records for (RRUtils.RRIterator memory iter = data.iterateRRs(0); !iter.done(); iter.next()) { if (resource == 0) { resource = iter.dnstype; name = iter.name(); nameHash = keccak256(abi.encodePacked(name)); value = bytes(iter.rdata()); } else { bytes memory newName = iter.name(); if (resource != iter.dnstype || !name.equals(newName)) { setDNSRRSet(node, name, resource, data, offset, iter.offset - offset, value.length == 0); resource = iter.dnstype; offset = iter.offset; name = newName; nameHash = keccak256(name); value = bytes(iter.rdata()); } } } if (name.length > 0) { setDNSRRSet(node, name, resource, data, offset, data.length - offset, value.length == 0); } } /** * Obtain a DNS record. * @param node the namehash of the node for which to fetch the record * @param name the keccak-256 hash of the fully-qualified name for which to fetch the record * @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types * @return the DNS record in wire format if present, otherwise empty */ function dnsRecord(bytes32 node, bytes32 name, uint16 resource) public view returns (bytes memory) { return records[node][versions[node]][name][resource]; } /** * Check if a given node has records. * @param node the namehash of the node for which to check the records * @param name the namehash of the node for which to check the records */ function hasDNSRecords(bytes32 node, bytes32 name) public view returns (bool) { return (nameEntriesCount[node][versions[node]][name] != 0); } /** * Clear all information for a DNS zone. * @param node the namehash of the node for which to clear the zone */ function clearDNSZone(bytes32 node) public authorised(node) { versions[node]++; emit DNSZoneCleared(node); } /** * setZonehash sets the hash for the zone. * May only be called by the owner of that node in the ENS registry. * @param node The node to update. * @param hash The zonehash to set */ function setZonehash(bytes32 node, bytes calldata hash) external authorised(node) { bytes memory oldhash = zonehashes[node]; zonehashes[node] = hash; emit DNSZonehashChanged(node, oldhash, hash); } /** * zonehash obtains the hash for the zone. * @param node The ENS node to query. * @return The associated contenthash. */ function zonehash(bytes32 node) external view returns (bytes memory) { return zonehashes[node]; } function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) { return interfaceID == DNS_RECORD_INTERFACE_ID || interfaceID == DNS_ZONE_INTERFACE_ID || super.supportsInterface(interfaceID); } function setDNSRRSet( bytes32 node, bytes memory name, uint16 resource, bytes memory data, uint256 offset, uint256 size, bool deleteRecord) private { uint256 version = versions[node]; bytes32 nameHash = keccak256(name); bytes memory rrData = data.substring(offset, size); if (deleteRecord) { if (records[node][version][nameHash][resource].length != 0) { nameEntriesCount[node][version][nameHash]--; } delete(records[node][version][nameHash][resource]); emit DNSRecordDeleted(node, name, resource); } else { if (records[node][version][nameHash][resource].length == 0) { nameEntriesCount[node][version][nameHash]++; } records[node][version][nameHash][resource] = rrData; emit DNSRecordChanged(node, name, resource, rrData); } } }
pragma solidity >=0.8.4; import "../ResolverBase.sol"; import "./AddrResolver.sol"; abstract contract InterfaceResolver is ResolverBase, AddrResolver { bytes4 constant private INTERFACE_INTERFACE_ID = bytes4(keccak256("interfaceImplementer(bytes32,bytes4)")); bytes4 private constant INTERFACE_META_ID = 0x01ffc9a7; event InterfaceChanged(bytes32 indexed node, bytes4 indexed interfaceID, address implementer); mapping(bytes32=>mapping(bytes4=>address)) interfaces; /** * Sets an interface associated with a name. * Setting the address to 0 restores the default behaviour of querying the contract at `addr()` for interface support. * @param node The node to update. * @param interfaceID The EIP 165 interface ID. * @param implementer The address of a contract that implements this interface for this node. */ function setInterface(bytes32 node, bytes4 interfaceID, address implementer) external authorised(node) { interfaces[node][interfaceID] = implementer; emit InterfaceChanged(node, interfaceID, implementer); } /** * Returns the address of a contract that implements the specified interface for this name. * If an implementer has not been set for this interfaceID and name, the resolver will query * the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that * contract implements EIP165 and returns `true` for the specified interfaceID, its address * will be returned. * @param node The ENS node to query. * @param interfaceID The EIP 165 interface ID to check for. * @return The address that implements this interface, or 0 if the interface is unsupported. */ function interfaceImplementer(bytes32 node, bytes4 interfaceID) external view returns (address) { address implementer = interfaces[node][interfaceID]; if(implementer != address(0)) { return implementer; } address a = addr(node); if(a == address(0)) { return address(0); } (bool success, bytes memory returnData) = a.staticcall(abi.encodeWithSignature("supportsInterface(bytes4)", INTERFACE_META_ID)); if(!success || returnData.length < 32 || returnData[31] == 0) { // EIP 165 not supported by target return address(0); } (success, returnData) = a.staticcall(abi.encodeWithSignature("supportsInterface(bytes4)", interfaceID)); if(!success || returnData.length < 32 || returnData[31] == 0) { // Specified interface not supported by target return address(0); } return a; } function supportsInterface(bytes4 interfaceID) virtual override(AddrResolver, ResolverBase) public pure returns(bool) { return interfaceID == INTERFACE_INTERFACE_ID || super.supportsInterface(interfaceID); } }
pragma solidity >=0.8.4; import "../ResolverBase.sol"; abstract contract NameResolver is ResolverBase { bytes4 constant private NAME_INTERFACE_ID = 0x691f3431; event NameChanged(bytes32 indexed node, string name); mapping(bytes32=>string) names; /** * Sets the name associated with an ENS node, for reverse records. * May only be called by the owner of that node in the ENS registry. * @param node The node to update. * @param name The name to set. */ function setName(bytes32 node, string calldata name) external authorised(node) { names[node] = name; emit NameChanged(node, name); } /** * Returns the name associated with an ENS node, for reverse records. * Defined in EIP181. * @param node The ENS node to query. * @return The associated name. */ function name(bytes32 node) external view returns (string memory) { return names[node]; } function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) { return interfaceID == NAME_INTERFACE_ID || super.supportsInterface(interfaceID); } }
pragma solidity >=0.8.4; import "../ResolverBase.sol"; abstract contract PubkeyResolver is ResolverBase { bytes4 constant private PUBKEY_INTERFACE_ID = 0xc8690233; event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y); struct PublicKey { bytes32 x; bytes32 y; } mapping(bytes32=>PublicKey) pubkeys; /** * Sets the SECP256k1 public key associated with an ENS node. * @param node The ENS node to query * @param x the X coordinate of the curve point for the public key. * @param y the Y coordinate of the curve point for the public key. */ function setPubkey(bytes32 node, bytes32 x, bytes32 y) external authorised(node) { pubkeys[node] = PublicKey(x, y); emit PubkeyChanged(node, x, y); } /** * Returns the SECP256k1 public key associated with an ENS node. * Defined in EIP 619. * @param node The ENS node to query * @return x The X coordinate of the curve point for the public key. * @return y The Y coordinate of the curve point for the public key. */ function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y) { return (pubkeys[node].x, pubkeys[node].y); } function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) { return interfaceID == PUBKEY_INTERFACE_ID || super.supportsInterface(interfaceID); } }
pragma solidity >=0.8.4; import "../ResolverBase.sol"; abstract contract TextResolver is ResolverBase { bytes4 constant private TEXT_INTERFACE_ID = 0x59d1d43c; event TextChanged(bytes32 indexed node, string indexed indexedKey, string key); mapping(bytes32=>mapping(string=>string)) texts; /** * Sets the text data associated with an ENS node and key. * May only be called by the owner of that node in the ENS registry. * @param node The node to update. * @param key The key to set. * @param value The text data value to set. */ function setText(bytes32 node, string calldata key, string calldata value) external authorised(node) { texts[node][key] = value; emit TextChanged(node, key, key); } /** * Returns the text data associated with an ENS node and key. * @param node The ENS node to query. * @param key The text data key to query. * @return The associated text data. */ function text(bytes32 node, string calldata key) external view returns (string memory) { return texts[node][key]; } function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) { return interfaceID == TEXT_INTERFACE_ID || super.supportsInterface(interfaceID); } }
pragma solidity >=0.8.4; abstract contract ResolverBase { bytes4 private constant INTERFACE_META_ID = 0x01ffc9a7; function supportsInterface(bytes4 interfaceID) virtual public pure returns(bool) { return interfaceID == INTERFACE_META_ID; } function isAuthorised(bytes32 node) internal virtual view returns(bool); modifier authorised(bytes32 node) { require(isAuthorised(node)); _; } function bytesToAddress(bytes memory b) internal pure returns(address payable a) { require(b.length == 20); assembly { a := div(mload(add(b, 32)), exp(256, 12)) } } function addressToBytes(address a) internal pure returns(bytes memory b) { b = new bytes(20); assembly { mstore(add(b, 32), mul(a, exp(256, 12))) } } }
pragma solidity ^0.8.4; import "./BytesUtils.sol"; import "@ensdomains/buffer/contracts/Buffer.sol"; /** * @dev RRUtils is a library that provides utilities for parsing DNS resource records. */ library RRUtils { using BytesUtils for *; using Buffer for *; /** * @dev Returns the number of bytes in the DNS name at 'offset' in 'self'. * @param self The byte array to read a name from. * @param offset The offset to start reading at. * @return The length of the DNS name at 'offset', in bytes. */ function nameLength(bytes memory self, uint offset) internal pure returns(uint) { uint idx = offset; while (true) { assert(idx < self.length); uint labelLen = self.readUint8(idx); idx += labelLen + 1; if (labelLen == 0) { break; } } return idx - offset; } /** * @dev Returns a DNS format name at the specified offset of self. * @param self The byte array to read a name from. * @param offset The offset to start reading at. * @return ret The name. */ function readName(bytes memory self, uint offset) internal pure returns(bytes memory ret) { uint len = nameLength(self, offset); return self.substring(offset, len); } /** * @dev Returns the number of labels in the DNS name at 'offset' in 'self'. * @param self The byte array to read a name from. * @param offset The offset to start reading at. * @return The number of labels in the DNS name at 'offset', in bytes. */ function labelCount(bytes memory self, uint offset) internal pure returns(uint) { uint count = 0; while (true) { assert(offset < self.length); uint labelLen = self.readUint8(offset); offset += labelLen + 1; if (labelLen == 0) { break; } count += 1; } return count; } uint constant RRSIG_TYPE = 0; uint constant RRSIG_ALGORITHM = 2; uint constant RRSIG_LABELS = 3; uint constant RRSIG_TTL = 4; uint constant RRSIG_EXPIRATION = 8; uint constant RRSIG_INCEPTION = 12; uint constant RRSIG_KEY_TAG = 16; uint constant RRSIG_SIGNER_NAME = 18; struct SignedSet { uint16 typeCovered; uint8 algorithm; uint8 labels; uint32 ttl; uint32 expiration; uint32 inception; uint16 keytag; bytes signerName; bytes data; bytes name; } function readSignedSet(bytes memory data) internal pure returns(SignedSet memory self) { self.typeCovered = data.readUint16(RRSIG_TYPE); self.algorithm = data.readUint8(RRSIG_ALGORITHM); self.labels = data.readUint8(RRSIG_LABELS); self.ttl = data.readUint32(RRSIG_TTL); self.expiration = data.readUint32(RRSIG_EXPIRATION); self.inception = data.readUint32(RRSIG_INCEPTION); self.keytag = data.readUint16(RRSIG_KEY_TAG); self.signerName = readName(data, RRSIG_SIGNER_NAME); self.data = data.substring(RRSIG_SIGNER_NAME + self.signerName.length, data.length - RRSIG_SIGNER_NAME - self.signerName.length); } function rrs(SignedSet memory rrset) internal pure returns(RRIterator memory) { return iterateRRs(rrset.data, 0); } /** * @dev An iterator over resource records. */ struct RRIterator { bytes data; uint offset; uint16 dnstype; uint16 class; uint32 ttl; uint rdataOffset; uint nextOffset; } /** * @dev Begins iterating over resource records. * @param self The byte string to read from. * @param offset The offset to start reading at. * @return ret An iterator object. */ function iterateRRs(bytes memory self, uint offset) internal pure returns (RRIterator memory ret) { ret.data = self; ret.nextOffset = offset; next(ret); } /** * @dev Returns true iff there are more RRs to iterate. * @param iter The iterator to check. * @return True iff the iterator has finished. */ function done(RRIterator memory iter) internal pure returns(bool) { return iter.offset >= iter.data.length; } /** * @dev Moves the iterator to the next resource record. * @param iter The iterator to advance. */ function next(RRIterator memory iter) internal pure { iter.offset = iter.nextOffset; if (iter.offset >= iter.data.length) { return; } // Skip the name uint off = iter.offset + nameLength(iter.data, iter.offset); // Read type, class, and ttl iter.dnstype = iter.data.readUint16(off); off += 2; iter.class = iter.data.readUint16(off); off += 2; iter.ttl = iter.data.readUint32(off); off += 4; // Read the rdata uint rdataLength = iter.data.readUint16(off); off += 2; iter.rdataOffset = off; iter.nextOffset = off + rdataLength; } /** * @dev Returns the name of the current record. * @param iter The iterator. * @return A new bytes object containing the owner name from the RR. */ function name(RRIterator memory iter) internal pure returns(bytes memory) { return iter.data.substring(iter.offset, nameLength(iter.data, iter.offset)); } /** * @dev Returns the rdata portion of the current record. * @param iter The iterator. * @return A new bytes object containing the RR's RDATA. */ function rdata(RRIterator memory iter) internal pure returns(bytes memory) { return iter.data.substring(iter.rdataOffset, iter.nextOffset - iter.rdataOffset); } uint constant DNSKEY_FLAGS = 0; uint constant DNSKEY_PROTOCOL = 2; uint constant DNSKEY_ALGORITHM = 3; uint constant DNSKEY_PUBKEY = 4; struct DNSKEY { uint16 flags; uint8 protocol; uint8 algorithm; bytes publicKey; } function readDNSKEY(bytes memory data, uint offset, uint length) internal pure returns(DNSKEY memory self) { self.flags = data.readUint16(offset + DNSKEY_FLAGS); self.protocol = data.readUint8(offset + DNSKEY_PROTOCOL); self.algorithm = data.readUint8(offset + DNSKEY_ALGORITHM); self.publicKey = data.substring(offset + DNSKEY_PUBKEY, length - DNSKEY_PUBKEY); } uint constant DS_KEY_TAG = 0; uint constant DS_ALGORITHM = 2; uint constant DS_DIGEST_TYPE = 3; uint constant DS_DIGEST = 4; struct DS { uint16 keytag; uint8 algorithm; uint8 digestType; bytes digest; } function readDS(bytes memory data, uint offset, uint length) internal pure returns(DS memory self) { self.keytag = data.readUint16(offset + DS_KEY_TAG); self.algorithm = data.readUint8(offset + DS_ALGORITHM); self.digestType = data.readUint8(offset + DS_DIGEST_TYPE); self.digest = data.substring(offset + DS_DIGEST, length - DS_DIGEST); } struct NSEC3 { uint8 hashAlgorithm; uint8 flags; uint16 iterations; bytes salt; bytes32 nextHashedOwnerName; bytes typeBitmap; } uint constant NSEC3_HASH_ALGORITHM = 0; uint constant NSEC3_FLAGS = 1; uint constant NSEC3_ITERATIONS = 2; uint constant NSEC3_SALT_LENGTH = 4; uint constant NSEC3_SALT = 5; function readNSEC3(bytes memory data, uint offset, uint length) internal pure returns(NSEC3 memory self) { uint end = offset + length; self.hashAlgorithm = data.readUint8(offset + NSEC3_HASH_ALGORITHM); self.flags = data.readUint8(offset + NSEC3_FLAGS); self.iterations = data.readUint16(offset + NSEC3_ITERATIONS); uint8 saltLength = data.readUint8(offset + NSEC3_SALT_LENGTH); offset = offset + NSEC3_SALT; self.salt = data.substring(offset, saltLength); offset += saltLength; uint8 nextLength = data.readUint8(offset); require(nextLength <= 32); offset += 1; self.nextHashedOwnerName = data.readBytesN(offset, nextLength); offset += nextLength; self.typeBitmap = data.substring(offset, end - offset); } function checkTypeBitmap(NSEC3 memory self, uint16 rrtype) internal pure returns(bool) { return checkTypeBitmap(self.typeBitmap, 0, rrtype); } /** * @dev Checks if a given RR type exists in a type bitmap. * @param bitmap The byte string to read the type bitmap from. * @param offset The offset to start reading at. * @param rrtype The RR type to check for. * @return True if the type is found in the bitmap, false otherwise. */ function checkTypeBitmap(bytes memory bitmap, uint offset, uint16 rrtype) internal pure returns (bool) { uint8 typeWindow = uint8(rrtype >> 8); uint8 windowByte = uint8((rrtype & 0xff) / 8); uint8 windowBitmask = uint8(uint8(1) << (uint8(7) - uint8(rrtype & 0x7))); for (uint off = offset; off < bitmap.length;) { uint8 window = bitmap.readUint8(off); uint8 len = bitmap.readUint8(off + 1); if (typeWindow < window) { // We've gone past our window; it's not here. return false; } else if (typeWindow == window) { // Check this type bitmap if (len <= windowByte) { // Our type is past the end of the bitmap return false; } return (bitmap.readUint8(off + windowByte + 2) & windowBitmask) != 0; } else { // Skip this type bitmap off += len + 2; } } return false; } function compareNames(bytes memory self, bytes memory other) internal pure returns (int) { if (self.equals(other)) { return 0; } uint off; uint otheroff; uint prevoff; uint otherprevoff; uint counts = labelCount(self, 0); uint othercounts = labelCount(other, 0); // Keep removing labels from the front of the name until both names are equal length while (counts > othercounts) { prevoff = off; off = progress(self, off); counts--; } while (othercounts > counts) { otherprevoff = otheroff; otheroff = progress(other, otheroff); othercounts--; } // Compare the last nonequal labels to each other while (counts > 0 && !self.equals(off, other, otheroff)) { prevoff = off; off = progress(self, off); otherprevoff = otheroff; otheroff = progress(other, otheroff); counts -= 1; } if (off == 0) { return -1; } if(otheroff == 0) { return 1; } return self.compare(prevoff + 1, self.readUint8(prevoff), other, otherprevoff + 1, other.readUint8(otherprevoff)); } /** * @dev Compares two serial numbers using RFC1982 serial number math. */ function serialNumberGte(uint32 i1, uint32 i2) internal pure returns(bool) { return int32(i1) - int32(i2) >= 0; } function progress(bytes memory body, uint off) internal pure returns(uint) { return off + 1 + body.readUint8(off); } }
pragma solidity ^0.8.4; library BytesUtils { /* * @dev Returns the keccak-256 hash of a byte range. * @param self The byte string to hash. * @param offset The position to start hashing at. * @param len The number of bytes to hash. * @return The hash of the byte range. */ function keccak(bytes memory self, uint offset, uint len) internal pure returns (bytes32 ret) { require(offset + len <= self.length); assembly { ret := keccak256(add(add(self, 32), offset), len) } } /* * @dev Returns a positive number if `other` comes lexicographically after * `self`, a negative number if it comes before, or zero if the * contents of the two bytes are equal. * @param self The first bytes to compare. * @param other The second bytes to compare. * @return The result of the comparison. */ function compare(bytes memory self, bytes memory other) internal pure returns (int) { return compare(self, 0, self.length, other, 0, other.length); } /* * @dev Returns a positive number if `other` comes lexicographically after * `self`, a negative number if it comes before, or zero if the * contents of the two bytes are equal. Comparison is done per-rune, * on unicode codepoints. * @param self The first bytes to compare. * @param offset The offset of self. * @param len The length of self. * @param other The second bytes to compare. * @param otheroffset The offset of the other string. * @param otherlen The length of the other string. * @return The result of the comparison. */ function compare(bytes memory self, uint offset, uint len, bytes memory other, uint otheroffset, uint otherlen) internal pure returns (int) { uint shortest = len; if (otherlen < len) shortest = otherlen; uint selfptr; uint otherptr; assembly { selfptr := add(self, add(offset, 32)) otherptr := add(other, add(otheroffset, 32)) } for (uint idx = 0; idx < shortest; idx += 32) { uint a; uint b; assembly { a := mload(selfptr) b := mload(otherptr) } if (a != b) { // Mask out irrelevant bytes and check again uint mask; if (shortest > 32) { mask = type(uint256).max; } else { mask = ~(2 ** (8 * (32 - shortest + idx)) - 1); } int diff = int(a & mask) - int(b & mask); if (diff != 0) return diff; } selfptr += 32; otherptr += 32; } return int(len) - int(otherlen); } /* * @dev Returns true if the two byte ranges are equal. * @param self The first byte range to compare. * @param offset The offset into the first byte range. * @param other The second byte range to compare. * @param otherOffset The offset into the second byte range. * @param len The number of bytes to compare * @return True if the byte ranges are equal, false otherwise. */ function equals(bytes memory self, uint offset, bytes memory other, uint otherOffset, uint len) internal pure returns (bool) { return keccak(self, offset, len) == keccak(other, otherOffset, len); } /* * @dev Returns true if the two byte ranges are equal with offsets. * @param self The first byte range to compare. * @param offset The offset into the first byte range. * @param other The second byte range to compare. * @param otherOffset The offset into the second byte range. * @return True if the byte ranges are equal, false otherwise. */ function equals(bytes memory self, uint offset, bytes memory other, uint otherOffset) internal pure returns (bool) { return keccak(self, offset, self.length - offset) == keccak(other, otherOffset, other.length - otherOffset); } /* * @dev Compares a range of 'self' to all of 'other' and returns True iff * they are equal. * @param self The first byte range to compare. * @param offset The offset into the first byte range. * @param other The second byte range to compare. * @return True if the byte ranges are equal, false otherwise. */ function equals(bytes memory self, uint offset, bytes memory other) internal pure returns (bool) { return self.length >= offset + other.length && equals(self, offset, other, 0, other.length); } /* * @dev Returns true if the two byte ranges are equal. * @param self The first byte range to compare. * @param other The second byte range to compare. * @return True if the byte ranges are equal, false otherwise. */ function equals(bytes memory self, bytes memory other) internal pure returns(bool) { return self.length == other.length && equals(self, 0, other, 0, self.length); } /* * @dev Returns the 8-bit number at the specified index of self. * @param self The byte string. * @param idx The index into the bytes * @return The specified 8 bits of the string, interpreted as an integer. */ function readUint8(bytes memory self, uint idx) internal pure returns (uint8 ret) { return uint8(self[idx]); } /* * @dev Returns the 16-bit number at the specified index of self. * @param self The byte string. * @param idx The index into the bytes * @return The specified 16 bits of the string, interpreted as an integer. */ function readUint16(bytes memory self, uint idx) internal pure returns (uint16 ret) { require(idx + 2 <= self.length); assembly { ret := and(mload(add(add(self, 2), idx)), 0xFFFF) } } /* * @dev Returns the 32-bit number at the specified index of self. * @param self The byte string. * @param idx The index into the bytes * @return The specified 32 bits of the string, interpreted as an integer. */ function readUint32(bytes memory self, uint idx) internal pure returns (uint32 ret) { require(idx + 4 <= self.length); assembly { ret := and(mload(add(add(self, 4), idx)), 0xFFFFFFFF) } } /* * @dev Returns the 32 byte value at the specified index of self. * @param self The byte string. * @param idx The index into the bytes * @return The specified 32 bytes of the string. */ function readBytes32(bytes memory self, uint idx) internal pure returns (bytes32 ret) { require(idx + 32 <= self.length); assembly { ret := mload(add(add(self, 32), idx)) } } /* * @dev Returns the 32 byte value at the specified index of self. * @param self The byte string. * @param idx The index into the bytes * @return The specified 32 bytes of the string. */ function readBytes20(bytes memory self, uint idx) internal pure returns (bytes20 ret) { require(idx + 20 <= self.length); assembly { ret := and(mload(add(add(self, 32), idx)), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000) } } /* * @dev Returns the n byte value at the specified index of self. * @param self The byte string. * @param idx The index into the bytes. * @param len The number of bytes. * @return The specified 32 bytes of the string. */ function readBytesN(bytes memory self, uint idx, uint len) internal pure returns (bytes32 ret) { require(len <= 32); require(idx + len <= self.length); assembly { let mask := not(sub(exp(256, sub(32, len)), 1)) ret := and(mload(add(add(self, 32), idx)), mask) } } function memcpy(uint dest, uint src, uint len) private pure { // Copy word-length chunks while possible for (; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } // Copy remaining bytes unchecked { uint mask = (256 ** (32 - len)) - 1; assembly { let srcpart := and(mload(src), not(mask)) let destpart := and(mload(dest), mask) mstore(dest, or(destpart, srcpart)) } } } /* * @dev Copies a substring into a new byte string. * @param self The byte string to copy from. * @param offset The offset to start copying at. * @param len The number of bytes to copy. */ function substring(bytes memory self, uint offset, uint len) internal pure returns(bytes memory) { require(offset + len <= self.length); bytes memory ret = new bytes(len); uint dest; uint src; assembly { dest := add(ret, 32) src := add(add(self, 32), offset) } memcpy(dest, src, len); return ret; } // Maps characters from 0x30 to 0x7A to their base32 values. // 0xFF represents invalid characters in that range. bytes constant base32HexTable = hex'00010203040506070809FFFFFFFFFFFFFF0A0B0C0D0E0F101112131415161718191A1B1C1D1E1FFFFFFFFFFFFFFFFFFFFF0A0B0C0D0E0F101112131415161718191A1B1C1D1E1F'; /** * @dev Decodes unpadded base32 data of up to one word in length. * @param self The data to decode. * @param off Offset into the string to start at. * @param len Number of characters to decode. * @return The decoded data, left aligned. */ function base32HexDecodeWord(bytes memory self, uint off, uint len) internal pure returns(bytes32) { require(len <= 52); uint ret = 0; uint8 decoded; for(uint i = 0; i < len; i++) { bytes1 char = self[off + i]; require(char >= 0x30 && char <= 0x7A); decoded = uint8(base32HexTable[uint(uint8(char)) - 0x30]); require(decoded <= 0x20); if(i == len - 1) { break; } ret = (ret << 5) | decoded; } uint bitlen = len * 5; if(len % 8 == 0) { // Multiple of 8 characters, no padding ret = (ret << 5) | decoded; } else if(len % 8 == 2) { // Two extra characters - 1 byte ret = (ret << 3) | (decoded >> 2); bitlen -= 2; } else if(len % 8 == 4) { // Four extra characters - 2 bytes ret = (ret << 1) | (decoded >> 4); bitlen -= 4; } else if(len % 8 == 5) { // Five extra characters - 3 bytes ret = (ret << 4) | (decoded >> 1); bitlen -= 1; } else if(len % 8 == 7) { // Seven extra characters - 4 bytes ret = (ret << 2) | (decoded >> 3); bitlen -= 3; } else { revert(); } return bytes32(ret << (256 - bitlen)); } }
pragma solidity ^0.8.4; /** * @dev A library for working with mutable byte buffers in Solidity. * * Byte buffers are mutable and expandable, and provide a variety of primitives * for writing to them. At any time you can fetch a bytes object containing the * current contents of the buffer. The bytes object should not be stored between * operations, as it may change due to resizing of the buffer. */ library Buffer { /** * @dev Represents a mutable buffer. Buffers have a current value (buf) and * a capacity. The capacity may be longer than the current value, in * which case it can be extended without the need to allocate more memory. */ struct buffer { bytes buf; uint capacity; } /** * @dev Initializes a buffer with an initial capacity. * @param buf The buffer to initialize. * @param capacity The number of bytes of space to allocate the buffer. * @return The buffer, for chaining. */ function init(buffer memory buf, uint capacity) internal pure returns(buffer memory) { if (capacity % 32 != 0) { capacity += 32 - (capacity % 32); } // Allocate space for the buffer data buf.capacity = capacity; assembly { let ptr := mload(0x40) mstore(buf, ptr) mstore(ptr, 0) mstore(0x40, add(32, add(ptr, capacity))) } return buf; } /** * @dev Initializes a new buffer from an existing bytes object. * Changes to the buffer may mutate the original value. * @param b The bytes object to initialize the buffer with. * @return A new buffer. */ function fromBytes(bytes memory b) internal pure returns(buffer memory) { buffer memory buf; buf.buf = b; buf.capacity = b.length; return buf; } function resize(buffer memory buf, uint capacity) private pure { bytes memory oldbuf = buf.buf; init(buf, capacity); append(buf, oldbuf); } function max(uint a, uint b) private pure returns(uint) { if (a > b) { return a; } return b; } /** * @dev Sets buffer length to 0. * @param buf The buffer to truncate. * @return The original buffer, for chaining.. */ function truncate(buffer memory buf) internal pure returns (buffer memory) { assembly { let bufptr := mload(buf) mstore(bufptr, 0) } return buf; } /** * @dev Writes a byte string to a buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param off The start offset to write to. * @param data The data to append. * @param len The number of bytes to copy. * @return The original buffer, for chaining. */ function write(buffer memory buf, uint off, bytes memory data, uint len) internal pure returns(buffer memory) { require(len <= data.length); if (off + len > buf.capacity) { resize(buf, max(buf.capacity, len + off) * 2); } uint dest; uint src; assembly { // Memory address of the buffer data let bufptr := mload(buf) // Length of existing buffer data let buflen := mload(bufptr) // Start address = buffer address + offset + sizeof(buffer length) dest := add(add(bufptr, 32), off) // Update buffer length if we're extending it if gt(add(len, off), buflen) { mstore(bufptr, add(len, off)) } src := add(data, 32) } // Copy word-length chunks while possible for (; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } // Copy remaining bytes unchecked { uint mask = (256 ** (32 - len)) - 1; assembly { let srcpart := and(mload(src), not(mask)) let destpart := and(mload(dest), mask) mstore(dest, or(destpart, srcpart)) } } return buf; } /** * @dev Appends a byte string to a buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @param len The number of bytes to copy. * @return The original buffer, for chaining. */ function append(buffer memory buf, bytes memory data, uint len) internal pure returns (buffer memory) { return write(buf, buf.buf.length, data, len); } /** * @dev Appends a byte string to a buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chaining. */ function append(buffer memory buf, bytes memory data) internal pure returns (buffer memory) { return write(buf, buf.buf.length, data, data.length); } /** * @dev Writes a byte to the buffer. Resizes if doing so would exceed the * capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write the byte at. * @param data The data to append. * @return The original buffer, for chaining. */ function writeUint8(buffer memory buf, uint off, uint8 data) internal pure returns(buffer memory) { if (off >= buf.capacity) { resize(buf, buf.capacity * 2); } assembly { // Memory address of the buffer data let bufptr := mload(buf) // Length of existing buffer data let buflen := mload(bufptr) // Address = buffer address + sizeof(buffer length) + off let dest := add(add(bufptr, off), 32) mstore8(dest, data) // Update buffer length if we extended it if eq(off, buflen) { mstore(bufptr, add(buflen, 1)) } } return buf; } /** * @dev Appends a byte to the buffer. Resizes if doing so would exceed the * capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chaining. */ function appendUint8(buffer memory buf, uint8 data) internal pure returns(buffer memory) { return writeUint8(buf, buf.buf.length, data); } /** * @dev Writes up to 32 bytes to the buffer. Resizes if doing so would * exceed the capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write at. * @param data The data to append. * @param len The number of bytes to write (left-aligned). * @return The original buffer, for chaining. */ function write(buffer memory buf, uint off, bytes32 data, uint len) private pure returns(buffer memory) { if (len + off > buf.capacity) { resize(buf, (len + off) * 2); } unchecked { uint mask = (256 ** len) - 1; // Right-align data data = data >> (8 * (32 - len)); assembly { // Memory address of the buffer data let bufptr := mload(buf) // Address = buffer address + sizeof(buffer length) + off + len let dest := add(add(bufptr, off), len) mstore(dest, or(and(mload(dest), not(mask)), data)) // Update buffer length if we extended it if gt(add(off, len), mload(bufptr)) { mstore(bufptr, add(off, len)) } } } return buf; } /** * @dev Writes a bytes20 to the buffer. Resizes if doing so would exceed the * capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write at. * @param data The data to append. * @return The original buffer, for chaining. */ function writeBytes20(buffer memory buf, uint off, bytes20 data) internal pure returns (buffer memory) { return write(buf, off, bytes32(data), 20); } /** * @dev Appends a bytes20 to the buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chhaining. */ function appendBytes20(buffer memory buf, bytes20 data) internal pure returns (buffer memory) { return write(buf, buf.buf.length, bytes32(data), 20); } /** * @dev Appends a bytes32 to the buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chaining. */ function appendBytes32(buffer memory buf, bytes32 data) internal pure returns (buffer memory) { return write(buf, buf.buf.length, data, 32); } /** * @dev Writes an integer to the buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write at. * @param data The data to append. * @param len The number of bytes to write (right-aligned). * @return The original buffer, for chaining. */ function writeInt(buffer memory buf, uint off, uint data, uint len) private pure returns(buffer memory) { if (len + off > buf.capacity) { resize(buf, (len + off) * 2); } uint mask = (256 ** len) - 1; assembly { // Memory address of the buffer data let bufptr := mload(buf) // Address = buffer address + off + sizeof(buffer length) + len let dest := add(add(bufptr, off), len) mstore(dest, or(and(mload(dest), not(mask)), data)) // Update buffer length if we extended it if gt(add(off, len), mload(bufptr)) { mstore(bufptr, add(off, len)) } } return buf; } /** * @dev Appends a byte to the end of the buffer. Resizes if doing so would * exceed the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer. */ function appendInt(buffer memory buf, uint data, uint len) internal pure returns(buffer memory) { return writeInt(buf, buf.buf.length, data, len); } }
// SPDX-License-Identifier: MIT 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() { _setOwner(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _setOwner(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"); _setOwner(newOwner); } function _setOwner(address newOwner) private { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IERC721.sol"; import "./IERC721Receiver.sol"; import "./extensions/IERC721Metadata.sol"; import "../../utils/Address.sol"; import "../../utils/Context.sol"; import "../../utils/Strings.sol"; import "../../utils/introspection/ERC165.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: balance query for the zero address"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: owner query for nonexistent token"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overriden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { require(operator != _msgSender(), "ERC721: approve to caller"); _operatorApprovals[_msgSender()][operator] = approved; emit ApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _safeTransfer(from, to, tokenId, _data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `_data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory _data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _owners[tokenId] != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ERC721.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory _data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _balances[to] += 1; _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _balances[owner] -= 1; delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _balances[from] -= 1; _balances[to] += 1; _owners[tokenId] = to; emit Transfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; /** * @title ISDaoRegistrar interface * @notice A registrar that allows registrations in the DAO. * The registrar holds an ENS subdomain of the .eth domain, e.g. 'example.eth'. * * A registration allocates one ENS subdomain of the root subdomain, e.g. 'myname.example.eth' to an address. * * The registrations from the public `register` method can be restricted by the owner of the contract. */ interface ISDaoRegistrar { /** * @dev Emitted when a new name is registered through standard registration or claiming. */ event NameRegistered( uint256 indexed id, string label, address indexed owner, address indexed registrant ); /** * @dev Emitted when the root domain ownership is transferred to a new address. */ event DomainOwnershipTransferred(address indexed owner); /** * @dev Emitted when the public registration is restricted. */ event Restricted(); /** * @dev Emitted when the public registration is open. */ event Unrestricted(); /** * @notice Register a name. * @param label The label to register. * * Emits a {NameRegistered} event. */ function register(string memory label) external; /** * @notice Transfer the root domain ownership of the SDAO Registrar to a new owner. * * Emits a {DomainOwnershipTransfered} event. */ function transferDomainOwnership(address newDomainOwner) external; /** * @notice Restrict registration. * * Emits a {Restricted} event. */ function restrictRegistration() external; /** * @notice Open registration. * * Emits a {Unrestricted} event. */ function openRegistration() external; }
// SPDX-License-Identifier: MIT 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 pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @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] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT 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 pragma solidity >=0.8.4; import {ISDaoRegistrar} from '../../ISDaoRegistrar.sol'; /** * @title ISDaoRegistrarLimited interface. * @notice An optional extension introducing a controlled limit on the number of registrations. */ interface ISDaoRegistrarLimited is ISDaoRegistrar { /** * @dev Emitted when the registration limit is updated. */ event RegistrationLimitUpdated(uint256 registrationLimit); /** * @notice Update registration limit. * @param registrationLimit The new registration limit. * * Emits a {RegistrationLimitUpdated} event. */ function updateRegistrationLimit(uint256 registrationLimit) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import {ISDaoRegistrar} from '../../ISDaoRegistrar.sol'; /** * @title ISDaoRegistrarReserved interface. * @notice An optional extension introducing a controlled reservation period. * Within the registration period, only the owners of the associated .eth subdomain may register this subdomain. */ interface ISDaoRegistrarReserved is ISDaoRegistrar { /** * @dev Emitted when the reservation duration is updated. */ event ReservationDurationUpdated(uint256 reservationDuration); /** * @notice Update reservation duration. * * Emits a {ReservationDurationUpdated} event. */ function updateReservationDuration(uint256 reservationDuration) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import {ISDaoRegistrar} from '../../ISDaoRegistrar.sol'; /** * @title ISDaoRegistrarCodeAccessible interface. * @notice An optional extension introducing the registration with named access code. */ interface ISDaoRegistrarCodeAccessible is ISDaoRegistrar { /** * @dev Emitted when an access code is consumed. */ event AccessCodeConsumed(uint256 groupId, bytes accessCode); /** * @dev Emitted when the code signer is updated. */ event CodeSignerUpdated(address codeSigner); /** * @notice Register a name and mints. * @param label The label to register. * @param recipient Address of the recipient of the registration. * @param accessCode The EIP712 signature corresponding to a groupId and the recipient address. * * Emits a {AccessCodeConsumed} and a {NameRegistered} events. */ function registerWithAccessCode( string memory label, address recipient, bytes memory accessCode ) external; /** * @notice Update the code signer. * @param codeSigner The address of the code signer. * * Emits a {CodeSignerUpdated} event. */ function updateCodeSigner(address codeSigner) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @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 } 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"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' 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) { // Check the signature length // - case 65: r,s,v signature (standard) // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._ 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. 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 if (signature.length == 64) { bytes32 r; bytes32 vs; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) vs := mload(add(signature, 0x40)) } return tryRecover(hash, r, vs); } 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; uint8 v; assembly { s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) v := add(shr(255, vs), 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 (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // 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 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)); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "berlin", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract ENS","name":"ensAddr","type":"address"},{"internalType":"contract PublicResolver","name":"resolver","type":"address"},{"internalType":"contract IERC1155Minter","name":"erc1155Token","type":"address"},{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"reservationDuration","type":"uint256"},{"internalType":"uint256","name":"registrationLimit","type":"uint256"},{"internalType":"uint256","name":"groupId","type":"uint256"},{"internalType":"address","name":"codeSigner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"groupId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"accessCode","type":"bytes"}],"name":"AccessCodeConsumed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"codeSigner","type":"address"}],"name":"CodeSignerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"DomainOwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"gen","type":"uint256"}],"name":"GenUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"groupId","type":"uint256"}],"name":"GroupIdUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"string","name":"label","type":"string"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"registrant","type":"address"}],"name":"NameRegistered","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":"uint256","name":"registrationLimit","type":"uint256"}],"name":"RegistrationLimitUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reservationDuration","type":"uint256"}],"name":"ReservationDurationUpdated","type":"event"},{"anonymous":false,"inputs":[],"name":"Restricted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"tokenData","type":"bytes"}],"name":"TokenDataUpdated","type":"event"},{"anonymous":false,"inputs":[],"name":"Unrestricted","type":"event"},{"inputs":[],"name":"DAO_BIRTH_DATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ENS_REGISTRY","outputs":[{"internalType":"contract ENS","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERC1155_MINTER","outputs":[{"internalType":"contract IERC1155Minter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETH_NODE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RESOLVER","outputs":[{"internalType":"contract PublicResolver","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROOT_NODE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_codeSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"_consumed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_counter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_gen","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_groupId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_maxGenReached","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_registrationLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_reservationDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_restricted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_tokenData","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"openRegistration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"label","type":"string"}],"name":"register","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"label","type":"string"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bytes","name":"accessCode","type":"bytes"}],"name":"registerWithAccessCode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"restrictRegistration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newDomainOwner","type":"address"}],"name":"transferDomainOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"registrationLimit","type":"uint256"},{"internalType":"uint256","name":"gen","type":"uint256"},{"internalType":"uint256","name":"groupId","type":"uint256"},{"internalType":"bytes","name":"tokenData","type":"bytes"}],"name":"transitToGeneration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"codeSigner","type":"address"}],"name":"updateCodeSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"gen","type":"uint256"}],"name":"updateGeneration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"groupId","type":"uint256"}],"name":"updateGroupId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"registrationLimit","type":"uint256"}],"name":"updateRegistrationLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"reservationDuration","type":"uint256"}],"name":"updateReservationDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"tokenData","type":"bytes"}],"name":"updateTokenData","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101406040526000805460ff60a01b191690553480156200001f57600080fd5b5060405162002afe38038062002afe83398101604081905262000042916200047f565b604051806040016040528060058152602001645369736d6f60d81b815250604051806040016040528060038152602001620312e360ec1b815250828987878e8e8d8d6200009e620000986200021660201b60201c565b6200021a565b6001600160601b0319606085811b821660a05284901b1660805260c0829052620000c8816200026a565b505050600191909155504260e0526003556001600160a01b0381166200015b5760405162461bcd60e51b815260206004820152603860248201527f5344414f5f5245474953545241525f455243313135355f47454e455241544f5260448201527f3a20494e56414c49445f4552433732315f41444452455353000000000000000060648201526084015b60405180910390fd5b6001600160601b0319606091821b16610100526040805160808101825285815260208101859052469181019190915230918101919091526200019d906200033b565b610120526000805460ff60a01b1916600160a01b178155600580546001600160a01b039093166001600160a01b0319909316929092179091556006859055604080516020810191829052829052620001fb93506009925090620003d9565b50506001600781905560085550620005799650505050505050565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000546001600160a01b03163314620002c65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000152565b6001600160a01b0381166200032d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000152565b62000338816200021a565b50565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f82600001518051906020012083602001518051906020012084604001518560600151604051602001620003bc9594939291909485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b604051602081830303815290604052805190602001209050919050565b828054620003e79062000526565b90600052602060002090601f0160209004810192826200040b576000855562000456565b82601f106200042657805160ff191683800117855562000456565b8280016001018555821562000456579182015b828111156200045657825182559160200191906001019062000439565b506200046492915062000468565b5090565b5b8082111562000464576000815560010162000469565b60008060008060008060008060006101208a8c0312156200049e578485fd5b8951620004ab8162000563565b60208b0151909950620004be8162000563565b60408b0151909850620004d18162000563565b60608b015160808c01519198509650620004eb8162000563565b8095505060a08a0151935060c08a0151925060e08a015191506101008a0151620005158162000563565b809150509295985092959850929598565b600181811c908216806200053b57607f821691505b602082108114156200055d57634e487b7160e01b600052602260045260246000fd5b50919050565b6001600160a01b03811681146200033857600080fd5b60805160601c60a05160601c60c05160e0516101005160601c610120516124bc620006426000396000610bcb0152600081816102ff015281816117890152611c4a0152600081816102bf015281816105c5015261192b015260008181610220015281816106d301528181610f7e01528181610ff90152818161113401526112880152600081816103420152818161070901528181610fca0152818161119e015281816112c5015261195901526000818161025a0152818161116f015261121d01526124bc6000f3fe608060405234801561001057600080fd5b50600436106101e55760003560e01c80638da5cb5b1161010f578063e2b33abb116100a2578063f4ff1f9f11610071578063f4ff1f9f14610489578063f654f7c714610492578063f93da193146104a5578063fdd4c437146104b857600080fd5b8063e2b33abb1461042b578063ec2bc3541461044e578063f2c298be14610463578063f2fde38b1461047657600080fd5b8063b28c0eec116100de578063b28c0eec1461039a578063cc473be3146103be578063d06e4ee714610410578063d631931a1461041857600080fd5b80638da5cb5b146103645780639adac29b14610375578063a106a73014610388578063ad2c68841461039157600080fd5b806356ddb853116101875780637aafdd65116101565780637aafdd65146102fa5780637cd49fde14610321578063831441bc1461032a57806385e969171461033d57600080fd5b806356ddb853146102ba5780636302fbc7146102e15780636737762a146102e9578063715018a6146102f257600080fd5b80634b206217116101c35780634b206217146102425780634d77532d146102555780635393240e1461029457806354bfc7e5146102a757600080fd5b80630c568e06146101ea57806344944540146102065780634a9fe1c71461021b575b600080fd5b6101f360065481565b6040519081526020015b60405180910390f35b610219610214366004612097565b6104cb565b005b6101f37f000000000000000000000000000000000000000000000000000000000000000081565b6102196102503660046121ca565b61050a565b61027c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016101fd565b6102196102a2366004612097565b610595565b6102196102b5366004611fb7565b61069a565b6101f37f000000000000000000000000000000000000000000000000000000000000000081565b61021961079c565b6101f360015481565b610219610802565b61027c7f000000000000000000000000000000000000000000000000000000000000000081565b6101f360025481565b610219610338366004612097565b610838565b61027c7f000000000000000000000000000000000000000000000000000000000000000081565b6000546001600160a01b031661027c565b60055461027c906001600160a01b031681565b6101f360085481565b6101f360035481565b6000546103ae90600160a01b900460ff1681565b60405190151581526020016101fd565b6101f360408051600060208201527f4f5b812789fc606be1b3b16908db13fc7a9adf7ca72641f84d75b47069d3d7f0918101919091526060016040516020818303038152906040528051906020012081565b61021961086b565b610219610426366004611fb7565b6108cb565b6103ae610439366004612097565b60046020526000908152604090205460ff1681565b610456610943565b6040516101fd919061232e565b610219610471366004612107565b6109d1565b610219610484366004611fb7565b610a45565b6101f360075481565b6102196104a03660046120c7565b610add565b6102196104b3366004612097565b610b4a565b6102196104c6366004612142565b610b7d565b6000546001600160a01b031633146104fe5760405162461bcd60e51b81526004016104f590612341565b60405180910390fd5b61050781610db5565b50565b6000546001600160a01b031633146105345760405162461bcd60e51b81526004016104f590612341565b61053d84610db5565b61054685610dfa565b61054f83610ea0565b61058e82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ed592505050565b5050505050565b6000546001600160a01b031633146105bf5760405162461bcd60e51b81526004016104f590612341565b806105ea7f0000000000000000000000000000000000000000000000000000000000000000426123d8565b101561065e5760405162461bcd60e51b815260206004820152603b60248201527f5344414f5f5245474953545241525f52455345525645443a204e45575f52455360448201527f4552564154494f4e5f4455524154494f4e5f544f4f5f53484f5254000000000060648201526084016104f5565b60038190556040518181527feacba3a202f7b555213f324c322315b7f103096934a8261be08fbd478cb2d5cd906020015b60405180910390a150565b6000546001600160a01b031633146106c45760405162461bcd60e51b81526004016104f590612341565b604051635b0fc9c360e01b81527f000000000000000000000000000000000000000000000000000000000000000060048201526001600160a01b0382811660248301527f00000000000000000000000000000000000000000000000000000000000000001690635b0fc9c390604401600060405180830381600087803b15801561074d57600080fd5b505af1158015610761573d6000803e3d6000fd5b50506040516001600160a01b03841692507f80876669255bbe670102b94465f3622bfeaf7c469f8d25da3f9492fda77be2189150600090a250565b6000546001600160a01b031633146107c65760405162461bcd60e51b81526004016104f590612341565b6000805460ff60a01b1916600160a01b1781556040517fccc08913caa4d04144e0e33d08ba51f4325e7abd29d1c782a78fc145c630b8fe9190a1565b6000546001600160a01b0316331461082c5760405162461bcd60e51b81526004016104f590612341565b6108366000610f17565b565b6000546001600160a01b031633146108625760405162461bcd60e51b81526004016104f590612341565b61050781610dfa565b6000546001600160a01b031633146108955760405162461bcd60e51b81526004016104f590612341565b6000805460ff60a01b191681556040517f454c32e1ec7ff1f33e92430b5b0a167eb2012027c86dddf862de5577d2c0d9ad9190a1565b6000546001600160a01b031633146108f55760405162461bcd60e51b81526004016104f590612341565b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527ffa5505bcea7e8bf8a7d3cfa219d1ce29f585dd93937a6ea92d65722fffba4f859060200161068f565b60098054610950906123ef565b80601f016020809104026020016040519081016040528092919081815260200182805461097c906123ef565b80156109c95780601f1061099e576101008083540402835291602001916109c9565b820191906000526020600020905b8154815290600101906020018083116109ac57829003601f168201915b505050505081565b600054600160a01b900460ff1615610a3b5760405162461bcd60e51b815260206004820152602760248201527f5344414f5f5245474953545241523a20524553545249435445445f52454749536044820152662a2920aa24a7a760c91b60648201526084016104f5565b6105073382610f67565b6000546001600160a01b03163314610a6f5760405162461bcd60e51b81526004016104f590612341565b6001600160a01b038116610ad45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104f5565b61050781610f17565b6000546001600160a01b03163314610b075760405162461bcd60e51b81526004016104f590612341565b610b4682828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ed592505050565b5050565b6000546001600160a01b03163314610b745760405162461bcd60e51b81526004016104f590612341565b61050781610ea0565b6000610b8860065490565b604080518082019091526001600160a01b0385168152602081018290529091506000610c12610bb6836113a4565b6040805161190160f01b6020808301919091527f00000000000000000000000000000000000000000000000000000000000000006022830152604280830194909452825180830390940184526062909101909152815191012090565b60008181526004602052604090205490915060ff1615610ca85760405162461bcd60e51b8152602060048201526044602482018190527f5344414f5f5245474953545241525f4c494d495445445f434f44455f41434345908201527f535349424c453a204143434553535f434f44455f414c52454144595f434f4e536064820152631553515160e21b608482015260a4016104f5565b6005546001600160a01b0316610cbe8286611417565b6001600160a01b031614610d505760405162461bcd60e51b815260206004820152604d60248201527f5344414f5f5245474953545241525f4c494d495445445f434f44455f4143434560448201527f535349424c453a20494e56414c49445f4143434553535f434f4445204f52204960648201526c272b20a624a22fa9a2a72222a960991b608482015260a4016104f5565b610d5a8587610f67565b60008181526004602052604090819020805460ff19166001179055517f1fdf9002ebee4e268bab8c98f71c01022c9646c8b80e74365b8ae5a45293cb9c90610da59085908790612376565b60405180910390a1505050505050565b6007819055600854811115610dca5760088190555b6040518181527f10ae1abf8a69e09c092011dd84e508bc9ecbaf7894dd7d50b710be21372546699060200161068f565b600254811015610e6b5760405162461bcd60e51b815260206004820152603660248201527f5344414f5f5245474953545241525f4c494d495445443a204e45575f524547496044820152755354524154494f4e5f4c494d49545f544f4f5f4c4f5760501b60648201526084016104f5565b60018190556040518181527ff7af309301a686ddde7a6fc31c6911b5ea30a61f4139761c53949d679093bfd69060200161068f565b60068190556040518181527f9c38cfa39c08c0d55650101f668d291bfd2be949224f75cbe2e2279e63f207da9060200161068f565b8051610ee8906009906020840190611e60565b507e824c914528ffda4a1403904414c0879200004ca0234aaa4733134f927daa048160405161068f919061232e565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516020820120610f78838261143b565b604080517f0000000000000000000000000000000000000000000000000000000000000000602082015290810182905260009060600160405160208183030381529060405280519060200120905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166302571be37f000000000000000000000000000000000000000000000000000000000000000085604051602001611033929190918252602082015260400190565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b815260040161106791815260200190565b60206040518083038186803b15801561107f57600080fd5b505afa158015611093573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110b79190611fd3565b90506001600160a01b038116156111255760405162461bcd60e51b815260206004820152602c60248201527f5344414f5f5245474953545241523a20535542444f4d41494e5f414c5245414460448201526b1657d49151d254d51154915160a21b60648201526084016104f5565b6040516305ef2c7f60e41b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018490523060448201526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166064830152600060848301527f00000000000000000000000000000000000000000000000000000000000000001690635ef2c7f09060a401600060405180830381600087803b1580156111e257600080fd5b505af11580156111f6573d6000803e3d6000fd5b505060405162d5fa2b60e81b8152600481018590526001600160a01b0388811660248301527f000000000000000000000000000000000000000000000000000000000000000016925063d5fa2b009150604401600060405180830381600087803b15801561126357600080fd5b505af1158015611277573d6000803e3d6000fd5b50506040516306ab592360e01b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018690526001600160a01b0388811660448301527f00000000000000000000000000000000000000000000000000000000000000001692506306ab59239150606401602060405180830381600087803b15801561130b57600080fd5b505af115801561131f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134391906120af565b5061134e8584611445565b336001600160a01b0316856001600160a01b03168360001c7f1c8f8391e4953ccc2d4fad9ee0694fbee8d1766978c78d20b2ed060e455b4c9b87604051611395919061232e565b60405180910390a45050505050565b80516020808301516040516000936113fa937f5098faa4e4d97f1adf64bd7066c22dd2c4a20b86e7fb5deeb9f397eaeda6344d939192019283526001600160a01b03919091166020830152604082015260600190565b604051602081830303815290604052805190602001209050919050565b6000806000611426858561144f565b91509150611433816114bf565b509392505050565b610b4682826116c0565b610b468282611756565b6000808251604114156114865760208301516040840151606085015160001a61147a878285856117fd565b945094505050506114b8565b8251604014156114b057602083015160408401516114a58683836118ea565b9350935050506114b8565b506000905060025b9250929050565b60008160048111156114e157634e487b7160e01b600052602160045260246000fd5b14156114ea5750565b600181600481111561150c57634e487b7160e01b600052602160045260246000fd5b141561155a5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016104f5565b600281600481111561157c57634e487b7160e01b600052602160045260246000fd5b14156115ca5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016104f5565b60038160048111156115ec57634e487b7160e01b600052602160045260246000fd5b14156116455760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016104f5565b600481600481111561166757634e487b7160e01b600052602160045260246000fd5b14156105075760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016104f5565b6116ca8282611919565b6116d382611af2565b15806116ec57506000546001600160a01b038381169116145b610b465760405162461bcd60e51b815260206004820152603560248201527f5344414f5f5245474953545241525f455243313135355f47454e455241544f526044820152741d1020a62922a0a22cafaa27a5a2a72fa7aba722a960591b60648201526084016104f5565b6117608282611d36565b60008061176d8484611d52565b60405163731133e960e01b815291935091506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063731133e9906117c590879086906001908790600401612274565b600060405180830381600087803b1580156117df57600080fd5b505af11580156117f3573d6000803e3d6000fd5b5050505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561183457506000905060036118e1565b8460ff16601b1415801561184c57508460ff16601c14155b1561185d57506000905060046118e1565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156118b1573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166118da576000600192509250506118e1565b9150600090505b94509492505050565b6000806001600160ff1b03831660ff84901c601b0161190b878288856117fd565b935093505050935093915050565b6119238282611df2565b6003546119507f0000000000000000000000000000000000000000000000000000000000000000426123d8565b11610b465760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166302571be36000801b7f4f5b812789fc606be1b3b16908db13fc7a9adf7ca72641f84d75b47069d3d7f06040516020016119c5929190918252602082015260400190565b60408051601f198184030181528282528051602091820120908301528101859052606001604051602081830303815290604052805190602001206040518263ffffffff1660e01b8152600401611a1d91815260200190565b60206040518083038186803b158015611a3557600080fd5b505afa158015611a49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a6d9190611fd3565b90506001600160a01b0381161580611a8d57506001600160a01b03811633145b611aed5760405162461bcd60e51b815260206004820152602b60248201527f5344414f5f5245474953545241525f52455345525645443a20535542444f4d4160448201526a125397d49154d15495915160aa1b60648201526084016104f5565b505050565b60008060085467ffffffffffffffff811115611b1e57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611b47578160200160208202803683370190505b509050600060085467ffffffffffffffff811115611b7557634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611b9e578160200160208202803683370190505b50905060005b600854811015611c2f5784838281518110611bcf57634e487b7160e01b600052603260045260246000fd5b6001600160a01b0390921660209283029190910190910152611bf28160016123c0565b828281518110611c1257634e487b7160e01b600052603260045260246000fd5b602090810291909101015280611c278161242a565b915050611ba4565b506040516313849cfd60e21b81526000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690634e1273f490611c8190869086906004016122ab565b60006040518083038186803b158015611c9957600080fd5b505afa158015611cad573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611cd59190810190611fef565b90506000805b600854811015611d2c57828181518110611d0557634e487b7160e01b600052603260045260246000fd5b602002602001015182611d1891906123c0565b915080611d248161242a565b915050611cdb565b5095945050505050565b600160026000828254611d4991906123c0565b90915550505050565b600060606007546009808054611d67906123ef565b80601f0160208091040260200160405190810160405280929190818152602001828054611d93906123ef565b8015611de05780601f10611db557610100808354040283529160200191611de0565b820191906000526020600020905b815481529060010190602001808311611dc357829003601f168201915b50505050509050915091509250929050565b60015460025410610b465760405162461bcd60e51b815260206004820152603260248201527f5344414f5f5245474953545241525f4c494d495445443a205245474953545241604482015271151253d397d31253525517d4915050d2115160721b60648201526084016104f5565b828054611e6c906123ef565b90600052602060002090601f016020900481019282611e8e5760008555611ed4565b82601f10611ea757805160ff1916838001178555611ed4565b82800160010185558215611ed4579182015b82811115611ed4578251825591602001919060010190611eb9565b50611ee0929150611ee4565b5090565b5b80821115611ee05760008155600101611ee5565b600067ffffffffffffffff831115611f1357611f1361245b565b611f26601f8401601f191660200161238f565b9050828152838383011115611f3a57600080fd5b828260208301376000602084830101529392505050565b60008083601f840112611f62578182fd5b50813567ffffffffffffffff811115611f79578182fd5b6020830191508360208285010111156114b857600080fd5b600082601f830112611fa1578081fd5b611fb083833560208501611ef9565b9392505050565b600060208284031215611fc8578081fd5b8135611fb081612471565b600060208284031215611fe4578081fd5b8151611fb081612471565b60006020808385031215612001578182fd5b825167ffffffffffffffff80821115612018578384fd5b818501915085601f83011261202b578384fd5b81518181111561203d5761203d61245b565b8060051b915061204e84830161238f565b8181528481019084860184860187018a1015612068578788fd5b8795505b8386101561208a57805183526001959095019491860191860161206c565b5098975050505050505050565b6000602082840312156120a8578081fd5b5035919050565b6000602082840312156120c0578081fd5b5051919050565b600080602083850312156120d9578081fd5b823567ffffffffffffffff8111156120ef578182fd5b6120fb85828601611f51565b90969095509350505050565b600060208284031215612118578081fd5b813567ffffffffffffffff81111561212e578182fd5b61213a84828501611f91565b949350505050565b600080600060608486031215612156578081fd5b833567ffffffffffffffff8082111561216d578283fd5b61217987838801611f91565b94506020860135915061218b82612471565b909250604085013590808211156121a0578283fd5b508401601f810186136121b1578182fd5b6121c086823560208401611ef9565b9150509250925092565b6000806000806000608086880312156121e1578081fd5b853594506020860135935060408601359250606086013567ffffffffffffffff81111561220c578182fd5b61221888828901611f51565b969995985093965092949392505050565b60008151808452815b8181101561224e57602081850181015186830182015201612232565b8181111561225f5782602083870101525b50601f01601f19169290920160200192915050565b60018060a01b03851681528360208201528260408201526080606082015260006122a16080830184612229565b9695505050505050565b604080825283519082018190526000906020906060840190828701845b828110156122ed5781516001600160a01b0316845292840192908401906001016122c8565b50505083810382850152845180825285830191830190845b8181101561232157835183529284019291840191600101612305565b5090979650505050505050565b602081526000611fb06020830184612229565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b82815260406020820152600061213a6040830184612229565b604051601f8201601f1916810167ffffffffffffffff811182821017156123b8576123b861245b565b604052919050565b600082198211156123d3576123d3612445565b500190565b6000828210156123ea576123ea612445565b500390565b600181811c9082168061240357607f821691505b6020821081141561242457634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561243e5761243e612445565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461050757600080fdfea2646970667358221220aa6b01e167f45b8beec333abbed25bee068d369458d48f2c66ac93eca4e9c99464736f6c6343000804003300000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e0000000000000000000000004976fb03c32e5b8cfe2b6ccb31c09ba78ebaba41000000000000000000000000222c65d42871f3b68e140f6a0255df523cb8619c433c99d8edd0cf295e2314840cf7f62ca9b23c2d6004e72c706022297ae716ab000000000000000000000000e6acae0d7df3aa27e3a0353c8da8d6a784787249000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000001000000000000000000000000347f1341b91e362b9258fc2addfd498498c33436
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101e55760003560e01c80638da5cb5b1161010f578063e2b33abb116100a2578063f4ff1f9f11610071578063f4ff1f9f14610489578063f654f7c714610492578063f93da193146104a5578063fdd4c437146104b857600080fd5b8063e2b33abb1461042b578063ec2bc3541461044e578063f2c298be14610463578063f2fde38b1461047657600080fd5b8063b28c0eec116100de578063b28c0eec1461039a578063cc473be3146103be578063d06e4ee714610410578063d631931a1461041857600080fd5b80638da5cb5b146103645780639adac29b14610375578063a106a73014610388578063ad2c68841461039157600080fd5b806356ddb853116101875780637aafdd65116101565780637aafdd65146102fa5780637cd49fde14610321578063831441bc1461032a57806385e969171461033d57600080fd5b806356ddb853146102ba5780636302fbc7146102e15780636737762a146102e9578063715018a6146102f257600080fd5b80634b206217116101c35780634b206217146102425780634d77532d146102555780635393240e1461029457806354bfc7e5146102a757600080fd5b80630c568e06146101ea57806344944540146102065780634a9fe1c71461021b575b600080fd5b6101f360065481565b6040519081526020015b60405180910390f35b610219610214366004612097565b6104cb565b005b6101f37f433c99d8edd0cf295e2314840cf7f62ca9b23c2d6004e72c706022297ae716ab81565b6102196102503660046121ca565b61050a565b61027c7f0000000000000000000000004976fb03c32e5b8cfe2b6ccb31c09ba78ebaba4181565b6040516001600160a01b0390911681526020016101fd565b6102196102a2366004612097565b610595565b6102196102b5366004611fb7565b61069a565b6101f37f00000000000000000000000000000000000000000000000000000000619f7a9481565b61021961079c565b6101f360015481565b610219610802565b61027c7f000000000000000000000000222c65d42871f3b68e140f6a0255df523cb8619c81565b6101f360025481565b610219610338366004612097565b610838565b61027c7f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e81565b6000546001600160a01b031661027c565b60055461027c906001600160a01b031681565b6101f360085481565b6101f360035481565b6000546103ae90600160a01b900460ff1681565b60405190151581526020016101fd565b6101f360408051600060208201527f4f5b812789fc606be1b3b16908db13fc7a9adf7ca72641f84d75b47069d3d7f0918101919091526060016040516020818303038152906040528051906020012081565b61021961086b565b610219610426366004611fb7565b6108cb565b6103ae610439366004612097565b60046020526000908152604090205460ff1681565b610456610943565b6040516101fd919061232e565b610219610471366004612107565b6109d1565b610219610484366004611fb7565b610a45565b6101f360075481565b6102196104a03660046120c7565b610add565b6102196104b3366004612097565b610b4a565b6102196104c6366004612142565b610b7d565b6000546001600160a01b031633146104fe5760405162461bcd60e51b81526004016104f590612341565b60405180910390fd5b61050781610db5565b50565b6000546001600160a01b031633146105345760405162461bcd60e51b81526004016104f590612341565b61053d84610db5565b61054685610dfa565b61054f83610ea0565b61058e82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ed592505050565b5050505050565b6000546001600160a01b031633146105bf5760405162461bcd60e51b81526004016104f590612341565b806105ea7f00000000000000000000000000000000000000000000000000000000619f7a94426123d8565b101561065e5760405162461bcd60e51b815260206004820152603b60248201527f5344414f5f5245474953545241525f52455345525645443a204e45575f52455360448201527f4552564154494f4e5f4455524154494f4e5f544f4f5f53484f5254000000000060648201526084016104f5565b60038190556040518181527feacba3a202f7b555213f324c322315b7f103096934a8261be08fbd478cb2d5cd906020015b60405180910390a150565b6000546001600160a01b031633146106c45760405162461bcd60e51b81526004016104f590612341565b604051635b0fc9c360e01b81527f433c99d8edd0cf295e2314840cf7f62ca9b23c2d6004e72c706022297ae716ab60048201526001600160a01b0382811660248301527f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e1690635b0fc9c390604401600060405180830381600087803b15801561074d57600080fd5b505af1158015610761573d6000803e3d6000fd5b50506040516001600160a01b03841692507f80876669255bbe670102b94465f3622bfeaf7c469f8d25da3f9492fda77be2189150600090a250565b6000546001600160a01b031633146107c65760405162461bcd60e51b81526004016104f590612341565b6000805460ff60a01b1916600160a01b1781556040517fccc08913caa4d04144e0e33d08ba51f4325e7abd29d1c782a78fc145c630b8fe9190a1565b6000546001600160a01b0316331461082c5760405162461bcd60e51b81526004016104f590612341565b6108366000610f17565b565b6000546001600160a01b031633146108625760405162461bcd60e51b81526004016104f590612341565b61050781610dfa565b6000546001600160a01b031633146108955760405162461bcd60e51b81526004016104f590612341565b6000805460ff60a01b191681556040517f454c32e1ec7ff1f33e92430b5b0a167eb2012027c86dddf862de5577d2c0d9ad9190a1565b6000546001600160a01b031633146108f55760405162461bcd60e51b81526004016104f590612341565b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527ffa5505bcea7e8bf8a7d3cfa219d1ce29f585dd93937a6ea92d65722fffba4f859060200161068f565b60098054610950906123ef565b80601f016020809104026020016040519081016040528092919081815260200182805461097c906123ef565b80156109c95780601f1061099e576101008083540402835291602001916109c9565b820191906000526020600020905b8154815290600101906020018083116109ac57829003601f168201915b505050505081565b600054600160a01b900460ff1615610a3b5760405162461bcd60e51b815260206004820152602760248201527f5344414f5f5245474953545241523a20524553545249435445445f52454749536044820152662a2920aa24a7a760c91b60648201526084016104f5565b6105073382610f67565b6000546001600160a01b03163314610a6f5760405162461bcd60e51b81526004016104f590612341565b6001600160a01b038116610ad45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104f5565b61050781610f17565b6000546001600160a01b03163314610b075760405162461bcd60e51b81526004016104f590612341565b610b4682828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ed592505050565b5050565b6000546001600160a01b03163314610b745760405162461bcd60e51b81526004016104f590612341565b61050781610ea0565b6000610b8860065490565b604080518082019091526001600160a01b0385168152602081018290529091506000610c12610bb6836113a4565b6040805161190160f01b6020808301919091527f29ee100b5ea8ec362037b07aa4298c244c115e7aab04fe044c4f06b95563f5ef6022830152604280830194909452825180830390940184526062909101909152815191012090565b60008181526004602052604090205490915060ff1615610ca85760405162461bcd60e51b8152602060048201526044602482018190527f5344414f5f5245474953545241525f4c494d495445445f434f44455f41434345908201527f535349424c453a204143434553535f434f44455f414c52454144595f434f4e536064820152631553515160e21b608482015260a4016104f5565b6005546001600160a01b0316610cbe8286611417565b6001600160a01b031614610d505760405162461bcd60e51b815260206004820152604d60248201527f5344414f5f5245474953545241525f4c494d495445445f434f44455f4143434560448201527f535349424c453a20494e56414c49445f4143434553535f434f4445204f52204960648201526c272b20a624a22fa9a2a72222a960991b608482015260a4016104f5565b610d5a8587610f67565b60008181526004602052604090819020805460ff19166001179055517f1fdf9002ebee4e268bab8c98f71c01022c9646c8b80e74365b8ae5a45293cb9c90610da59085908790612376565b60405180910390a1505050505050565b6007819055600854811115610dca5760088190555b6040518181527f10ae1abf8a69e09c092011dd84e508bc9ecbaf7894dd7d50b710be21372546699060200161068f565b600254811015610e6b5760405162461bcd60e51b815260206004820152603660248201527f5344414f5f5245474953545241525f4c494d495445443a204e45575f524547496044820152755354524154494f4e5f4c494d49545f544f4f5f4c4f5760501b60648201526084016104f5565b60018190556040518181527ff7af309301a686ddde7a6fc31c6911b5ea30a61f4139761c53949d679093bfd69060200161068f565b60068190556040518181527f9c38cfa39c08c0d55650101f668d291bfd2be949224f75cbe2e2279e63f207da9060200161068f565b8051610ee8906009906020840190611e60565b507e824c914528ffda4a1403904414c0879200004ca0234aaa4733134f927daa048160405161068f919061232e565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516020820120610f78838261143b565b604080517f433c99d8edd0cf295e2314840cf7f62ca9b23c2d6004e72c706022297ae716ab602082015290810182905260009060600160405160208183030381529060405280519060200120905060007f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e6001600160a01b03166302571be37f433c99d8edd0cf295e2314840cf7f62ca9b23c2d6004e72c706022297ae716ab85604051602001611033929190918252602082015260400190565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b815260040161106791815260200190565b60206040518083038186803b15801561107f57600080fd5b505afa158015611093573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110b79190611fd3565b90506001600160a01b038116156111255760405162461bcd60e51b815260206004820152602c60248201527f5344414f5f5245474953545241523a20535542444f4d41494e5f414c5245414460448201526b1657d49151d254d51154915160a21b60648201526084016104f5565b6040516305ef2c7f60e41b81527f433c99d8edd0cf295e2314840cf7f62ca9b23c2d6004e72c706022297ae716ab6004820152602481018490523060448201526001600160a01b037f0000000000000000000000004976fb03c32e5b8cfe2b6ccb31c09ba78ebaba4181166064830152600060848301527f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e1690635ef2c7f09060a401600060405180830381600087803b1580156111e257600080fd5b505af11580156111f6573d6000803e3d6000fd5b505060405162d5fa2b60e81b8152600481018590526001600160a01b0388811660248301527f0000000000000000000000004976fb03c32e5b8cfe2b6ccb31c09ba78ebaba4116925063d5fa2b009150604401600060405180830381600087803b15801561126357600080fd5b505af1158015611277573d6000803e3d6000fd5b50506040516306ab592360e01b81527f433c99d8edd0cf295e2314840cf7f62ca9b23c2d6004e72c706022297ae716ab6004820152602481018690526001600160a01b0388811660448301527f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e1692506306ab59239150606401602060405180830381600087803b15801561130b57600080fd5b505af115801561131f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134391906120af565b5061134e8584611445565b336001600160a01b0316856001600160a01b03168360001c7f1c8f8391e4953ccc2d4fad9ee0694fbee8d1766978c78d20b2ed060e455b4c9b87604051611395919061232e565b60405180910390a45050505050565b80516020808301516040516000936113fa937f5098faa4e4d97f1adf64bd7066c22dd2c4a20b86e7fb5deeb9f397eaeda6344d939192019283526001600160a01b03919091166020830152604082015260600190565b604051602081830303815290604052805190602001209050919050565b6000806000611426858561144f565b91509150611433816114bf565b509392505050565b610b4682826116c0565b610b468282611756565b6000808251604114156114865760208301516040840151606085015160001a61147a878285856117fd565b945094505050506114b8565b8251604014156114b057602083015160408401516114a58683836118ea565b9350935050506114b8565b506000905060025b9250929050565b60008160048111156114e157634e487b7160e01b600052602160045260246000fd5b14156114ea5750565b600181600481111561150c57634e487b7160e01b600052602160045260246000fd5b141561155a5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016104f5565b600281600481111561157c57634e487b7160e01b600052602160045260246000fd5b14156115ca5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016104f5565b60038160048111156115ec57634e487b7160e01b600052602160045260246000fd5b14156116455760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016104f5565b600481600481111561166757634e487b7160e01b600052602160045260246000fd5b14156105075760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016104f5565b6116ca8282611919565b6116d382611af2565b15806116ec57506000546001600160a01b038381169116145b610b465760405162461bcd60e51b815260206004820152603560248201527f5344414f5f5245474953545241525f455243313135355f47454e455241544f526044820152741d1020a62922a0a22cafaa27a5a2a72fa7aba722a960591b60648201526084016104f5565b6117608282611d36565b60008061176d8484611d52565b60405163731133e960e01b815291935091506001600160a01b037f000000000000000000000000222c65d42871f3b68e140f6a0255df523cb8619c169063731133e9906117c590879086906001908790600401612274565b600060405180830381600087803b1580156117df57600080fd5b505af11580156117f3573d6000803e3d6000fd5b5050505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561183457506000905060036118e1565b8460ff16601b1415801561184c57508460ff16601c14155b1561185d57506000905060046118e1565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156118b1573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166118da576000600192509250506118e1565b9150600090505b94509492505050565b6000806001600160ff1b03831660ff84901c601b0161190b878288856117fd565b935093505050935093915050565b6119238282611df2565b6003546119507f00000000000000000000000000000000000000000000000000000000619f7a94426123d8565b11610b465760007f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e6001600160a01b03166302571be36000801b7f4f5b812789fc606be1b3b16908db13fc7a9adf7ca72641f84d75b47069d3d7f06040516020016119c5929190918252602082015260400190565b60408051601f198184030181528282528051602091820120908301528101859052606001604051602081830303815290604052805190602001206040518263ffffffff1660e01b8152600401611a1d91815260200190565b60206040518083038186803b158015611a3557600080fd5b505afa158015611a49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a6d9190611fd3565b90506001600160a01b0381161580611a8d57506001600160a01b03811633145b611aed5760405162461bcd60e51b815260206004820152602b60248201527f5344414f5f5245474953545241525f52455345525645443a20535542444f4d4160448201526a125397d49154d15495915160aa1b60648201526084016104f5565b505050565b60008060085467ffffffffffffffff811115611b1e57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611b47578160200160208202803683370190505b509050600060085467ffffffffffffffff811115611b7557634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611b9e578160200160208202803683370190505b50905060005b600854811015611c2f5784838281518110611bcf57634e487b7160e01b600052603260045260246000fd5b6001600160a01b0390921660209283029190910190910152611bf28160016123c0565b828281518110611c1257634e487b7160e01b600052603260045260246000fd5b602090810291909101015280611c278161242a565b915050611ba4565b506040516313849cfd60e21b81526000906001600160a01b037f000000000000000000000000222c65d42871f3b68e140f6a0255df523cb8619c1690634e1273f490611c8190869086906004016122ab565b60006040518083038186803b158015611c9957600080fd5b505afa158015611cad573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611cd59190810190611fef565b90506000805b600854811015611d2c57828181518110611d0557634e487b7160e01b600052603260045260246000fd5b602002602001015182611d1891906123c0565b915080611d248161242a565b915050611cdb565b5095945050505050565b600160026000828254611d4991906123c0565b90915550505050565b600060606007546009808054611d67906123ef565b80601f0160208091040260200160405190810160405280929190818152602001828054611d93906123ef565b8015611de05780601f10611db557610100808354040283529160200191611de0565b820191906000526020600020905b815481529060010190602001808311611dc357829003601f168201915b50505050509050915091509250929050565b60015460025410610b465760405162461bcd60e51b815260206004820152603260248201527f5344414f5f5245474953545241525f4c494d495445443a205245474953545241604482015271151253d397d31253525517d4915050d2115160721b60648201526084016104f5565b828054611e6c906123ef565b90600052602060002090601f016020900481019282611e8e5760008555611ed4565b82601f10611ea757805160ff1916838001178555611ed4565b82800160010185558215611ed4579182015b82811115611ed4578251825591602001919060010190611eb9565b50611ee0929150611ee4565b5090565b5b80821115611ee05760008155600101611ee5565b600067ffffffffffffffff831115611f1357611f1361245b565b611f26601f8401601f191660200161238f565b9050828152838383011115611f3a57600080fd5b828260208301376000602084830101529392505050565b60008083601f840112611f62578182fd5b50813567ffffffffffffffff811115611f79578182fd5b6020830191508360208285010111156114b857600080fd5b600082601f830112611fa1578081fd5b611fb083833560208501611ef9565b9392505050565b600060208284031215611fc8578081fd5b8135611fb081612471565b600060208284031215611fe4578081fd5b8151611fb081612471565b60006020808385031215612001578182fd5b825167ffffffffffffffff80821115612018578384fd5b818501915085601f83011261202b578384fd5b81518181111561203d5761203d61245b565b8060051b915061204e84830161238f565b8181528481019084860184860187018a1015612068578788fd5b8795505b8386101561208a57805183526001959095019491860191860161206c565b5098975050505050505050565b6000602082840312156120a8578081fd5b5035919050565b6000602082840312156120c0578081fd5b5051919050565b600080602083850312156120d9578081fd5b823567ffffffffffffffff8111156120ef578182fd5b6120fb85828601611f51565b90969095509350505050565b600060208284031215612118578081fd5b813567ffffffffffffffff81111561212e578182fd5b61213a84828501611f91565b949350505050565b600080600060608486031215612156578081fd5b833567ffffffffffffffff8082111561216d578283fd5b61217987838801611f91565b94506020860135915061218b82612471565b909250604085013590808211156121a0578283fd5b508401601f810186136121b1578182fd5b6121c086823560208401611ef9565b9150509250925092565b6000806000806000608086880312156121e1578081fd5b853594506020860135935060408601359250606086013567ffffffffffffffff81111561220c578182fd5b61221888828901611f51565b969995985093965092949392505050565b60008151808452815b8181101561224e57602081850181015186830182015201612232565b8181111561225f5782602083870101525b50601f01601f19169290920160200192915050565b60018060a01b03851681528360208201528260408201526080606082015260006122a16080830184612229565b9695505050505050565b604080825283519082018190526000906020906060840190828701845b828110156122ed5781516001600160a01b0316845292840192908401906001016122c8565b50505083810382850152845180825285830191830190845b8181101561232157835183529284019291840191600101612305565b5090979650505050505050565b602081526000611fb06020830184612229565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b82815260406020820152600061213a6040830184612229565b604051601f8201601f1916810167ffffffffffffffff811182821017156123b8576123b861245b565b604052919050565b600082198211156123d3576123d3612445565b500190565b6000828210156123ea576123ea612445565b500390565b600181811c9082168061240357607f821691505b6020821081141561242457634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561243e5761243e612445565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461050757600080fdfea2646970667358221220aa6b01e167f45b8beec333abbed25bee068d369458d48f2c66ac93eca4e9c99464736f6c63430008040033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e0000000000000000000000004976fb03c32e5b8cfe2b6ccb31c09ba78ebaba41000000000000000000000000222c65d42871f3b68e140f6a0255df523cb8619c433c99d8edd0cf295e2314840cf7f62ca9b23c2d6004e72c706022297ae716ab000000000000000000000000e6acae0d7df3aa27e3a0353c8da8d6a784787249000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000001000000000000000000000000347f1341b91e362b9258fc2addfd498498c33436
-----Decoded View---------------
Arg [0] : ensAddr (address): 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
Arg [1] : resolver (address): 0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41
Arg [2] : erc1155Token (address): 0x222c65D42871F3b68E140f6a0255DF523CB8619C
Arg [3] : node (bytes32): 0x433c99d8edd0cf295e2314840cf7f62ca9b23c2d6004e72c706022297ae716ab
Arg [4] : owner (address): 0xE6AcAe0D7Df3AA27E3A0353c8Da8d6a784787249
Arg [5] : reservationDuration (uint256): 9676800
Arg [6] : registrationLimit (uint256): 50
Arg [7] : groupId (uint256): 1
Arg [8] : codeSigner (address): 0x347f1341B91E362b9258Fc2aDDFD498498c33436
-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e
Arg [1] : 0000000000000000000000004976fb03c32e5b8cfe2b6ccb31c09ba78ebaba41
Arg [2] : 000000000000000000000000222c65d42871f3b68e140f6a0255df523cb8619c
Arg [3] : 433c99d8edd0cf295e2314840cf7f62ca9b23c2d6004e72c706022297ae716ab
Arg [4] : 000000000000000000000000e6acae0d7df3aa27e3a0353c8da8d6a784787249
Arg [5] : 000000000000000000000000000000000000000000000000000000000093a800
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000032
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [8] : 000000000000000000000000347f1341b91e362b9258fc2addfd498498c33436
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.