> For the complete documentation index, see [llms.txt](https://docs.dothype.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.dothype.io/architecture/how-it-all-works/dothype-smart-contracts/controller-contract.md).

# 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 →](/architecture/how-it-all-works/dothype-smart-contracts/resolver-contract.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.dothype.io/architecture/how-it-all-works/dothype-smart-contracts/controller-contract.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
