DotnsRegistrarController
Inherits: Initializable, UUPSUpgradeable, DotnsRoleManager, ReentrancyGuardTransient, IDotnsRegistrarController
Title: Dotns Registrar Controller
Allocates .dot labels using a commit reveal scheme.
Orchestrates allocation, PoP validation, pricing enforcement, forward registry
wiring, default reverse resolution, and immutable store writing.
Tokenisation: the minted ERC721 tokenId is uint256(node), where
node = namehash(DOT_NODE, labelhash). The registry stores a sentinel owner
(address(0)) for tokenised nodes and derives ownership from the ERC721 registrar for
authorisation.
Note: security-contact: admin@parity.io
Constants
MAX_ALLOWED_COMMITMENT_AGE
Upper bound for commitment validity to cap storage griefing risk.
uint256 public constant MAX_ALLOWED_COMMITMENT_AGE = 7 days
State Variables
minCommitmentAge
Minimum age a commitment must reach before reveal.
uint256 public minCommitmentAge
maxCommitmentAge
Maximum age after which a commitment expires.
uint256 public maxCommitmentAge
commitments
Stores Mapping of commitment hashes to timestamp committed.
mapping(bytes32 hash => uint256 timestamp) public commitments
whiteList
Whitelist for addresses allowed to call registerReserved.
mapping(address user => bool isWhiteListed) public whiteList
protocolRegistry
Protocol-level address registry for all DotNS contracts.
IDotnsProtocolRegistry public protocolRegistry
__gap
Reserved storage space to allow for layout changes in the future.
uint256[50] private __gap
Functions
onlyWhiteListedOrOwner
Restricts calls to whitelisted addresses or the owner.
Used to gate registerReserved, which allows registering reserved names without
PoP checks or payment. Necessary so the owner (or a whitelisted operator) can seed
reserved names on behalf of users who are already known and verified and do not need
PoP checks.
modifier onlyWhiteListedOrOwner() ;
onlyWhitelistOperatorOrOwner
modifier onlyWhitelistOperatorOrOwner() ;
constructor
Note: oz-upgrades-unsafe-allow: constructor
constructor() ;
initialize
Initialises the registrar controller.
Callable once through the UUPS proxy; direct calls on the implementation revert
with @custom:reverts InvalidInitialization, and any nested call outside an active
initialiser scope reverts with @custom:reverts NotInitializing. Validates the
commitment window bounds: minAge must be strictly positive (otherwise
Notes:
-
reverts: MinCommitmentAgeZero) so a reveal cannot land in the same block as its commit;
maxAgemust exceedminAge(otherwise -
reverts: MaxCommitmentAgeTooLow) and must stay within
MAX_ALLOWED_COMMITMENT_AGE(otherwise @custom:reverts MaxCommitmentAgeTooHigh) before wiring the protocol registry.
function initialize(
IDotnsProtocolRegistry registry,
uint256 minAge,
uint256 maxAge
)
external
initializer;
available
Returns whether a label is available for registration.
Validates the canonical DNS-label shape (otherwise @custom:reverts InvalidLabel) and rejects labels below the minimum-length policy with
Note: reverts: LabelTooShort before checking ERC721 availability on the registrar.
function available(string calldata label) public view override returns (bool);
makeCommitment
Computes the commitment hash for a registration.
Uses abi.encode so the variable-width label is length-prefixed and the boundary
between label and the fixed-width owner, secret, and reserved fields is
unambiguous, binding the commitment to the exact tuple.
function makeCommitment(Registration calldata registration)
public
pure
override
returns (bytes32 commitment);
commit
Submits a commitment for a future registration.
Idempotent over expiry: re-committing an unexpired hash reverts with
Note:
reverts: UnexpiredCommitmentExists (front-running guard); a hash whose stored
timestamp has passed maxCommitmentAge overwrites the slot so storage cannot be
permanently griefed. The expiry boundary is inclusive on the commit side
(committedAt + maxCommitmentAge <= block.timestamp overwrites) and exclusive on the
reveal side (register rejects at the same instant with @custom:reverts
CommitmentTooOld), so the slot is overwritable from exactly the timestamp at which
reveal begins rejecting it. Emits @custom:emits NameCommitted on success.
function commit(bytes32 commitment) external override;
register
Registers a name after the commitment delay.
Validates the label shape (otherwise @custom:reverts InvalidLabel), rejects labels
below the minimum length policy (@custom:reverts LabelTooShort), and ERC721 availability
(otherwise @custom:reverts NameNotAvailable), then consumes the prior commitment, which
fails with @custom:reverts CommitmentNotFound when no commitment exists for the supplied
registration, @custom:reverts CommitmentTooNew before minCommitmentAge, and
Note:
reverts: CommitmentTooOld past maxCommitmentAge, and finally resolves the
configured escrow address from the protocol registry (otherwise
function register(Registration calldata registration) external payable override nonReentrant;
_settleEscrow
Settles every escrow side-effect of a successful registration.
Extracted to keep register under the stack-depth ceiling. On a direct
registration the full chargeAmount lands in the refundable deposit position
keyed to nameOwner. On a cross-payer registration the deposit position is
seeded with a zero amount so the release lifecycle stays reachable, and the same
chargeAmount routes to the insurance fund via depositInsurance keyed to
msg.sender as the payer.
function _settleEscrow(
address escrow,
uint256 tokenId,
address nameOwner,
bool isDirect,
uint256 chargeAmount
)
internal;
isWhiteListed
Checks if the given address is whitelisted to call registerReserved.
function isWhiteListed(address who) external view override returns (bool);
whiteListAddress
Adds or removes an address from the whitelist for registerReserved.
Callable by the owner or an account holding DotnsConstants.WHITELIST_OPERATOR_ROLE;
any other caller reverts with @custom:reverts IDotnsRoleManager.NotRoleOrOwner. Emits
Note: emits: WhiteListed on success.
function whiteListAddress(
address who,
bool whiteListStatus
)
external
override
onlyWhitelistOperatorOrOwner;
registerReserved
Registers a name after the commitment delay.
Whitelisted issuance path used to seed reserved labels at zero base cost: skips the PoP price check and the escrow deposit, but reuses the same commit-reveal pipeline so the same anti-front-running guarantees apply. Restricted to whitelisted callers and the owner (otherwise @custom:reverts NotWhiteListedOrOwner). Validates the label shape (otherwise @custom:reverts InvalidLabel) and ERC721 availability (otherwise
Notes:
-
reverts: NameNotAvailable), then consumes the prior commitment, which fails with
-
emits: NameRegistered on success.
function registerReserved(Registration calldata registration)
external
override
onlyWhiteListedOrOwner
nonReentrant;
supportsInterface
Returns true if this contract implements the interface defined by
interfaceId. See the corresponding
https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
to learn more about how these ids are created.
This function call must use less than 30 000 gas.
function supportsInterface(bytes4 interfaceId)
public
view
override(DotnsRoleManager, IERC165)
returns (bool);
_validatedLabelNode
Validates label shape and derives (labelhash, node).
Delegates hashing to @custom:contract LabelUtils so the assembly sequence lives in
exactly one place across the codebase. Error ownership stays on this interface: shape
violations revert with InvalidLabel(); labels below the minimum length revert with
LabelTooShort(label) so off-chain consumers can distinguish "shape-valid but below
the policy minimum" from "shape-valid but already minted".
function _validatedLabelNode(string calldata label)
internal
pure
returns (bytes32 labelhash, bytes32 node);
_requireAvailableLabel
function _requireAvailableLabel(string calldata label)
internal
view
returns (IDotnsRegistrar registrar, bytes32 labelhash, bytes32 node);
_consumeCommitment
function _consumeCommitment(Registration calldata registration) internal;
_completeRegistration
Completes a commit-reveal registration: mints (or skips when reclaiming), wires forward registry, optionally sets the reverse record, and writes the owner's Store.
On a fresh mint the triad of mint + forward-registry + store-write is delegated to @custom:function RegistrationUtils.registerAndStore, the single canonical implementation shared across every DotNS registration flow. On a reclaim the mint step is skipped (the escrow has already moved custody) and only the registry wiring and store write run. Reverse-record setting and the priced-registration event stay here because they are commit-reveal-specific policy.
function _completeRegistration(
Registration calldata registration,
bytes32 labelhash,
bytes32 node,
uint256 baseCost,
bool setReverseRecord,
IDotnsReverseResolver reverse,
bool isReclaim
)
internal;
_escrow
Returns the configured name escrow from the protocol registry.
function _escrow() internal view returns (address escrow);
version
Returns implementation version.
function version() external pure virtual returns (string memory versionString);
Returns
| Name | Type | Description |
|---|---|---|
versionString | string | Current version string. |
_onlyWhiteListedOrOwner
Internal check enforcing whitelist-or-owner access.
function _onlyWhiteListedOrOwner() internal view;
_isSupportedRole
function _isSupportedRole(bytes32 role) internal view override returns (bool supported);
_authorizeUpgrade
Function that should revert when msg.sender is not authorized to upgrade the contract.
Called by
{upgradeToAndCall}.
Normally, this function will use an xref:access.adoc[access control] modifier such as
{Ownable-onlyOwner}.
function _authorizeUpgrade(address) internal onlyOwner {}
function _authorizeUpgrade(address newImplementation) internal override onlyOwner;