---
description: >-
  The dotHYPEController is the logic layer for domain registration. It manages
  who can mint, how much they pay, and how names are allocated across phases.
---

# Controller Contract

All domain registrations and renewals are routed through the controller; it’s the decision-making contract that sits between users and the registry.

This is where pricing, access rules, signature verification, and allowlist enforcement live.

### 🔍 What It Does

The Controller handles:

* Enforcing registration pricing (based on name length and duration)
* Processing payments in $HYPE (based on USD-pegged prices)
* Verifying signed requests to prevent front-running (via EIP-712)
* Checking Merkle proofs for allowlisted mints
* Managing name reservations (for pre-approved addresses)

> Think of it as the programmable access layer for the dotHYPE registry.

### 💸 Pricing Model

dotHYPE uses a simple but powerful pricing structure:

* Price is based on name length (e.g., 3-char names cost more than 5+)
* All prices are denominated in USD
* Payment is made in $HYPE, converted using an onchain oracle
* Registration and renewal are priced separately

Example (public mint):

* 3 characters: $100/year
* 4 characters: $40/year
* 5+ characters: $15/year

> Pricing can be updated over time by the protocol owner, but logic is hardcoded for length-based tiers.

To fetch the price:

```solidity
function getPrice(string calldata name, uint256 duration) public view returns (uint256);
```

***

### ✍️ Signature-Based Registration

Most mints use EIP-712 structured data to ensure fair access. This prevents bots from front-running open registrations.

```solidity
function registerWithSignature(...) external payable returns (uint256);
```

This flow:

1. Verifies a signed message from an authorized backend signer
2. Confirms the nonce hasn't been used
3. Calculates price and duration
4. Registers the name through the Registry

> Signatures are used in public mint, premium auction, and certain reserved phases.

***

### 🌿 Merkle-Based Allowlists

For whitelist and partner-only phases, we use Merkle trees to verify whether a user can register a name:

```solidity
function registerWithMerkleProof(...) external payable returns (uint256);
```

Each address on the allowlist can register one name. Proofs are verified onchain. The Merkle root is updated periodically by the owner.

***

### 🪪 Reserved Name Access

Some names are explicitly reserved for specific addresses—partners, integrations, or founders.

```solidity
function registerReservedName(...) external payable returns (uint256);
```

Only the address that a name is reserved for can register it. No one else can front-run or bypass this.

Admin can assign or remove reservations:

```solidity
function reserveName(...) external onlyOwner;
function removeReservation(...) external onlyOwner;
```

***

### 🔁 Renewal

Renewals are permissionless. Anyone can renew any name by paying the correct amount.

```solidity
function renew(string calldata name, uint256 duration) external payable returns (uint256);
```

* Duration is in seconds
* Pricing uses the renewal tier (not the first-year price)

***

### 🔐 Payment Handling

The Controller:

* Calculates price in $USD
* Converts it to $HYPE using a live price oracle
* Verifies the user paid enough
* Refunds any overpayment
* Sends funds to the treasury or designated recipient

> All payments are native token compatible—no need for approval flows.

***

### 🛠 Admin Functions

The Controller can be configured by the protocol owner (via multisig):

```solidity
setAnnualPrice()
setAnnualRenewalPrice()
setRegistry()
setSigner()
setPaymentRecipient()
setPriceOracle()
```

These functions adjust pricing, set key addresses, and manage access without changing the contract itself.

***

### 📡 Events for Tracking

Events emitted for downstream analytics:

* `DomainRegistered`
* `DomainRenewed`
* `ReservedNameRegistered`
* `MerkleProofRegistration`
* `SignerUpdated`, `PaymentRecipientUpdated`, `PriceOracleUpdated`

> These can be tracked via Subgraph or block explorer for indexers and dashboards.

***

### 🔎 For Developers

If you’re building a dApp or CLI for minting:

* Use `getPrice()` to fetch cost before submitting
* Use `registerWithSignature()` for standard public minting
* Use `registerWithMerkleProof()` for allowlisted flows

You don’t need to interact with the Registry directly—the Controller routes all writes.

> Want to mint for users via backend signature? Check our SDK guide or integration examples.

To see how a registered name becomes usable across dApps, dashboards, and wallets, continue to the [Resolver Contract →](resolver-contract)
