Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 25 from a total of 130 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Register | 17613690 | 982 days ago | IN | 0.00407175 ETH | 0.00456233 | ||||
| Register | 17508404 | 997 days ago | IN | 0.00458551 ETH | 0.00249812 | ||||
| Register | 17335255 | 1021 days ago | IN | 0.00448174 ETH | 0.00445088 | ||||
| Register | 17331085 | 1022 days ago | IN | 0.00447218 ETH | 0.00894398 | ||||
| Register | 17291424 | 1027 days ago | IN | 0.00443439 ETH | 0.00601863 | ||||
| Register | 17276745 | 1029 days ago | IN | 0.00438659 ETH | 0.00792727 | ||||
| Register | 17274375 | 1030 days ago | IN | 0.0043814 ETH | 0.01012559 | ||||
| Register | 17271671 | 1030 days ago | IN | 0.00440392 ETH | 0.00670496 | ||||
| Register | 17218789 | 1038 days ago | IN | 0.00434008 ETH | 0.01362548 | ||||
| Register | 17214331 | 1038 days ago | IN | 0.00429725 ETH | 0.02227361 | ||||
| Register | 17167276 | 1045 days ago | IN | 0.00438162 ETH | 0.01362331 | ||||
| Register | 17133721 | 1050 days ago | IN | 0.00428446 ETH | 0.00585811 | ||||
| Register | 17133513 | 1050 days ago | IN | 0.00409581 ETH | 0.00215455 | ||||
| Register | 17130577 | 1050 days ago | IN | 0.00408293 ETH | 0.00617448 | ||||
| Register | 17097649 | 1055 days ago | IN | 0.00434333 ETH | 0.0058475 | ||||
| Register | 17072691 | 1058 days ago | IN | 0.00381286 ETH | 0.00593465 | ||||
| Register | 17068958 | 1059 days ago | IN | 0.00384213 ETH | 0.00736308 | ||||
| Register | 17032412 | 1064 days ago | IN | 0.00421538 ETH | 0.00479496 | ||||
| Register | 17019261 | 1066 days ago | IN | 0.00422464 ETH | 0.00550012 | ||||
| Register | 17000318 | 1069 days ago | IN | 0.00430961 ETH | 0.00329857 | ||||
| Register | 17000292 | 1069 days ago | IN | 0.00430961 ETH | 0.00095611 | ||||
| Register | 17000290 | 1069 days ago | IN | 0.00430961 ETH | 0.00552654 | ||||
| Register | 16999340 | 1069 days ago | IN | 0.00431677 ETH | 0.00339901 | ||||
| Register | 16991641 | 1070 days ago | IN | 0.00427311 ETH | 0.0053769 | ||||
| Register | 16961150 | 1074 days ago | IN | 0.00440006 ETH | 0.00291565 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| Transfer | 17613690 | 982 days ago | 0.00407175 ETH | ||||
| Transfer | 17508404 | 997 days ago | 0.00458551 ETH | ||||
| Transfer | 17335255 | 1021 days ago | 0.00448174 ETH | ||||
| Transfer | 17331085 | 1022 days ago | 0.00447218 ETH | ||||
| Transfer | 17291424 | 1027 days ago | 0.00443439 ETH | ||||
| Transfer | 17276745 | 1029 days ago | 0.00438659 ETH | ||||
| Transfer | 17274375 | 1030 days ago | 0.0043814 ETH | ||||
| Transfer | 17271671 | 1030 days ago | 0.00440392 ETH | ||||
| Transfer | 17218789 | 1038 days ago | 0.00434008 ETH | ||||
| Transfer | 17214331 | 1038 days ago | 0.00429725 ETH | ||||
| Transfer | 17167276 | 1045 days ago | 0.00438162 ETH | ||||
| Transfer | 17133721 | 1050 days ago | 0.00428446 ETH | ||||
| Transfer | 17130577 | 1050 days ago | 0.00408293 ETH | ||||
| Transfer | 17097649 | 1055 days ago | 0.00434333 ETH | ||||
| Transfer | 17072691 | 1058 days ago | 0.00381286 ETH | ||||
| Transfer | 17068958 | 1059 days ago | 0.00384213 ETH | ||||
| Transfer | 17032412 | 1064 days ago | 0.00421538 ETH | ||||
| Transfer | 17019261 | 1066 days ago | 0.00422464 ETH | ||||
| Transfer | 17000318 | 1069 days ago | 0.00430961 ETH | ||||
| Transfer | 17000290 | 1069 days ago | 0.00430961 ETH | ||||
| Transfer | 16999340 | 1069 days ago | 0.00431677 ETH | ||||
| Transfer | 16991641 | 1070 days ago | 0.00427311 ETH | ||||
| Transfer | 16961150 | 1074 days ago | 0.00440006 ETH | ||||
| Transfer | 16948169 | 1076 days ago | 0.00437025 ETH | ||||
| Transfer | 16930323 | 1078 days ago | 0.00449661 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
TalSubdomainRegistrar
Compiler Version
v0.8.7+commit.e28d00a7
Optimization Enabled:
Yes with 1000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity ^0.8.7;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import {PublicResolver} from "@ensdomains/ens-contracts/contracts/resolvers/PublicResolver.sol";
import {DNSRegistrar} from "@ensdomains/ens-contracts/contracts/dnsregistrar/DNSRegistrar.sol";
import {ENS} from "@ensdomains/ens-contracts/contracts/registry/ENS.sol";
import {DNSSEC} from "@ensdomains/ens-contracts/contracts/dnssec-oracle/DNSSEC.sol";
import {ITalRegistrarInterface} from "./ITalRegistrarInterface.sol";
import {SafeMath} from "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "hardhat/console.sol";
/**
* @dev Implements an ENS registrar that sells subdomains on behalf of their owners.
*
* Users may register a subdomain by calling `register` with the name of the domain
* they wish to register under, and the label hash of the subdomain they want to
* register. The registrar then configures a simple
* default resolver, which resolves `addr` lookups to the new owner, and sets
* the `owner` account as the owner of the subdomain in ENS.
*
* Critically, this contract does not check one key property of a listed domain:
*
* - Is the name UTS46 normalised?
*
* User applications MUST check these two elements for each domain before
* offering them to users for registration.
*
* Applications should additionally check that the domains they are offering to
* register are controlled by this registrar, since calls to `register` will
* fail if this is not the case.
*/
contract TalSubdomainRegistrar is Ownable, ITalRegistrarInterface {
bytes32 public immutable ROOT_NODE;
ENS public ensRegistry;
PublicResolver public publicResolver;
DNSRegistrar public dnsRegistrar;
AggregatorV3Interface internal priceFeed;
uint256 public subdomainFee;
bool public stopped = false;
/// Multiplier used to get integer values
uint256 internal constant MUL = 1e18;
/**
* @dev Constructor.
* @param ens The address of the ENS registry.
* @param resolver The address of the Resolver.
* @param registrar The address of the ENS DNS registrar.
* @param node The node that this registrar administers.
* @param contractOwner The owner of the contract.
* @param initialSubdomainFee The amount to pay for a subdomain in usd.
*/
constructor(
ENS ens,
PublicResolver resolver,
DNSRegistrar registrar,
AggregatorV3Interface priceFeedAddress,
bytes32 node,
address contractOwner,
uint256 initialSubdomainFee
) {
ensRegistry = ens;
publicResolver = resolver;
dnsRegistrar = registrar;
ROOT_NODE = node;
subdomainFee = initialSubdomainFee;
priceFeed = priceFeedAddress;
transferOwnership(contractOwner);
}
modifier notStopped() {
require(!stopped, "TALSUBDOMAIN_REGISTRAR: Contract is currently stopped.");
_;
}
/**
* @notice Transfer the root domain ownership of the TalSubdomain Registrar to a new owner.
* @dev Can be called by the owner of the registrar.
* @param newDomainOwner The address of the new owner of `tal.community`.
*/
function transferDomainOwnership(address newDomainOwner) public override onlyOwner {
ensRegistry.setOwner(ROOT_NODE, newDomainOwner);
emit DomainOwnershipTransferred(newDomainOwner);
}
/**
* @notice Returns the address that owns the subdomain.
* @param subdomainLabel The subdomain label to get the owner.
*/
function subDomainOwner(string memory subdomainLabel) public view override returns (address subDomainOwnerAddress) {
bytes32 labelHash = keccak256(bytes(subdomainLabel));
return ensRegistry.owner(keccak256(abi.encodePacked(ROOT_NODE, labelHash)));
}
/**
* @notice Register a name.
* @dev Can only be called if and only if the subdomain of the root node is free
* @param subdomainLabel The label hash of the domain to register a subdomain of.
*/
function register(string memory subdomainLabel) public payable override notStopped {
bytes32 labelHash = keccak256(bytes(subdomainLabel));
bytes32 childNode = keccak256(abi.encodePacked(ROOT_NODE, labelHash));
address subdomainOwner = ensRegistry.owner(childNode);
require(subdomainOwner == address(0x0), "TALSUBDOMAIN_REGISTRAR: SUBDOMAIN_ALREADY_REGISTERED");
_payAndRegister(_msgSender(), subdomainLabel, labelHash, childNode);
}
/**
* @notice Register a name for free.
* @dev Can only be called by the owner if and only if the subdomain of the root node is free
* @param subdomainLabel The label hash of the domain to register a subdomain of.
* @param subdomainNewOwner The address that will own the sudomain.
*/
function freeRegister(string memory subdomainLabel, address subdomainNewOwner) public override onlyOwner {
bytes32 labelHash = keccak256(bytes(subdomainLabel));
bytes32 childNode = keccak256(abi.encodePacked(ROOT_NODE, labelHash));
address subdomainOwner = ensRegistry.owner(childNode);
require(subdomainOwner == address(0x0), "TALSUBDOMAIN_REGISTRAR: SUBDOMAIN_ALREADY_REGISTERED");
_register(subdomainNewOwner, subdomainLabel, labelHash, childNode, 0);
}
/**
* @notice Removes the owner of a subdomain.
* @dev Can only be called by the owner if and only if the subdomain is taken
* @param subdomainLabel The subdomain label to register.
*/
function revokeSubdomain(string memory subdomainLabel) public override onlyOwner {
_revoke(subdomainLabel);
}
/**
* @notice Sets the new resolver address.
*/
function setPublicResolver(PublicResolver resolver) public override onlyOwner {
publicResolver = resolver;
}
/**
* @notice Sets the price to pay for upcoming subdomain registrations in usd.
*/
function setSubdomainFee(uint256 newSubdomainFee) public override onlyOwner {
require(newSubdomainFee != subdomainFee, "TALSUBDOMAIN_REGISTRAR: New fee matches the current fee");
subdomainFee = newSubdomainFee;
emit SubDomainFeeChanged(subdomainFee);
}
/**
* @notice Stops the registrar, disabling the register of new domains.
* @dev Can only be called by the owner.
*/
function stop() public override notStopped onlyOwner {
stopped = true;
}
/**
* @notice Opens the registrar, enabling configuring of new domains.
* @dev Can only be called by the owner.
*/
function open() public override onlyOwner {
stopped = false;
}
/**
* @notice Submits ownership proof to the DNS registrar contract.
* @dev Can only be called by the owner.
*/
function configureDnsOwnership(
bytes memory name,
DNSSEC.RRSetWithSignature[] memory input,
bytes memory proof
) public override onlyOwner {
dnsRegistrar.proveAndClaimWithResolver(name, input, proof, address(publicResolver), address(this));
}
/**
* @notice Return the price in eth to pay for a subdomain.
*/
function domainPriceInEth() public view override returns (uint256 price) {
if (subdomainFee == 0) {
return 0;
}
(, int256 ethUsdPrice, , , ) = priceFeed.latestRoundData();
// The priceFeed returns only 8 decimals
uint256 adjustedPrice = SafeMath.mul(uint256(ethUsdPrice), 10**10); // 18 decimals
uint256 subdomainFeeWithMUL = SafeMath.mul(subdomainFee, MUL);
return SafeMath.div(SafeMath.mul(subdomainFeeWithMUL, MUL), uint256(adjustedPrice));
}
/**
* @dev Register a name when the correct amount is passed.
* 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 subdomainLabel The label to register.
* @param labelHash Encrypted representation of the label to register.
* @param childNode Encrypted representation of the label to register plus the root domain.
*/
function _payAndRegister(
address account,
string memory subdomainLabel,
bytes32 labelHash,
bytes32 childNode
) internal {
// User must have paid enough
uint256 ethSubdomainFee = domainPriceInEth();
require(msg.value >= ethSubdomainFee, "TALSUBDOMAIN_REGISTRAR: Amount passed is not enough");
// Send any extra back
if (msg.value > ethSubdomainFee) {
payable(_msgSender()).transfer(msg.value - ethSubdomainFee);
}
payable(owner()).transfer(ethSubdomainFee);
_register(account, subdomainLabel, labelHash, childNode, ethSubdomainFee);
}
/**
* @dev Register a name.
* 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 subdomainLabel The label to register.
* @param labelHash Encrypted representation of the label to register.
* @param childNode Encrypted representation of the label to register plus the root domain.
*/
function _register(
address account,
string memory subdomainLabel,
bytes32 labelHash,
bytes32 childNode,
uint256 fee
) internal {
// Set ownership to TalRegistrar, so that the contract can set resolver
ensRegistry.setSubnodeRecord(ROOT_NODE, labelHash, address(this), address(publicResolver), 0);
// Setting the resolver for the user
publicResolver.setAddr(childNode, account);
// Giving back the ownership to the user
ensRegistry.setSubnodeOwner(ROOT_NODE, labelHash, account);
emit SubDomainRegistered(subdomainLabel, fee, account);
}
/**
* @notice Removes the owner of a subdomain.
* @dev Can only be called by the owner if and only if the subdomain is taken
* @param subdomainLabel The subdomain label to register.
*/
function _revoke(string memory subdomainLabel) internal {
bytes32 labelHash = keccak256(bytes(subdomainLabel));
bytes32 childNode = keccak256(abi.encodePacked(ROOT_NODE, labelHash));
address subdomainOwner = ensRegistry.owner(childNode);
require(subdomainOwner != address(0x0), "TALSUBDOMAIN_REGISTRAR: SUBDOMAIN_NOT_REGISTERED");
// Revoke ownership
ensRegistry.setSubnodeRecord(ROOT_NODE, labelHash, address(0x0), address(0x0), 0);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface AggregatorV3Interface {
function decimals() external view returns (uint8);
function description() external view returns (string memory);
function version() external view returns (uint256);
function getRoundData(uint80 _roundId)
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
function latestRoundData()
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
}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;
pragma experimental ABIEncoderV2;
import "../dnssec-oracle/BytesUtils.sol";
import "../dnssec-oracle/DNSSEC.sol";
import "../registry/ENSRegistry.sol";
import "../root/Root.sol";
import "./DNSClaimChecker.sol";
import "./PublicSuffixList.sol";
import "../resolvers/profiles/AddrResolver.sol";
interface IDNSRegistrar {
function claim(bytes memory name, bytes memory proof) external;
function proveAndClaim(bytes memory name, DNSSEC.RRSetWithSignature[] memory input, bytes memory proof) external;
function proveAndClaimWithResolver(bytes memory name, DNSSEC.RRSetWithSignature[] memory input, bytes memory proof, address resolver, address addr) external;
}
/**
* @dev An ENS registrar that allows the owner of a DNS name to claim the
* corresponding name in ENS.
*/
contract DNSRegistrar is IDNSRegistrar {
using BytesUtils for bytes;
DNSSEC public oracle;
ENS public ens;
PublicSuffixList public suffixes;
bytes4 constant private INTERFACE_META_ID = bytes4(keccak256("supportsInterface(bytes4)"));
event Claim(bytes32 indexed node, address indexed owner, bytes dnsname);
event NewOracle(address oracle);
event NewPublicSuffixList(address suffixes);
constructor(DNSSEC _dnssec, PublicSuffixList _suffixes, ENS _ens) {
oracle = _dnssec;
emit NewOracle(address(oracle));
suffixes = _suffixes;
emit NewPublicSuffixList(address(suffixes));
ens = _ens;
}
/**
* @dev This contract's owner-only functions can be invoked by the owner of the ENS root.
*/
modifier onlyOwner {
Root root = Root(ens.owner(bytes32(0)));
address owner = root.owner();
require(msg.sender == owner);
_;
}
function setOracle(DNSSEC _dnssec) public onlyOwner {
oracle = _dnssec;
emit NewOracle(address(oracle));
}
function setPublicSuffixList(PublicSuffixList _suffixes) public onlyOwner {
suffixes = _suffixes;
emit NewPublicSuffixList(address(suffixes));
}
/**
* @dev Claims a name by proving ownership of its DNS equivalent.
* @param name The name to claim, in DNS wire format.
* @param proof A DNS RRSet proving ownership of the name. Must be verified
* in the DNSSEC oracle before calling. This RRSET must contain a TXT
* record for '_ens.' + name, with the value 'a=0x...'. Ownership of
* the name will be transferred to the address specified in the TXT
* record.
*/
function claim(bytes memory name, bytes memory proof) public override {
(bytes32 rootNode, bytes32 labelHash, address addr) = _claim(name, proof);
ens.setSubnodeOwner(rootNode, labelHash, addr);
}
/**
* @dev Submits proofs to the DNSSEC oracle, then claims a name using those proofs.
* @param name The name to claim, in DNS wire format.
* @param input The data to be passed to the Oracle's `submitProofs` function. The last
* proof must be the TXT record required by the registrar.
* @param proof The proof record for the first element in input.
*/
function proveAndClaim(bytes memory name, DNSSEC.RRSetWithSignature[] memory input, bytes memory proof) public override {
proof = oracle.submitRRSets(input, proof);
claim(name, proof);
}
function proveAndClaimWithResolver(bytes memory name, DNSSEC.RRSetWithSignature[] memory input, bytes memory proof, address resolver, address addr) public override {
proof = oracle.submitRRSets(input, proof);
(bytes32 rootNode, bytes32 labelHash, address owner) = _claim(name, proof);
require(msg.sender == owner, "Only owner can call proveAndClaimWithResolver");
if(addr != address(0)) {
require(resolver != address(0), "Cannot set addr if resolver is not set");
// Set ourselves as the owner so we can set a record on the resolver
ens.setSubnodeRecord(rootNode, labelHash, address(this), resolver, 0);
bytes32 node = keccak256(abi.encodePacked(rootNode, labelHash));
// Set the resolver record
AddrResolver(resolver).setAddr(node, addr);
// Transfer the record to the owner
ens.setOwner(node, owner);
} else {
ens.setSubnodeRecord(rootNode, labelHash, owner, resolver, 0);
}
}
function supportsInterface(bytes4 interfaceID) external pure returns (bool) {
return interfaceID == INTERFACE_META_ID ||
interfaceID == type(IDNSRegistrar).interfaceId;
}
function _claim(bytes memory name, bytes memory proof) internal returns(bytes32 rootNode, bytes32 labelHash, address addr) {
// Get the first label
uint labelLen = name.readUint8(0);
labelHash = name.keccak(1, labelLen);
// Parent name must be in the public suffix list.
bytes memory parentName = name.substring(labelLen + 1, name.length - labelLen - 1);
require(suffixes.isPublicSuffix(parentName), "Parent name must be a public suffix");
// Make sure the parent name is enabled
rootNode = enableNode(parentName, 0);
(addr,) = DNSClaimChecker.getOwnerAddress(oracle, name, proof);
emit Claim(keccak256(abi.encodePacked(rootNode, labelHash)), addr, name);
}
function enableNode(bytes memory domain, uint offset) internal returns(bytes32 node) {
uint len = domain.readUint8(offset);
if(len == 0) {
return bytes32(0);
}
bytes32 parentNode = enableNode(domain, offset + len + 1);
bytes32 label = domain.keccak(offset + 1, len);
node = keccak256(abi.encodePacked(parentNode, label));
address owner = ens.owner(node);
require(owner == address(0) || owner == address(this), "Cannot enable a name owned by someone else");
if(owner != address(this)) {
if(parentNode == bytes32(0)) {
Root root = Root(ens.owner(bytes32(0)));
root.setSubnodeOwner(label, address(this));
} else {
ens.setSubnodeOwner(parentNode, label, address(this));
}
}
return node;
}
}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);
}pragma solidity ^0.8.4;
pragma experimental ABIEncoderV2;
abstract contract DNSSEC {
bytes public anchors;
struct RRSetWithSignature {
bytes rrset;
bytes sig;
}
event AlgorithmUpdated(uint8 id, address addr);
event DigestUpdated(uint8 id, address addr);
event NSEC3DigestUpdated(uint8 id, address addr);
event RRSetUpdated(bytes name, bytes rrset);
function submitRRSets(RRSetWithSignature[] memory input, bytes calldata proof) public virtual returns (bytes memory);
function submitRRSet(RRSetWithSignature calldata input, bytes calldata proof) public virtual returns (bytes memory);
function deleteRRSet(uint16 deleteType, bytes calldata deleteName, RRSetWithSignature calldata nsec, bytes calldata proof) public virtual;
function deleteRRSetNSEC3(uint16 deleteType, bytes memory deleteName, RRSetWithSignature memory closestEncloser, RRSetWithSignature memory nextClosest, bytes memory dnskey) public virtual;
function rrdata(uint16 dnstype, bytes calldata name) external virtual view returns (uint32, uint32, bytes20);
}pragma solidity ^0.8.7;
import {DNSSEC} from "@ensdomains/ens-contracts/contracts/dnssec-oracle/DNSSEC.sol";
import {PublicResolver} from "@ensdomains/ens-contracts/contracts/resolvers/PublicResolver.sol";
/**
* @title ITalRegistrarInterface interface
* @notice A registrar that allows registrations in the Talent Protocol community.
* The registrar holds an ENS subdomain of the convential DNS system, e.g. 'tal.community'.
*
* A registration allocates one ENS subdomain of the root subdomain, e.g. 'myname.tal.community' to an address.
*
* The registrations from the public `register` method can be restricted by the owner of the contract.
*/
interface ITalRegistrarInterface {
/**
* @dev Emitted when a new subdomain is registered.
*/
event SubDomainRegistered(string subDomainLabel, uint256 price, address indexed owner);
/**
* @dev Emitted when the root domain ownership is transferred to a new address.
*/
event DomainOwnershipTransferred(address indexed owner);
/**
* @dev Emitted when the subdomain fee is changed.
*/
event SubDomainFeeChanged(uint256 newFee);
/**
* @notice Transfer the root domain ownership of the TAL Subdomain Registrar to a new owner.
*
* Emits a {DomainOwnershipTransfered} event.
*/
function transferDomainOwnership(address newDomainOwner) external;
/**
* @notice Returns the address that owns the subdomain.
* @dev Can only be called if and only if the subdomain of the root node is free
* @param subdomainLabel The subdomain label to get the owner.
*/
function subDomainOwner(string memory subdomainLabel) external view returns (address owner);
/**
* @notice Register a name.
* @param subdomainLabel The subdomain label to register.
*
* Emits a {SubDomainRegistered} event.
*/
function register(string calldata subdomainLabel) external payable;
/**
* @notice Register a name for free.
* @param subdomainLabel The subdomain label to register.
* @param subdomainNewOwner The address that will own the sudomain.
*
* Emits a {SubDomainRegistered} event.
*/
function freeRegister(string calldata subdomainLabel, address subdomainNewOwner) external;
/**
* @notice Removes the owner of a subdomain.
* @param subdomainLabel The subdomain label to register.
*/
function revokeSubdomain(string calldata subdomainLabel) external;
/**
* @notice Sets the price to pay for upcoming subdomain registrations in usd.
*/
function setSubdomainFee(uint256 subdomainFee) external;
/**
* @notice Sets the new resolver address.
*/
function setPublicResolver(PublicResolver resolver) external;
/**
* @notice Stops subdomain registrations.
*/
function stop() external;
/**
* @notice Opens subdomain registration.
*/
function open() external;
/**
* @notice Submits ownership proof to the DNS registrar contract.
*/
function configureDnsOwnership(
bytes memory name,
DNSSEC.RRSetWithSignature[] memory input,
bytes memory proof
) external;
/**
* @notice Returns the price in eth to pay for a subdomain.
*/
function domainPriceInEth() external view returns (uint256 price);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)
pragma solidity ^0.8.0;
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}// SPDX-License-Identifier: MIT
pragma solidity >= 0.4.22 <0.9.0;
library console {
address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);
function _sendLogPayload(bytes memory payload) private view {
uint256 payloadLength = payload.length;
address consoleAddress = CONSOLE_ADDRESS;
assembly {
let payloadStart := add(payload, 32)
let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)
}
}
function log() internal view {
_sendLogPayload(abi.encodeWithSignature("log()"));
}
function logInt(int p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(int)", p0));
}
function logUint(uint p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint)", p0));
}
function logString(string memory p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
}
function logBool(bool p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
}
function logAddress(address p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
}
function logBytes(bytes memory p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes)", p0));
}
function logBytes1(bytes1 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0));
}
function logBytes2(bytes2 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0));
}
function logBytes3(bytes3 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0));
}
function logBytes4(bytes4 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0));
}
function logBytes5(bytes5 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0));
}
function logBytes6(bytes6 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0));
}
function logBytes7(bytes7 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0));
}
function logBytes8(bytes8 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0));
}
function logBytes9(bytes9 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0));
}
function logBytes10(bytes10 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0));
}
function logBytes11(bytes11 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0));
}
function logBytes12(bytes12 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0));
}
function logBytes13(bytes13 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0));
}
function logBytes14(bytes14 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0));
}
function logBytes15(bytes15 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0));
}
function logBytes16(bytes16 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0));
}
function logBytes17(bytes17 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0));
}
function logBytes18(bytes18 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0));
}
function logBytes19(bytes19 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0));
}
function logBytes20(bytes20 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0));
}
function logBytes21(bytes21 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0));
}
function logBytes22(bytes22 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0));
}
function logBytes23(bytes23 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0));
}
function logBytes24(bytes24 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0));
}
function logBytes25(bytes25 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0));
}
function logBytes26(bytes26 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0));
}
function logBytes27(bytes27 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0));
}
function logBytes28(bytes28 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0));
}
function logBytes29(bytes29 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0));
}
function logBytes30(bytes30 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0));
}
function logBytes31(bytes31 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0));
}
function logBytes32(bytes32 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0));
}
function log(uint p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint)", p0));
}
function log(string memory p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
}
function log(bool p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
}
function log(address p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
}
function log(uint p0, uint p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint)", p0, p1));
}
function log(uint p0, string memory p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string)", p0, p1));
}
function log(uint p0, bool p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool)", p0, p1));
}
function log(uint p0, address p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address)", p0, p1));
}
function log(string memory p0, uint p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint)", p0, p1));
}
function log(string memory p0, string memory p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1));
}
function log(string memory p0, bool p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1));
}
function log(string memory p0, address p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1));
}
function log(bool p0, uint p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint)", p0, p1));
}
function log(bool p0, string memory p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1));
}
function log(bool p0, bool p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1));
}
function log(bool p0, address p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1));
}
function log(address p0, uint p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint)", p0, p1));
}
function log(address p0, string memory p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1));
}
function log(address p0, bool p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1));
}
function log(address p0, address p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1));
}
function log(uint p0, uint p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2));
}
function log(uint p0, uint p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2));
}
function log(uint p0, uint p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2));
}
function log(uint p0, uint p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2));
}
function log(uint p0, string memory p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2));
}
function log(uint p0, string memory p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2));
}
function log(uint p0, string memory p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2));
}
function log(uint p0, string memory p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2));
}
function log(uint p0, bool p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2));
}
function log(uint p0, bool p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2));
}
function log(uint p0, bool p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2));
}
function log(uint p0, bool p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2));
}
function log(uint p0, address p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2));
}
function log(uint p0, address p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2));
}
function log(uint p0, address p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2));
}
function log(uint p0, address p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2));
}
function log(string memory p0, uint p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2));
}
function log(string memory p0, uint p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2));
}
function log(string memory p0, uint p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2));
}
function log(string memory p0, uint p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2));
}
function log(string memory p0, string memory p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint)", p0, p1, p2));
}
function log(string memory p0, string memory p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2));
}
function log(string memory p0, string memory p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2));
}
function log(string memory p0, string memory p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2));
}
function log(string memory p0, bool p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint)", p0, p1, p2));
}
function log(string memory p0, bool p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2));
}
function log(string memory p0, bool p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2));
}
function log(string memory p0, bool p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2));
}
function log(string memory p0, address p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint)", p0, p1, p2));
}
function log(string memory p0, address p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2));
}
function log(string memory p0, address p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2));
}
function log(string memory p0, address p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2));
}
function log(bool p0, uint p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2));
}
function log(bool p0, uint p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2));
}
function log(bool p0, uint p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2));
}
function log(bool p0, uint p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2));
}
function log(bool p0, string memory p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint)", p0, p1, p2));
}
function log(bool p0, string memory p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2));
}
function log(bool p0, string memory p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2));
}
function log(bool p0, string memory p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2));
}
function log(bool p0, bool p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint)", p0, p1, p2));
}
function log(bool p0, bool p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2));
}
function log(bool p0, bool p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2));
}
function log(bool p0, bool p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2));
}
function log(bool p0, address p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint)", p0, p1, p2));
}
function log(bool p0, address p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2));
}
function log(bool p0, address p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2));
}
function log(bool p0, address p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2));
}
function log(address p0, uint p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2));
}
function log(address p0, uint p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2));
}
function log(address p0, uint p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2));
}
function log(address p0, uint p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2));
}
function log(address p0, string memory p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint)", p0, p1, p2));
}
function log(address p0, string memory p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2));
}
function log(address p0, string memory p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2));
}
function log(address p0, string memory p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2));
}
function log(address p0, bool p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint)", p0, p1, p2));
}
function log(address p0, bool p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2));
}
function log(address p0, bool p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2));
}
function log(address p0, bool p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2));
}
function log(address p0, address p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint)", p0, p1, p2));
}
function log(address p0, address p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2));
}
function log(address p0, address p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2));
}
function log(address p0, address p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2));
}
function log(uint p0, uint p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,uint)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,uint)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,address)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,uint)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,string)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,bool)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,uint)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,uint)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,uint)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3));
}
function log(uint p0, address p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3));
}
function log(uint p0, address p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3));
}
function log(uint p0, address p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3));
}
function log(uint p0, address p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3));
}
function log(uint p0, address p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,uint)", p0, p1, p2, p3));
}
function log(uint p0, address p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3));
}
function log(uint p0, address p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3));
}
function log(uint p0, address p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3));
}
function log(uint p0, address p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3));
}
function log(uint p0, address p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3));
}
function log(uint p0, address p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3));
}
function log(uint p0, address p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3));
}
function log(uint p0, address p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3));
}
function log(uint p0, address p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3));
}
function log(uint p0, address p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3));
}
function log(uint p0, address p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,uint)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,uint)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,uint)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,uint)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,uint)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,uint)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,uint)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,uint)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,uint)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3));
}
function log(address p0, uint p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3));
}
function log(address p0, uint p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3));
}
function log(address p0, uint p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3));
}
function log(address p0, uint p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3));
}
function log(address p0, uint p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,uint)", p0, p1, p2, p3));
}
function log(address p0, uint p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3));
}
function log(address p0, uint p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3));
}
function log(address p0, uint p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3));
}
function log(address p0, uint p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3));
}
function log(address p0, uint p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3));
}
function log(address p0, uint p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, uint p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3));
}
function log(address p0, uint p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3));
}
function log(address p0, uint p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3));
}
function log(address p0, uint p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3));
}
function log(address p0, uint p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,uint)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}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);
}
}pragma solidity >=0.8.4;
import "./ENS.sol";
/**
* The ENS registry contract.
*/
contract ENSRegistry is ENS {
struct Record {
address owner;
address resolver;
uint64 ttl;
}
mapping (bytes32 => Record) records;
mapping (address => mapping(address => bool)) operators;
// Permits modifications only by the owner of the specified node.
modifier authorised(bytes32 node) {
address owner = records[node].owner;
require(owner == msg.sender || operators[owner][msg.sender]);
_;
}
/**
* @dev Constructs a new ENS registrar.
*/
constructor() public {
records[0x0].owner = msg.sender;
}
/**
* @dev Sets the record for a node.
* @param node The node to update.
* @param owner The address of the new owner.
* @param resolver The address of the resolver.
* @param ttl The TTL in seconds.
*/
function setRecord(bytes32 node, address owner, address resolver, uint64 ttl) external virtual override {
setOwner(node, owner);
_setResolverAndTTL(node, resolver, ttl);
}
/**
* @dev Sets the record for a subnode.
* @param node The parent node.
* @param label The hash of the label specifying the subnode.
* @param owner The address of the new owner.
* @param resolver The address of the resolver.
* @param ttl The TTL in seconds.
*/
function setSubnodeRecord(bytes32 node, bytes32 label, address owner, address resolver, uint64 ttl) external virtual override {
bytes32 subnode = setSubnodeOwner(node, label, owner);
_setResolverAndTTL(subnode, resolver, ttl);
}
/**
* @dev Transfers ownership of a node to a new address. May only be called by the current owner of the node.
* @param node The node to transfer ownership of.
* @param owner The address of the new owner.
*/
function setOwner(bytes32 node, address owner) public virtual override authorised(node) {
_setOwner(node, owner);
emit Transfer(node, owner);
}
/**
* @dev Transfers ownership of a subnode keccak256(node, label) to a new address. May only be called by the owner of the parent node.
* @param node The parent node.
* @param label The hash of the label specifying the subnode.
* @param owner The address of the new owner.
*/
function setSubnodeOwner(bytes32 node, bytes32 label, address owner) public virtual override authorised(node) returns(bytes32) {
bytes32 subnode = keccak256(abi.encodePacked(node, label));
_setOwner(subnode, owner);
emit NewOwner(node, label, owner);
return subnode;
}
/**
* @dev Sets the resolver address for the specified node.
* @param node The node to update.
* @param resolver The address of the resolver.
*/
function setResolver(bytes32 node, address resolver) public virtual override authorised(node) {
emit NewResolver(node, resolver);
records[node].resolver = resolver;
}
/**
* @dev Sets the TTL for the specified node.
* @param node The node to update.
* @param ttl The TTL in seconds.
*/
function setTTL(bytes32 node, uint64 ttl) public virtual override authorised(node) {
emit NewTTL(node, ttl);
records[node].ttl = ttl;
}
/**
* @dev Enable or disable approval for a third party ("operator") to manage
* all of `msg.sender`'s ENS records. Emits the ApprovalForAll event.
* @param operator Address to add to the set of authorized operators.
* @param approved True if the operator is approved, false to revoke approval.
*/
function setApprovalForAll(address operator, bool approved) external virtual override {
operators[msg.sender][operator] = approved;
emit ApprovalForAll(msg.sender, operator, approved);
}
/**
* @dev Returns the address that owns the specified node.
* @param node The specified node.
* @return address of the owner.
*/
function owner(bytes32 node) public virtual override view returns (address) {
address addr = records[node].owner;
if (addr == address(this)) {
return address(0x0);
}
return addr;
}
/**
* @dev Returns the address of the resolver for the specified node.
* @param node The specified node.
* @return address of the resolver.
*/
function resolver(bytes32 node) public virtual override view returns (address) {
return records[node].resolver;
}
/**
* @dev Returns the TTL of a node, and any records associated with it.
* @param node The specified node.
* @return ttl of the node.
*/
function ttl(bytes32 node) public virtual override view returns (uint64) {
return records[node].ttl;
}
/**
* @dev Returns whether a record has been imported to the registry.
* @param node The specified node.
* @return Bool if record exists
*/
function recordExists(bytes32 node) public virtual override view returns (bool) {
return records[node].owner != address(0x0);
}
/**
* @dev Query if an address is an authorized operator for another address.
* @param owner The address that owns the records.
* @param operator The address that acts on behalf of the owner.
* @return True if `operator` is an approved operator for `owner`, false otherwise.
*/
function isApprovedForAll(address owner, address operator) external virtual override view returns (bool) {
return operators[owner][operator];
}
function _setOwner(bytes32 node, address owner) internal virtual {
records[node].owner = owner;
}
function _setResolverAndTTL(bytes32 node, address resolver, uint64 ttl) internal {
if(resolver != records[node].resolver) {
records[node].resolver = resolver;
emit NewResolver(node, resolver);
}
if(ttl != records[node].ttl) {
records[node].ttl = ttl;
emit NewTTL(node, ttl);
}
}
}pragma solidity ^0.8.4;
import "../registry/ENS.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./Controllable.sol";
contract Root is Ownable, Controllable {
bytes32 private constant ROOT_NODE = bytes32(0);
bytes4 private constant INTERFACE_META_ID =
bytes4(keccak256("supportsInterface(bytes4)"));
event TLDLocked(bytes32 indexed label);
ENS public ens;
mapping(bytes32 => bool) public locked;
constructor(ENS _ens) public {
ens = _ens;
}
function setSubnodeOwner(bytes32 label, address owner)
external
onlyController
{
require(!locked[label]);
ens.setSubnodeOwner(ROOT_NODE, label, owner);
}
function setResolver(address resolver) external onlyOwner {
ens.setResolver(ROOT_NODE, resolver);
}
function lock(bytes32 label) external onlyOwner {
emit TLDLocked(label);
locked[label] = true;
}
function supportsInterface(bytes4 interfaceID)
external
pure
returns (bool)
{
return interfaceID == INTERFACE_META_ID;
}
}pragma solidity ^0.8.4;
import "../dnssec-oracle/DNSSEC.sol";
import "../dnssec-oracle/BytesUtils.sol";
import "../dnssec-oracle/RRUtils.sol";
import "@ensdomains/buffer/contracts/Buffer.sol";
library DNSClaimChecker {
using BytesUtils for bytes;
using RRUtils for *;
using Buffer for Buffer.buffer;
uint16 constant CLASS_INET = 1;
uint16 constant TYPE_TXT = 16;
function getOwnerAddress(DNSSEC oracle, bytes memory name, bytes memory proof)
internal
view
returns (address, bool)
{
// Add "_ens." to the front of the name.
Buffer.buffer memory buf;
buf.init(name.length + 5);
buf.append("\x04_ens");
buf.append(name);
bytes20 hash;
uint32 expiration;
// Check the provided TXT record has been validated by the oracle
(, expiration, hash) = oracle.rrdata(TYPE_TXT, buf.buf);
if (hash == bytes20(0) && proof.length == 0) return (address(0x0), false);
require(hash == bytes20(keccak256(proof)));
for (RRUtils.RRIterator memory iter = proof.iterateRRs(0); !iter.done(); iter.next()) {
require(RRUtils.serialNumberGte(expiration + iter.ttl, uint32(block.timestamp)), "DNS record is stale; refresh or delete it before proceeding.");
bool found;
address addr;
(addr, found) = parseRR(proof, iter.rdataOffset);
if (found) {
return (addr, true);
}
}
return (address(0x0), false);
}
function parseRR(bytes memory rdata, uint idx) internal pure returns (address, bool) {
while (idx < rdata.length) {
uint len = rdata.readUint8(idx); idx += 1;
bool found;
address addr;
(addr, found) = parseString(rdata, idx, len);
if (found) return (addr, true);
idx += len;
}
return (address(0x0), false);
}
function parseString(bytes memory str, uint idx, uint len) internal pure returns (address, bool) {
// TODO: More robust parsing that handles whitespace and multiple key/value pairs
if (str.readUint32(idx) != 0x613d3078) return (address(0x0), false); // 0x613d3078 == 'a=0x'
if (len < 44) return (address(0x0), false);
return hexToAddress(str, idx + 4);
}
function hexToAddress(bytes memory str, uint idx) internal pure returns (address, bool) {
if (str.length - idx < 40) return (address(0x0), false);
uint ret = 0;
for (uint i = idx; i < idx + 40; i++) {
ret <<= 4;
uint x = str.readUint8(i);
if (x >= 48 && x < 58) {
ret |= x - 48;
} else if (x >= 65 && x < 71) {
ret |= x - 55;
} else if (x >= 97 && x < 103) {
ret |= x - 87;
} else {
return (address(0x0), false);
}
}
return (address(uint160(ret)), true);
}
}pragma solidity ^0.8.4;
interface PublicSuffixList {
function isPublicSuffix(bytes calldata name) external view returns(bool);
}pragma solidity ^0.8.4;
import "@openzeppelin/contracts/access/Ownable.sol";
contract Controllable is Ownable {
mapping(address => bool) public controllers;
event ControllerChanged(address indexed controller, bool enabled);
modifier onlyController {
require(
controllers[msg.sender],
"Controllable: Caller is not a controller"
);
_;
}
function setController(address controller, bool enabled) public onlyOwner {
controllers[controller] = enabled;
emit ControllerChanged(controller, enabled);
}
}{
"optimizer": {
"enabled": true,
"runs": 1000
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract ENS","name":"ens","type":"address"},{"internalType":"contract PublicResolver","name":"resolver","type":"address"},{"internalType":"contract DNSRegistrar","name":"registrar","type":"address"},{"internalType":"contract AggregatorV3Interface","name":"priceFeedAddress","type":"address"},{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"contractOwner","type":"address"},{"internalType":"uint256","name":"initialSubdomainFee","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"DomainOwnershipTransferred","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":"newFee","type":"uint256"}],"name":"SubDomainFeeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"subDomainLabel","type":"string"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"SubDomainRegistered","type":"event"},{"inputs":[],"name":"ROOT_NODE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"},{"components":[{"internalType":"bytes","name":"rrset","type":"bytes"},{"internalType":"bytes","name":"sig","type":"bytes"}],"internalType":"struct DNSSEC.RRSetWithSignature[]","name":"input","type":"tuple[]"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"configureDnsOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"dnsRegistrar","outputs":[{"internalType":"contract DNSRegistrar","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"domainPriceInEth","outputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ensRegistry","outputs":[{"internalType":"contract ENS","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"subdomainLabel","type":"string"},{"internalType":"address","name":"subdomainNewOwner","type":"address"}],"name":"freeRegister","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"open","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicResolver","outputs":[{"internalType":"contract PublicResolver","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"subdomainLabel","type":"string"}],"name":"register","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"subdomainLabel","type":"string"}],"name":"revokeSubdomain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract PublicResolver","name":"resolver","type":"address"}],"name":"setPublicResolver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newSubdomainFee","type":"uint256"}],"name":"setSubdomainFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stopped","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"subdomainLabel","type":"string"}],"name":"subDomainOwner","outputs":[{"internalType":"address","name":"subDomainOwnerAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"subdomainFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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"}]Contract Creation Code
60a06040526006805460ff191690553480156200001b57600080fd5b5060405162001b8538038062001b858339810160408190526200003e91620001e6565b6200004933620000b5565b600180546001600160a01b03808a166001600160a01b0319928316179092556002805489841690831617905560038054888416908316179055608085905260058390556004805492871692909116919091179055620000a88262000105565b505050505050506200028f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6200010f62000188565b6001600160a01b0381166200017a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b6200018581620000b5565b50565b6000546001600160a01b03163314620001e45760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000171565b565b600080600080600080600060e0888a0312156200020257600080fd5b87516200020f8162000279565b6020890151909750620002228162000279565b6040890151909650620002358162000279565b6060890151909550620002488162000279565b608089015160a08a01519195509350620002628162000279565b8092505060c0880151905092959891949750929550565b6001600160a01b03811681146200018557600080fd5b6080516118a2620002e3600039600081816101cd01528181610497015281816106c4015281816107e501528181610ae801528181610d5b01528181610e8901528181610ff5015261115701526118a26000f3fe60806040526004361061015f5760003560e01c8063957f992d116100c0578063f2800a1411610074578063f2fde38b11610059578063f2fde38b14610395578063f8256121146103b5578063fcfff16f146103d557600080fd5b8063f2800a1414610362578063f2c298be1461038257600080fd5b8063ab517d13116100a5578063ab517d1314610317578063be8ee97514610337578063e37ce2b11461034c57600080fd5b8063957f992d146102d7578063a4f50b75146102f757600080fd5b8063715018a6116101175780637d73b231116100fc5780637d73b231146102615780638da5cb5b14610299578063943e60aa146102b757600080fd5b8063715018a61461022257806375f12b211461023757600080fd5b806339998ddb1161014857806339998ddb1461019b5780634a9fe1c7146101bb57806354bfc7e51461020257600080fd5b806307da68f51461016457806307ddce4e1461017b575b600080fd5b34801561017057600080fd5b506101796103ea565b005b34801561018757600080fd5b5061017961019636600461157d565b61047f565b3480156101a757600080fd5b506101796101b63660046113cf565b6105fd565b3480156101c757600080fd5b506101ef7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b34801561020e57600080fd5b5061017961021d36600461137c565b610691565b34801561022e57600080fd5b5061017961076e565b34801561024357600080fd5b506006546102519060ff1681565b60405190151581526020016101f9565b34801561026d57600080fd5b50600154610281906001600160a01b031681565b6040516001600160a01b0390911681526020016101f9565b3480156102a557600080fd5b506000546001600160a01b0316610281565b3480156102c357600080fd5b50600354610281906001600160a01b031681565b3480156102e357600080fd5b506101796102f236600461137c565b610782565b34801561030357600080fd5b50610281610312366004611540565b6107b9565b34801561032357600080fd5b506101796103323660046115cf565b6108a1565b34801561034357600080fd5b506101ef61095c565b34801561035857600080fd5b506101ef60055481565b34801561036e57600080fd5b5061017961037d366004611540565b610a4b565b610179610390366004611540565b610a5f565b3480156103a157600080fd5b506101796103b036600461137c565b610c4b565b3480156103c157600080fd5b50600254610281906001600160a01b031681565b3480156103e157600080fd5b50610179610cd8565b60065460ff16156104685760405162461bcd60e51b815260206004820152603660248201527f54414c535542444f4d41494e5f5245474953545241523a20436f6e747261637460448201527f2069732063757272656e746c792073746f707065642e0000000000000000000060648201526084015b60405180910390fd5b610470610cec565b6006805460ff19166001179055565b610487610cec565b60008280519060200120905060007f0000000000000000000000000000000000000000000000000000000000000000826040516020016104d1929190918252602082015260400190565b60408051808303601f190181529082905280516020909101206001546302571be360e01b8352600483018290529092506000916001600160a01b03909116906302571be39060240160206040518083038186803b15801561053157600080fd5b505afa158015610545573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105699190611399565b90506001600160a01b038116156105e85760405162461bcd60e51b815260206004820152603460248201527f54414c535542444f4d41494e5f5245474953545241523a20535542444f4d414960448201527f4e5f414c52454144595f52454749535445524544000000000000000000000000606482015260840161045f565b6105f6848685856000610d46565b5050505050565b610605610cec565b6003546002546040517f224199c20000000000000000000000000000000000000000000000000000000081526001600160a01b039283169263224199c29261065a928892889288929116903090600401611685565b600060405180830381600087803b15801561067457600080fd5b505af1158015610688573d6000803e3d6000fd5b50505050505050565b610699610cec565b6001546040517f5b0fc9c30000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201526001600160a01b03838116602483015290911690635b0fc9c390604401600060405180830381600087803b15801561071f57600080fd5b505af1158015610733573d6000803e3d6000fd5b50506040516001600160a01b03841692507f80876669255bbe670102b94465f3622bfeaf7c469f8d25da3f9492fda77be2189150600090a250565b610776610cec565b6107806000610f70565b565b61078a610cec565b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b80516020808301919091206001546040516000936001600160a01b03909216916302571be391610816917f000000000000000000000000000000000000000000000000000000000000000091869101918252602082015260400190565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b815260040161084a91815260200190565b60206040518083038186803b15801561086257600080fd5b505afa158015610876573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061089a9190611399565b9392505050565b6108a9610cec565b6005548114156109215760405162461bcd60e51b815260206004820152603760248201527f54414c535542444f4d41494e5f5245474953545241523a204e6577206665652060448201527f6d617463686573207468652063757272656e7420666565000000000000000000606482015260840161045f565b60058190556040518181527fcb68a7bea0c5859aaa9685064dc77fd526c1541b8dadc621789c571efcf64eea9060200160405180910390a150565b60006005546000141561096f5750600090565b6000600460009054906101000a90046001600160a01b03166001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b1580156109bf57600080fd5b505afa1580156109d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f791906115e8565b5050509150506000610a0e826402540be400610fcd565b90506000610a26600554670de0b6b3a7640000610fcd565b9050610a43610a3d82670de0b6b3a7640000610fcd565b83610fd9565b935050505090565b610a53610cec565b610a5c81610fe5565b50565b60065460ff1615610ad85760405162461bcd60e51b815260206004820152603660248201527f54414c535542444f4d41494e5f5245474953545241523a20436f6e747261637460448201527f2069732063757272656e746c792073746f707065642e00000000000000000000606482015260840161045f565b60008180519060200120905060007f000000000000000000000000000000000000000000000000000000000000000082604051602001610b22929190918252602082015260400190565b60408051808303601f190181529082905280516020909101206001546302571be360e01b8352600483018290529092506000916001600160a01b03909116906302571be39060240160206040518083038186803b158015610b8257600080fd5b505afa158015610b96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bba9190611399565b90506001600160a01b03811615610c395760405162461bcd60e51b815260206004820152603460248201527f54414c535542444f4d41494e5f5245474953545241523a20535542444f4d414960448201527f4e5f414c52454144595f52454749535445524544000000000000000000000000606482015260840161045f565b610c45338585856111e4565b50505050565b610c53610cec565b6001600160a01b038116610ccf5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161045f565b610a5c81610f70565b610ce0610cec565b6006805460ff19169055565b6000546001600160a01b031633146107805760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161045f565b6001546002546040516305ef2c7f60e41b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018690523060448201526001600160a01b03918216606482015260006084820152911690635ef2c7f09060a401600060405180830381600087803b158015610dc957600080fd5b505af1158015610ddd573d6000803e3d6000fd5b50506002546040517fd5fa2b00000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b038981166024830152909116925063d5fa2b009150604401600060405180830381600087803b158015610e4857600080fd5b505af1158015610e5c573d6000803e3d6000fd5b50506001546040517f06ab59230000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018790526001600160a01b03898116604483015290911692506306ab59239150606401602060405180830381600087803b158015610eed57600080fd5b505af1158015610f01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2591906113b6565b50846001600160a01b03167fe5a2fb255dcde603207f25d174df1258a5334eefd2d4484e801e0bf66c200b038583604051610f61929190611757565b60405180910390a25050505050565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600061089a82846117f5565b600061089a82846117d3565b60008180519060200120905060007f00000000000000000000000000000000000000000000000000000000000000008260405160200161102f929190918252602082015260400190565b60408051808303601f190181529082905280516020909101206001546302571be360e01b8352600483018290529092506000916001600160a01b03909116906302571be39060240160206040518083038186803b15801561108f57600080fd5b505afa1580156110a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c79190611399565b90506001600160a01b0381166111455760405162461bcd60e51b815260206004820152603060248201527f54414c535542444f4d41494e5f5245474953545241523a20535542444f4d414960448201527f4e5f4e4f545f5245474953544552454400000000000000000000000000000000606482015260840161045f565b6001546040516305ef2c7f60e41b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018590526000604482018190526064820181905260848201526001600160a01b0390911690635ef2c7f09060a401600060405180830381600087803b1580156111c657600080fd5b505af11580156111da573d6000803e3d6000fd5b5050505050505050565b60006111ee61095c565b9050803410156112665760405162461bcd60e51b815260206004820152603360248201527f54414c535542444f4d41494e5f5245474953545241523a20416d6f756e74207060448201527f6173736564206973206e6f7420656e6f75676800000000000000000000000000606482015260840161045f565b803411156112a657336108fc61127c8334611814565b6040518115909202916000818181858888f193505050501580156112a4573d6000803e3d6000fd5b505b600080546040516001600160a01b039091169183156108fc02918491818181858888f193505050501580156112df573d6000803e3d6000fd5b506105f68585858585610d46565b600082601f8301126112fe57600080fd5b813567ffffffffffffffff81111561131857611318611841565b61132b601f8201601f19166020016117a2565b81815284602083860101111561134057600080fd5b816020850160208301376000918101602001919091529392505050565b805169ffffffffffffffffffff8116811461137757600080fd5b919050565b60006020828403121561138e57600080fd5b813561089a81611857565b6000602082840312156113ab57600080fd5b815161089a81611857565b6000602082840312156113c857600080fd5b5051919050565b6000806000606084860312156113e457600080fd5b67ffffffffffffffff80853511156113fb57600080fd5b61140886863587016112ed565b935060208501358181111561141c57600080fd5b8501601f8101871361142d57600080fd5b80358281111561143f5761143f611841565b61144e60208260051b016117a2565b80828252602082019150602084018a60208560051b870101111561147157600080fd5b60005b8481101561150e57868235111561148a57600080fd5b813586016040818e03601f190112156114a257600080fd5b6114aa611779565b6020820135898111156114bc57600080fd5b6114cb8f6020838601016112ed565b8252506040820135898111156114e057600080fd5b6114ef8f6020838601016112ed565b6020838101919091529187525094850194929092019150600101611474565b50508096505050505060408501358181111561152957600080fd5b611535878288016112ed565b925050509250925092565b60006020828403121561155257600080fd5b813567ffffffffffffffff81111561156957600080fd5b611575848285016112ed565b949350505050565b6000806040838503121561159057600080fd5b823567ffffffffffffffff8111156115a757600080fd5b6115b3858286016112ed565b92505060208301356115c481611857565b809150509250929050565b6000602082840312156115e157600080fd5b5035919050565b600080600080600060a0868803121561160057600080fd5b6116098661135d565b945060208601519350604086015192506060860151915061162c6080870161135d565b90509295509295909350565b6000815180845260005b8181101561165e57602081850181015186830182015201611642565b81811115611670576000602083870101525b50601f01601f19169290920160200192915050565b60a08152600061169860a0830188611638565b6020838203818501528188518084528284019150828160051b850101838b0160005b8381101561170e57601f198784030185528151604081518186526116e082870182611638565b915050878201519150848103888601526116fa8183611638565b9688019694505050908501906001016116ba565b50508681036040880152611722818b611638565b9550505050505061173e60608301856001600160a01b03169052565b6001600160a01b03831660808301529695505050505050565b60408152600061176a6040830185611638565b90508260208301529392505050565b6040805190810167ffffffffffffffff8111828210171561179c5761179c611841565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156117cb576117cb611841565b604052919050565b6000826117f057634e487b7160e01b600052601260045260246000fd5b500490565b600081600019048311821515161561180f5761180f61182b565b500290565b6000828210156118265761182661182b565b500390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610a5c57600080fdfea2646970667358221220792f0d3842be74bb5245e4c82ec24da99c7936d4fee9194dfce0447127eb967964736f6c6343000807003300000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e0000000000000000000000004976fb03c32e5b8cfe2b6ccb31c09ba78ebaba41000000000000000000000000a2f428617a523837d4adc81c67a296d42fd95e860000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b8419354819c1b2a342014cc40aa6bfc675f4a889f13e7ac60e77f1715954afedbc35000000000000000000000000c925bd0e839e8e22a7ddebe7f4c21b187deec3580000000000000000000000000000000000000000000000000000000000000008
Deployed Bytecode
0x60806040526004361061015f5760003560e01c8063957f992d116100c0578063f2800a1411610074578063f2fde38b11610059578063f2fde38b14610395578063f8256121146103b5578063fcfff16f146103d557600080fd5b8063f2800a1414610362578063f2c298be1461038257600080fd5b8063ab517d13116100a5578063ab517d1314610317578063be8ee97514610337578063e37ce2b11461034c57600080fd5b8063957f992d146102d7578063a4f50b75146102f757600080fd5b8063715018a6116101175780637d73b231116100fc5780637d73b231146102615780638da5cb5b14610299578063943e60aa146102b757600080fd5b8063715018a61461022257806375f12b211461023757600080fd5b806339998ddb1161014857806339998ddb1461019b5780634a9fe1c7146101bb57806354bfc7e51461020257600080fd5b806307da68f51461016457806307ddce4e1461017b575b600080fd5b34801561017057600080fd5b506101796103ea565b005b34801561018757600080fd5b5061017961019636600461157d565b61047f565b3480156101a757600080fd5b506101796101b63660046113cf565b6105fd565b3480156101c757600080fd5b506101ef7f354819c1b2a342014cc40aa6bfc675f4a889f13e7ac60e77f1715954afedbc3581565b6040519081526020015b60405180910390f35b34801561020e57600080fd5b5061017961021d36600461137c565b610691565b34801561022e57600080fd5b5061017961076e565b34801561024357600080fd5b506006546102519060ff1681565b60405190151581526020016101f9565b34801561026d57600080fd5b50600154610281906001600160a01b031681565b6040516001600160a01b0390911681526020016101f9565b3480156102a557600080fd5b506000546001600160a01b0316610281565b3480156102c357600080fd5b50600354610281906001600160a01b031681565b3480156102e357600080fd5b506101796102f236600461137c565b610782565b34801561030357600080fd5b50610281610312366004611540565b6107b9565b34801561032357600080fd5b506101796103323660046115cf565b6108a1565b34801561034357600080fd5b506101ef61095c565b34801561035857600080fd5b506101ef60055481565b34801561036e57600080fd5b5061017961037d366004611540565b610a4b565b610179610390366004611540565b610a5f565b3480156103a157600080fd5b506101796103b036600461137c565b610c4b565b3480156103c157600080fd5b50600254610281906001600160a01b031681565b3480156103e157600080fd5b50610179610cd8565b60065460ff16156104685760405162461bcd60e51b815260206004820152603660248201527f54414c535542444f4d41494e5f5245474953545241523a20436f6e747261637460448201527f2069732063757272656e746c792073746f707065642e0000000000000000000060648201526084015b60405180910390fd5b610470610cec565b6006805460ff19166001179055565b610487610cec565b60008280519060200120905060007f354819c1b2a342014cc40aa6bfc675f4a889f13e7ac60e77f1715954afedbc35826040516020016104d1929190918252602082015260400190565b60408051808303601f190181529082905280516020909101206001546302571be360e01b8352600483018290529092506000916001600160a01b03909116906302571be39060240160206040518083038186803b15801561053157600080fd5b505afa158015610545573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105699190611399565b90506001600160a01b038116156105e85760405162461bcd60e51b815260206004820152603460248201527f54414c535542444f4d41494e5f5245474953545241523a20535542444f4d414960448201527f4e5f414c52454144595f52454749535445524544000000000000000000000000606482015260840161045f565b6105f6848685856000610d46565b5050505050565b610605610cec565b6003546002546040517f224199c20000000000000000000000000000000000000000000000000000000081526001600160a01b039283169263224199c29261065a928892889288929116903090600401611685565b600060405180830381600087803b15801561067457600080fd5b505af1158015610688573d6000803e3d6000fd5b50505050505050565b610699610cec565b6001546040517f5b0fc9c30000000000000000000000000000000000000000000000000000000081527f354819c1b2a342014cc40aa6bfc675f4a889f13e7ac60e77f1715954afedbc3560048201526001600160a01b03838116602483015290911690635b0fc9c390604401600060405180830381600087803b15801561071f57600080fd5b505af1158015610733573d6000803e3d6000fd5b50506040516001600160a01b03841692507f80876669255bbe670102b94465f3622bfeaf7c469f8d25da3f9492fda77be2189150600090a250565b610776610cec565b6107806000610f70565b565b61078a610cec565b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b80516020808301919091206001546040516000936001600160a01b03909216916302571be391610816917f354819c1b2a342014cc40aa6bfc675f4a889f13e7ac60e77f1715954afedbc3591869101918252602082015260400190565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b815260040161084a91815260200190565b60206040518083038186803b15801561086257600080fd5b505afa158015610876573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061089a9190611399565b9392505050565b6108a9610cec565b6005548114156109215760405162461bcd60e51b815260206004820152603760248201527f54414c535542444f4d41494e5f5245474953545241523a204e6577206665652060448201527f6d617463686573207468652063757272656e7420666565000000000000000000606482015260840161045f565b60058190556040518181527fcb68a7bea0c5859aaa9685064dc77fd526c1541b8dadc621789c571efcf64eea9060200160405180910390a150565b60006005546000141561096f5750600090565b6000600460009054906101000a90046001600160a01b03166001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b1580156109bf57600080fd5b505afa1580156109d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f791906115e8565b5050509150506000610a0e826402540be400610fcd565b90506000610a26600554670de0b6b3a7640000610fcd565b9050610a43610a3d82670de0b6b3a7640000610fcd565b83610fd9565b935050505090565b610a53610cec565b610a5c81610fe5565b50565b60065460ff1615610ad85760405162461bcd60e51b815260206004820152603660248201527f54414c535542444f4d41494e5f5245474953545241523a20436f6e747261637460448201527f2069732063757272656e746c792073746f707065642e00000000000000000000606482015260840161045f565b60008180519060200120905060007f354819c1b2a342014cc40aa6bfc675f4a889f13e7ac60e77f1715954afedbc3582604051602001610b22929190918252602082015260400190565b60408051808303601f190181529082905280516020909101206001546302571be360e01b8352600483018290529092506000916001600160a01b03909116906302571be39060240160206040518083038186803b158015610b8257600080fd5b505afa158015610b96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bba9190611399565b90506001600160a01b03811615610c395760405162461bcd60e51b815260206004820152603460248201527f54414c535542444f4d41494e5f5245474953545241523a20535542444f4d414960448201527f4e5f414c52454144595f52454749535445524544000000000000000000000000606482015260840161045f565b610c45338585856111e4565b50505050565b610c53610cec565b6001600160a01b038116610ccf5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161045f565b610a5c81610f70565b610ce0610cec565b6006805460ff19169055565b6000546001600160a01b031633146107805760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161045f565b6001546002546040516305ef2c7f60e41b81527f354819c1b2a342014cc40aa6bfc675f4a889f13e7ac60e77f1715954afedbc356004820152602481018690523060448201526001600160a01b03918216606482015260006084820152911690635ef2c7f09060a401600060405180830381600087803b158015610dc957600080fd5b505af1158015610ddd573d6000803e3d6000fd5b50506002546040517fd5fa2b00000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b038981166024830152909116925063d5fa2b009150604401600060405180830381600087803b158015610e4857600080fd5b505af1158015610e5c573d6000803e3d6000fd5b50506001546040517f06ab59230000000000000000000000000000000000000000000000000000000081527f354819c1b2a342014cc40aa6bfc675f4a889f13e7ac60e77f1715954afedbc356004820152602481018790526001600160a01b03898116604483015290911692506306ab59239150606401602060405180830381600087803b158015610eed57600080fd5b505af1158015610f01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2591906113b6565b50846001600160a01b03167fe5a2fb255dcde603207f25d174df1258a5334eefd2d4484e801e0bf66c200b038583604051610f61929190611757565b60405180910390a25050505050565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600061089a82846117f5565b600061089a82846117d3565b60008180519060200120905060007f354819c1b2a342014cc40aa6bfc675f4a889f13e7ac60e77f1715954afedbc358260405160200161102f929190918252602082015260400190565b60408051808303601f190181529082905280516020909101206001546302571be360e01b8352600483018290529092506000916001600160a01b03909116906302571be39060240160206040518083038186803b15801561108f57600080fd5b505afa1580156110a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c79190611399565b90506001600160a01b0381166111455760405162461bcd60e51b815260206004820152603060248201527f54414c535542444f4d41494e5f5245474953545241523a20535542444f4d414960448201527f4e5f4e4f545f5245474953544552454400000000000000000000000000000000606482015260840161045f565b6001546040516305ef2c7f60e41b81527f354819c1b2a342014cc40aa6bfc675f4a889f13e7ac60e77f1715954afedbc356004820152602481018590526000604482018190526064820181905260848201526001600160a01b0390911690635ef2c7f09060a401600060405180830381600087803b1580156111c657600080fd5b505af11580156111da573d6000803e3d6000fd5b5050505050505050565b60006111ee61095c565b9050803410156112665760405162461bcd60e51b815260206004820152603360248201527f54414c535542444f4d41494e5f5245474953545241523a20416d6f756e74207060448201527f6173736564206973206e6f7420656e6f75676800000000000000000000000000606482015260840161045f565b803411156112a657336108fc61127c8334611814565b6040518115909202916000818181858888f193505050501580156112a4573d6000803e3d6000fd5b505b600080546040516001600160a01b039091169183156108fc02918491818181858888f193505050501580156112df573d6000803e3d6000fd5b506105f68585858585610d46565b600082601f8301126112fe57600080fd5b813567ffffffffffffffff81111561131857611318611841565b61132b601f8201601f19166020016117a2565b81815284602083860101111561134057600080fd5b816020850160208301376000918101602001919091529392505050565b805169ffffffffffffffffffff8116811461137757600080fd5b919050565b60006020828403121561138e57600080fd5b813561089a81611857565b6000602082840312156113ab57600080fd5b815161089a81611857565b6000602082840312156113c857600080fd5b5051919050565b6000806000606084860312156113e457600080fd5b67ffffffffffffffff80853511156113fb57600080fd5b61140886863587016112ed565b935060208501358181111561141c57600080fd5b8501601f8101871361142d57600080fd5b80358281111561143f5761143f611841565b61144e60208260051b016117a2565b80828252602082019150602084018a60208560051b870101111561147157600080fd5b60005b8481101561150e57868235111561148a57600080fd5b813586016040818e03601f190112156114a257600080fd5b6114aa611779565b6020820135898111156114bc57600080fd5b6114cb8f6020838601016112ed565b8252506040820135898111156114e057600080fd5b6114ef8f6020838601016112ed565b6020838101919091529187525094850194929092019150600101611474565b50508096505050505060408501358181111561152957600080fd5b611535878288016112ed565b925050509250925092565b60006020828403121561155257600080fd5b813567ffffffffffffffff81111561156957600080fd5b611575848285016112ed565b949350505050565b6000806040838503121561159057600080fd5b823567ffffffffffffffff8111156115a757600080fd5b6115b3858286016112ed565b92505060208301356115c481611857565b809150509250929050565b6000602082840312156115e157600080fd5b5035919050565b600080600080600060a0868803121561160057600080fd5b6116098661135d565b945060208601519350604086015192506060860151915061162c6080870161135d565b90509295509295909350565b6000815180845260005b8181101561165e57602081850181015186830182015201611642565b81811115611670576000602083870101525b50601f01601f19169290920160200192915050565b60a08152600061169860a0830188611638565b6020838203818501528188518084528284019150828160051b850101838b0160005b8381101561170e57601f198784030185528151604081518186526116e082870182611638565b915050878201519150848103888601526116fa8183611638565b9688019694505050908501906001016116ba565b50508681036040880152611722818b611638565b9550505050505061173e60608301856001600160a01b03169052565b6001600160a01b03831660808301529695505050505050565b60408152600061176a6040830185611638565b90508260208301529392505050565b6040805190810167ffffffffffffffff8111828210171561179c5761179c611841565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156117cb576117cb611841565b604052919050565b6000826117f057634e487b7160e01b600052601260045260246000fd5b500490565b600081600019048311821515161561180f5761180f61182b565b500290565b6000828210156118265761182661182b565b500390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610a5c57600080fdfea2646970667358221220792f0d3842be74bb5245e4c82ec24da99c7936d4fee9194dfce0447127eb967964736f6c63430008070033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e0000000000000000000000004976fb03c32e5b8cfe2b6ccb31c09ba78ebaba41000000000000000000000000a2f428617a523837d4adc81c67a296d42fd95e860000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b8419354819c1b2a342014cc40aa6bfc675f4a889f13e7ac60e77f1715954afedbc35000000000000000000000000c925bd0e839e8e22a7ddebe7f4c21b187deec3580000000000000000000000000000000000000000000000000000000000000008
-----Decoded View---------------
Arg [0] : ens (address): 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
Arg [1] : resolver (address): 0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41
Arg [2] : registrar (address): 0xa2F428617a523837d4adC81C67a296d42FD95e86
Arg [3] : priceFeedAddress (address): 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419
Arg [4] : node (bytes32): 0x354819c1b2a342014cc40aa6bfc675f4a889f13e7ac60e77f1715954afedbc35
Arg [5] : contractOwner (address): 0xC925bD0E839E8e22A7DDEbe7f4C21b187deeC358
Arg [6] : initialSubdomainFee (uint256): 8
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e
Arg [1] : 0000000000000000000000004976fb03c32e5b8cfe2b6ccb31c09ba78ebaba41
Arg [2] : 000000000000000000000000a2f428617a523837d4adc81c67a296d42fd95e86
Arg [3] : 0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b8419
Arg [4] : 354819c1b2a342014cc40aa6bfc675f4a889f13e7ac60e77f1715954afedbc35
Arg [5] : 000000000000000000000000c925bd0e839e8e22a7ddebe7f4c21b187deec358
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000008
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.