-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Registrar fixes #3
Conversation
These values will never change, so setting them as constants makes auditing the contract a little easier.
The new ens registry has a fallback mechanism where the old registry will be queried if an owner for a record cannot be found in the new registry. The logic for this mechanism makes use to two sentinel values for the `owner` field in a record: - `address(0)`: no owner found in the new registry, try the old one - `address(this)`: record is unowned, do not fallback to the old registrar Calling `setOwner(record, address(0))` on the new registrar will in fact set a value of `address(this)` for the owner field on that record. the `recordExists` method only checks if the owner of a domain is `address(0)` and returns `true` otherwise. The combination of the above two points meant that revoked names (where the owner had been set to `address(0)`) could not be reregistered. This commit replaces the call to `recordExists` with a check based on `ens.owner(node)` (which returns `address(0)` when the owner of a record is `address(this)`), thus allowing reregistration of intentionally revoked names.
This check ensures that the owner of the "eth" tld in the ens registry has been set. However the call to `setDomainOwner` will always fail if this is not the case (due to the call to `transferFrom` later in the method). Removing as this is not a user facing method, and clarity of implementation trumps clarity of error messages in this case.
The `setDomainOwner` method should not set the resolver and ttl values. In particular the previous behaviour (setting the resolver to the address of the new domain owner) seems almost certain to be wrong (and cause disruption for downstream clients who may rely on the resolver for the `radicle.eth` domain).
Either sets a default value for the resolver and ttl, or allows the caller to specify a custom one when registering a new name.
This prevents an attack where a malicious actor could scan the mempool and front run name registration before charging the original registrant an extra fee.
The ENS registry has migrated before, and may do so again in the future, this change gives admin a little more flexibility in case such a situation arises again in the future.
This prevents an attack where a malicious actor could frontrun a call to `register` with an atomic call to `commit` followed by `register` for the same name. 50 blocks has been (somewhat arbitrarily) chosen as a default for now, some more work is required to justify the safety of this value in the face of e.g. heavy network congestion.
contracts/Registrar.sol
Outdated
commited[commitment] = block.number; | ||
} | ||
|
||
function mkCommitment( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this can live in the Registrar imo
contracts/Registrar.sol
Outdated
uint256 public registrationFeeUsd = 10; | ||
/// The minimum number of blocks that must have passed between a commitment and name registration | ||
// TODO: justify this as a default value... | ||
uint256 public minCommitmentAge = 50; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the purpose of having a minimum greater than 1
? Is it in case of a re-org? Perhaps worth documenting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, to cover network congestion, re-orgs, or cases where the register
tx was submitted with a very low gas fee.
Definately agree re: docs, was planning to write up a deeper analysis of the commit / reveal scheme in the audit report.
contracts/Registrar.sol
Outdated
/// Commit to a future name registration | ||
function commit(bytes32 commitment) external { | ||
require(commitments.commited(commitment) == 0, "Registrar::commit: already commited"); | ||
require(rad.balanceOf(msg.sender) >= fee, "Registrar::register: insufficient rad balance"); | ||
|
||
rad.burnFrom(msg.sender, fee); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah so the burn happens on commit, not on reveal. I guess this means commitments shouldn't expire, right? (Which I believe they don't)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, commitments currently do not expire.
contracts/Registrar.sol
Outdated
} | ||
|
||
function _register(bytes32 label, address owner) private { | ||
bytes32 node = namehash(domain, label); | ||
/// Register a subdomain (with a custom resolver and ttl) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this function can be called by anyone. That could be useful if we want to bare the costs.
|
||
return valid(name) && !ens.recordExists(node); | ||
bytes32 node = namehash(radNode, label); | ||
return ens.owner(node) == address(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps worth documenting why we don't use recordExists
?
Looks good to me so far. |
- add commitWithPermit - fover RadicleToken over ERC20Burnable interface
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! I only have a few nitpicks
contracts/Registrar.sol
Outdated
|
||
/// The token ID for the node in the `eth` TLD, eg. sha256("radicle"). | ||
uint256 public immutable tokenId; | ||
uint256 public constant tokenId = uint(keccak256(abi.encodePacked("radicle"))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're hardcoding the full radicle.eth
domain here, is this necessary? It removes deployment elasticity making test deployments on real networks (ropsten/mainnet) impossible.
contracts/Registrar.sol
Outdated
|
||
/// Registration fee in *Radicle* (uRads). | ||
uint256 public registrationFeeRad = 1e18; | ||
uint256 public fee = 1e18; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This DeScRiPtIvE VaRiAbLe NaEms
is a part of the public API, it probably should be both descriptive and future-proof without renaming, we are considering different payment schemes.
contracts/Registrar.sol
Outdated
} | ||
|
||
/// Set the address for the ENS registry | ||
function setEns(address newEns) public adminOnly { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we realistically expect this to be ever used? If the ENS is moved, it's probably due to some API changes, which will require a full registrar update anyway. If we remove this function, we'll save some gas on accessing the ens
variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm inclined to agree. If another migration were to happen it could be dealt with by transferring ownership to a new Registrar.
Your comments should now be addressed @CodeSandwich |
This should address all the issues / improvements with the registrar we found in the report. In summary:
The changes here are relatively substantial (+149/-83) in the registrar, so this needs a lot more testing and review.
Most of the above changes are self contained in their own commit, so you might find it helpful to review commit by commit.