# NFT Token ID contains forbidden character by design which prevents any domain from being issued at all

Initia usernames module builds NFT token IDs as domain:timestamp, but the stdlib nft module forbids ':', so every register_domain reverts, permanently blocking all domain registration.

- Payout: Contest reward
- Severity: high
- Program: Initia
- Credited: 0xluk3
- Disclosed: 2025-04-10
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2025-01-initia-move#h-02
- Library page: https://bugbountylibrary.com/r/c4%3A2025-01-initia-move%3AH-02
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:high tech:solidity technique:regression technique:source-review vuln:dos

**Target:** Move usernames/name-service module and initia_nft stdlib
**Root cause:** register_domain appends ':timestamp' to the domain to form the NFT token_id, but nft::assert_token_id rejects any token_id containing ':', so mint_nft_object aborts.
**Steps:**
1. Call `register_domain(&user, string::utf8(b"abc"), 1000)` after initialize.
2. register_domain builds name `abc.init:1000` and passes it as token_id to `mint_nft_object`.
3. initia_nft::mint_internal -> nft::create -> `assert_token_id` fails because `string::index_of(token_id, ":") != len`, aborting with EINVALID_TOKEN_ID (65545).
4. Confirm by changing separator to `-` in line 359; test then passes and mints `abc.init-1000`.
**How found:** Ran the module's own end_to_end unit test, saw it abort in nft::assert_token_id, added a debug print of the constructed name, and traced the call stack from register_domain through mint_nft_object to the ':' check.
**Insight:** When a module composes an identifier from user input plus a delimiter, check the downstream mint/registry validator's character rules; here the stdlib forbade ':' that the caller itself injected.
