# Soulbound TLD contract

The Soulbound TLD contract is almost identical to the Flexi TLD contract, except that it does not allow domain transfers beyong minting and burning. Soulbound TLD is another name for a non-transferable TLD.

See the Soulbound TLD contract here: https://github.com/punk-domains-2/punk-contracts/blob/main/contracts/factories/soulbound/SoulboundPunkTLD.sol

ABI (the same as for the Flexi TLD): https://github.com/punk-domains-2/punk-abi/blob/main/FlexiTldAbi.json

# Data

# Domain struct

Each domain name is represented as a struct:

struct Domain {
	string name;
	uint256 tokenId;
	address holder;
	string data;
  • name: Domain name that goes before the TLD name. For example: techie in techie.wagmi.
  • tokenId: Each domain is an NFT, which means it has a unique token ID. ID numbers increment for every newly minted domain starting with 0.
  • holder: The address that owns the domain. Domain also resolves to this address.
  • data (optional): Domain can also hold custom data in a stringified JSON object, for example: {"url": "https://my.homepage", "image": {"address": "0x123...orUrl", "tokenId": 22}, "description": "Some text", "twitter": "@techie1239", "friends": ["0x123..."]}.

Read more about custom data here.

Note that in Flexi/Soulbound contracts the Domain struct is defined in the IBasePunkTLD interface.

# Read methods

# metadataAddress*

The address of the smart contract that holds metadata for the domain.

function metadataAddress() public view returns(address)


  • Metadata contract address

# minter*

The address of the smart contract that is allowed to mint domains even if buyingEnabled is set to false. Useful if you want to have minting logic in a separate smart contract.

function minter() public view returns(address)


  • Minter contract address

# royaltyFeeUpdater*

The address of the entity (either EOA or a smart contract) which is allowed to update the royalty fee. Example: This can be a multisig wallet (like Safe) where two parties need to agree on the royalty fee change.

function royaltyFeeUpdater() public view returns(address)


  • Royalty Fee Updater address

# royaltyFeeReceiver*

The address which receives a royalty fee on each domain mint.

function royaltyFeeReceiver() public view returns(address)


  • Royalty Fee Receiver address

# buyingEnabled

If this value is set to false, only the TLD owner can mint new domains (for free). Otherwise anyone can mint new domains (but paid).

function buyingEnabled() public view returns(bool)


  • Boolean value (true or false)

# buyingDisabledForever*

If this value is set to false, the TLD owner can enable or disable domain buying at any time they want.

But if the value is set to true, buying domains is disabled forever, and can never be turned on again (in that case even minter and owner cannot mint new domains anymore).

function buyingDisabledForever() public view returns(bool)


  • Boolean value (true or false)

# metadataFrozen*

If this value is set to false, the TLD owner can change the metadata address at any time they want.

But if the value is set to true, the metadata address is frozen and can never be changed again.

function metadataFrozen() public view returns(bool)


  • Boolean value (true or false)

# totalSupply

The total number of minted domains.

function totalSupply() public view returns(uint256)


  • The total number of minted domains

# idCounter*

Counter for settings token IDs. In all Flexi/Soulbound TLD contracts, token IDs must start with 1, not 0 (mainly to enable the burn feature to properly work).

function idCounter() public view returns(uint256)


  • The next token ID number

# price

Returns the price to mint a new domain.

function price() public view returns(uint256)


  • Domain price in wei

# royalty

For every newly minted (paid) domain name a royalty payment is taken and sent to the Royalty Fee Receiver.

Only Royalty Fee Updater can change the royalty amount.

function royalty() public view returns(uint256)


  • Royalty fee in bips

# referral

A TLD can decide to enable referral fees for each domain mint.

By default the referral fee is set to 1000 bips (10%). If the owner does not want to allow referral fees, they need to set the referral fee to 0.

function royalty() public view returns(uint256)


  • Referral fee in bips

# nameMaxLength

Returns the maximum length of a domain name.

function nameMaxLength() public view returns(uint256)


  • The number of characters that a domain name can have at maximum

# domains

Returns the domain struct data that belong to the entered domain name.


  • Domain name
function domains(string) public view returns(Domain memory)


  • Domain struct data

# domainIdsNames

Returns the domain name that belongs to the entered token ID.


  • Token ID
function domainIdsNames(uint256) public view returns(string memory)


  • Domain name

# defaultNames

Returns the domain name that the holder defined as their "default" for that specific TLD.


  • User address
function defaultNames(address) public view returns(string memory)

This may be useful for social networks and games where user has multiple domain names under the same TLD.


  • Domain name

# getDomainHolder

Returns the domain holder's address. If no one owns the domain (yet), the returned address is the 0x0 address.


  • Domain name (without extension!)
function getDomainHolder(string memory) public view returns(address)

This is useful for checking whether a domain name has been already taken or not.


  • Domain holder's address

# getDomainData

Returns the domain holder's custom data. Note that this is different from the domains call which returns all domain struct data, not just the custom data string.


  • Domain name
function getDomainData(string memory) public view returns(string memory)


  • Domain holder's custom data as a stringified JSON object.

# tokenURI

This function calls the Metadata contract and gets back domain/NFT metadata (each domain is an ERC-721 NFT).


  • Token ID
function tokenURI(uint256) public view override returns (string memory)


  • Domain metadata as string (either base64-encoded or an URL)

# Write methods

# burn*

This function allows the domain owner to burn the domain. A burned domain can be minted again.


  • Domain name
function burn(string calldata _domainName) external

# editDefaultDomain

Through this function, a user can set one of their domains as their default domain (within the TLD that's defined by that contract, of course).


  • Domain name to be set as default
function editDefaultDomain(string calldata _domainName) external

Emitted events:

  • DefaultDomainChanged event

# editData

Function where user can edit custom data. Thread carefully, so that data is not accidentally deleted.


  • Domain name
  • Data (stringified JSON object)
function editData(string calldata _domainName, string calldata _data) external

Emitted events:

  • DataChanged event

# mint

Function to mint a new domain for a specific address (owner). Note that both TLD owner and minter can call this function even if public minting is disabled.


  • Domain name
  • Domain (future) owner
  • Referrer
function mint(
    string memory _domainName,
    address _domainHolder,
    address _referrer
  ) external payable nonReentrant returns(uint256)

Emitted events:

  • DomainCreated event

# Owner methods

# changeMetadataAddress*

Owner can change the address of the metadata contract (unless metadata address is frozen forever).

function changeMetadataAddress(address _metadataAddress) external onlyOwner


  • _metadataAddress: Metadata contract address

# changeMinter*

Owner can change the minter address. Minter can be either an EOA address, or a contract.

function changeMinter(address _minter) external onlyOwner


  • _minter: Minter address

# changeNameMaxLength

TLD owner can change max length of newly minted domain names. Does not work retroactively.


  • Maximum length
function changeNameMaxLength(uint256 _maxLength) external onlyOwner

# changePrice

TLD owner can change domain minting price.


  • Price in wei
function changePrice(uint256 _price) external onlyOwner

Emitted events:

  • TldPriceChanged event

# changeReferralFee

TLD owner can change the referral fee. The referral fee is in basis points (0 =< fee < 5000 bps).


  • Referral fee in bps
function changeReferralFee(uint256 _referral) external onlyOwner

Emitted events:

  • ReferralFeeChanged event

# disableBuyingForever*

TLD owner can stop domain minting forever. After this call, no one can mint new domains, not even owner or minter.

function disableBuyingForever() external onlyOwner

Emitted events:

  • MintingDisabledForever event

# freezeMetadata*

TLD owner can freeze the metadata forever. After this call, no one can change the metadata address anymore, not even the owner.

function freezeMetadata() external onlyOwner

# toggleBuyingDomains

TLD owner can start/stop public domain minting.

function toggleBuyingDomains() external onlyOwner

Emitted events:

  • DomainBuyingToggle event

# Royalty fee methods

# changeRoyalty

Royalty fee updater can change the royalty fee for minting a domain. Royalty fee is in basis points (bips).


  • Royalty fee in bps
function changeRoyalty(uint256 _royalty) external

Emitted events:

  • TldRoyaltyChanged event

# changeRoyaltyFeeReceiver*

The existing royalty fee receiver can change the royalty fee receiver address.


  • Address
function changeRoyaltyFeeReceiver(address _newReceiver) external

# changeRoyaltyFeeUpdater*

The existing royalty fee updater can change the royalty fee updater address.


  • Address
function changeRoyaltyFeeUpdater(address _newUpdater) external

*Methods marked with a star are specific for the Flexi/Soulbound contract. They are not obligatory for other contracts of that type.