Skip to content

Commit

Permalink
v0.0.19
Browse files Browse the repository at this point in the history
  • Loading branch information
Arachnid committed Feb 23, 2023
1 parent 03fa257 commit f5f2ede
Show file tree
Hide file tree
Showing 14 changed files with 357 additions and 194 deletions.
10 changes: 5 additions & 5 deletions contracts/dnsregistrar/DNSClaimChecker.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ library DNSClaimChecker {
return (address(0x0), false);
}

function parseRR(bytes memory rdata, uint256 idx, uint256 endIdx)
internal
pure
returns (address, bool)
{
function parseRR(
bytes memory rdata,
uint256 idx,
uint256 endIdx
) internal pure returns (address, bool) {
while (idx < endIdx) {
uint256 len = rdata.readUint8(idx);
idx += 1;
Expand Down
31 changes: 17 additions & 14 deletions contracts/dnsregistrar/DNSRegistrar.sol
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,12 @@ contract DNSRegistrar is IDNSRegistrar, IERC165 {
name,
input
);
if(msg.sender != owner) {
if (msg.sender != owner) {
revert PermissionDenied(msg.sender, owner);
}
ens.setSubnodeRecord(rootNode, labelHash, owner, resolver, 0);
if (addr != address(0)) {
if(resolver == address(0)) {
if (resolver == address(0)) {
revert PreconditionNotMet();
}
bytes32 node = keccak256(abi.encodePacked(rootNode, labelHash));
Expand Down Expand Up @@ -156,28 +156,25 @@ contract DNSRegistrar is IDNSRegistrar, IERC165 {

bool found;
(addr, found) = DNSClaimChecker.getOwnerAddress(name, data);
if(!found) {
if (!found) {
revert NoOwnerRecordFound();
}

emit Claim(node, addr, name, inception);
}

function enableNode(bytes memory domain)
public
returns (bytes32 node)
{
function enableNode(bytes memory domain) public returns (bytes32 node) {
// Name must be in the public suffix list.
if(!suffixes.isPublicSuffix(domain)) {
if (!suffixes.isPublicSuffix(domain)) {
revert InvalidPublicSuffix(domain);
}
return _enableNode(domain, 0);
}

function _enableNode(bytes memory domain, uint256 offset)
internal
returns(bytes32 node)
{
function _enableNode(
bytes memory domain,
uint256 offset
) internal returns (bytes32 node) {
uint256 len = domain.readUint8(offset);
if (len == 0) {
return bytes32(0);
Expand All @@ -193,9 +190,15 @@ contract DNSRegistrar is IDNSRegistrar, IERC165 {
root.setSubnodeOwner(label, address(this));
ens.setResolver(node, resolver);
} else {
ens.setSubnodeRecord(parentNode, label, address(this), resolver, 0);
ens.setSubnodeRecord(
parentNode,
label,
address(this),
resolver,
0
);
}
} else if(owner != address(this)) {
} else if (owner != address(this)) {
revert PreconditionNotMet();
}
return node;
Expand Down
127 changes: 93 additions & 34 deletions contracts/dnsregistrar/OffchainDNSResolver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ error OffchainLookup(
);

interface IDNSGateway {
function resolve(bytes memory name, uint16 qtype) external returns(DNSSEC.RRSetWithSignature[] memory);
function resolve(
bytes memory name,
uint16 qtype
) external returns (DNSSEC.RRSetWithSignature[] memory);
}

uint16 constant CLASS_INET = 1;
Expand Down Expand Up @@ -57,14 +60,19 @@ contract OffchainDNSResolver is IExtendedResolver {
);
}

function resolveCallback(bytes calldata response, bytes calldata extraData)
external
view
returns (bytes memory)
{
(bytes memory name, bytes memory query) = abi.decode(extraData, (bytes, bytes));
DNSSEC.RRSetWithSignature[] memory rrsets = abi.decode(response, (DNSSEC.RRSetWithSignature[]));

function resolveCallback(
bytes calldata response,
bytes calldata extraData
) external view returns (bytes memory) {
(bytes memory name, bytes memory query) = abi.decode(
extraData,
(bytes, bytes)
);
DNSSEC.RRSetWithSignature[] memory rrsets = abi.decode(
response,
(DNSSEC.RRSetWithSignature[])
);

(bytes memory data, ) = oracle.verifyRRSet(rrsets);
for (
RRUtils.RRIterator memory iter = data.iterateRRs(0);
Expand All @@ -73,74 +81,118 @@ contract OffchainDNSResolver is IExtendedResolver {
) {
// Ignore records with wrong name, type, or class
bytes memory rrname = RRUtils.readName(iter.data, iter.offset);
if(!rrname.equals(name) || iter.class != CLASS_INET || iter.dnstype != TYPE_TXT) {
if (
!rrname.equals(name) ||
iter.class != CLASS_INET ||
iter.dnstype != TYPE_TXT
) {
continue;
}

// Look for a valid ENS-DNS TXT record
(address dnsresolver, bytes memory context) = parseRR(iter.data, iter.rdataOffset, iter.nextOffset);
(address dnsresolver, bytes memory context) = parseRR(
iter.data,
iter.rdataOffset,
iter.nextOffset
);

// If we found a valid record, try to resolve it
if(dnsresolver != address(0)) {
if(IERC165(dnsresolver).supportsInterface(IExtendedDNSResolver.resolve.selector)) {
return IExtendedDNSResolver(dnsresolver).resolve(name, query, context);
} else if(IERC165(dnsresolver).supportsInterface(IExtendedResolver.resolve.selector)) {
if (dnsresolver != address(0)) {
if (
IERC165(dnsresolver).supportsInterface(
IExtendedDNSResolver.resolve.selector
)
) {
return
IExtendedDNSResolver(dnsresolver).resolve(
name,
query,
context
);
} else if (
IERC165(dnsresolver).supportsInterface(
IExtendedResolver.resolve.selector
)
) {
return IExtendedResolver(dnsresolver).resolve(name, query);
} else {
(bool ok, bytes memory ret) = address(dnsresolver).staticcall(query);
if(ok) {
(bool ok, bytes memory ret) = address(dnsresolver)
.staticcall(query);
if (ok) {
return ret;
} else {
revert CouldNotResolve(name);
}
}
}
}

// No valid records; revert.
revert CouldNotResolve(name);
}

function parseRR(bytes memory data, uint256 idx, uint256 lastIdx) internal view returns (address, bytes memory) {
function parseRR(
bytes memory data,
uint256 idx,
uint256 lastIdx
) internal view returns (address, bytes memory) {
bytes memory txt = readTXT(data, idx, lastIdx);

// Must start with the magic word
if(txt.length < 5 || !txt.equals(0, "ENS1 ", 0, 5)) {
if (txt.length < 5 || !txt.equals(0, "ENS1 ", 0, 5)) {
return (address(0), "");
}

// Parse the name or address
uint256 lastTxtIdx = txt.find(5, txt.length - 5, " ");
if(lastTxtIdx > txt.length) {
if (lastTxtIdx > txt.length) {
address dnsResolver = parseAndResolve(txt, 5, txt.length);
return (dnsResolver, "");
} else {
address dnsResolver = parseAndResolve(txt, 5, lastTxtIdx);
return (dnsResolver, txt.substring(lastTxtIdx + 1, txt.length - lastTxtIdx - 1));
return (
dnsResolver,
txt.substring(lastTxtIdx + 1, txt.length - lastTxtIdx - 1)
);
}
}

function readTXT(bytes memory data, uint256 startIdx, uint256 lastIdx) internal pure returns(bytes memory) {
function readTXT(
bytes memory data,
uint256 startIdx,
uint256 lastIdx
) internal pure returns (bytes memory) {
// TODO: Concatenate multiple text fields
uint256 fieldLength = data.readUint8(startIdx);
assert(startIdx + fieldLength < lastIdx);
return data.substring(startIdx + 1, fieldLength);
}

function parseAndResolve(bytes memory nameOrAddress, uint256 idx, uint256 lastIdx) internal view returns(address) {
if(nameOrAddress[idx] == '0' && nameOrAddress[idx + 1] == 'x') {
(address ret, bool valid) = nameOrAddress.hexToAddress(idx + 2, lastIdx);
if(valid) {
function parseAndResolve(
bytes memory nameOrAddress,
uint256 idx,
uint256 lastIdx
) internal view returns (address) {
if (nameOrAddress[idx] == "0" && nameOrAddress[idx + 1] == "x") {
(address ret, bool valid) = nameOrAddress.hexToAddress(
idx + 2,
lastIdx
);
if (valid) {
return ret;
}
}
return resolveName(nameOrAddress, idx, lastIdx);
}

function resolveName(bytes memory name, uint256 idx, uint256 lastIdx) internal view returns(address) {
function resolveName(
bytes memory name,
uint256 idx,
uint256 lastIdx
) internal view returns (address) {
bytes32 node = textNamehash(name, idx, lastIdx);
address resolver = ens.resolver(node);
if(resolver == address(0)) {
if (resolver == address(0)) {
return address(0);
}
return IAddrResolver(resolver).addr(node);
Expand All @@ -152,14 +204,21 @@ contract OffchainDNSResolver is IExtendedResolver {
* @param idx Index to start at
* @param lastIdx Index to end at
*/
function textNamehash(bytes memory name, uint256 idx, uint256 lastIdx) internal view returns(bytes32) {
uint256 separator = name.find(idx, name.length - idx, bytes1('.'));
function textNamehash(
bytes memory name,
uint256 idx,
uint256 lastIdx
) internal view returns (bytes32) {
uint256 separator = name.find(idx, name.length - idx, bytes1("."));
bytes32 parentNode = bytes32(0);
if(separator < lastIdx) {
if (separator < lastIdx) {
parentNode = textNamehash(name, separator + 1, lastIdx);
} else {
separator = lastIdx;
}
return keccak256(abi.encodePacked(parentNode, name.keccak(idx, separator - idx)));
return
keccak256(
abi.encodePacked(parentNode, name.keccak(idx, separator - idx))
);
}
}
18 changes: 10 additions & 8 deletions contracts/dnsregistrar/mocks/DummyExtendedDNSSECResolver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ import "../../resolvers/profiles/IExtendedDNSResolver.sol";
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

contract DummyExtendedDNSSECResolver is IExtendedDNSResolver, IERC165 {
function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
function supportsInterface(
bytes4 interfaceId
) external pure override returns (bool) {
return interfaceId == type(IExtendedDNSResolver).interfaceId;
}

function resolve(bytes memory /* name */, bytes memory /* data */, bytes memory context)
external
view
override
returns (bytes memory) {
return abi.encode(context);
}
function resolve(
bytes memory /* name */,
bytes memory /* data */,
bytes memory context
) external view override returns (bytes memory) {
return abi.encode(context);
}
}
9 changes: 7 additions & 2 deletions contracts/dnsregistrar/mocks/DummyLegacyTextResolver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@ import "../../resolvers/profiles/ITextResolver.sol";
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

contract DummyLegacyTextResolver is ITextResolver, IERC165 {
function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
function supportsInterface(
bytes4 interfaceId
) external pure override returns (bool) {
return interfaceId == type(ITextResolver).interfaceId;
}

function text(bytes32 /* node */, string calldata key) external view override returns (string memory) {
function text(
bytes32 /* node */,
string calldata key
) external view override returns (string memory) {
return key;
}
}
10 changes: 5 additions & 5 deletions contracts/dnssec-oracle/BytesUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -404,11 +404,11 @@ library BytesUtils {
* @param idx The offset to start parsing at
* @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.
*/
function hexToAddress(bytes memory str, uint256 idx, uint256 lastIdx)
internal
pure
returns (address, bool)
{
function hexToAddress(
bytes memory str,
uint256 idx,
uint256 lastIdx
) internal pure returns (address, bool) {
if (lastIdx - idx < 40) return (address(0x0), false);
uint256 ret = 0;
for (uint256 i = idx; i < idx + 40; i++) {
Expand Down
11 changes: 5 additions & 6 deletions contracts/resolvers/profiles/ExtendedResolver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
pragma solidity ^0.8.4;

contract ExtendedResolver {
function resolve(bytes memory /* name */, bytes memory data)
external
view
returns (bytes memory)
{
function resolve(
bytes memory /* name */,
bytes memory data
) external view returns (bytes memory) {
(bool success, bytes memory result) = address(this).staticcall(data);
if(success) {
if (success) {
return result;
} else {
// Revert with the reason provided by the call
Expand Down
9 changes: 5 additions & 4 deletions contracts/resolvers/profiles/IExtendedDNSResolver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
pragma solidity ^0.8.4;

interface IExtendedDNSResolver {
function resolve(bytes memory name, bytes memory data, bytes memory context)
external
view
returns (bytes memory);
function resolve(
bytes memory name,
bytes memory data,
bytes memory context
) external view returns (bytes memory);
}
8 changes: 4 additions & 4 deletions contracts/resolvers/profiles/IExtendedResolver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
pragma solidity ^0.8.4;

interface IExtendedResolver {
function resolve(bytes memory name, bytes memory data)
external
view
returns (bytes memory);
function resolve(
bytes memory name,
bytes memory data
) external view returns (bytes memory);
}
Loading

0 comments on commit f5f2ede

Please sign in to comment.