# Loss of funds due to address mappings are not cleaned up after domain expiry

Initia name service leaves stale name_to_addr/addr_to_name mappings after domain expiry, so re-registered domains resolve to the previous owner's address, misdirecting transfers.

- Payout: Contest reward
- Severity: medium
- Program: Initia
- Credited: d4r3d3v1l
- Disclosed: 2025-04-10
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2025-01-initia-move#m-01
- Library page: https://bugbountylibrary.com/r/c4%3A2025-01-initia-move%3AM-01
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:regression technique:source-review vuln:accounting-error vuln:business-logic

**Target:** Move name service module (register_domain/set_name view functions)
**Root cause:** register_domain only clears name_to_token on re-registration of an expired domain, leaving name_to_addr and addr_to_name pointing at the previous owner; the is_expired guard in getters is bypassed once the domain is re-registered with a fresh expiry.
**Steps:**
1. User1 registers `abc` and calls `set_name`, setting name_to_addr[abc]=User1 and addr_to_name[User1]=abc
2. Advance block time past expiry + grace period
3. User2 calls `register_domain(abc)` without calling `set_name`
4. Call `get_address_from_name(abc)` — returns User1's address, not None or User2
5. Send tokens to `abc.init`; funds route to User1
**How found:** Code reading of register_domain vs set_name cleanup logic; noticed only name_to_token was removed on re-registration, then wrote an end-to-end Move test asserting stale getter results and verified on testnet.
**Exploitation:** A sender who was given the domain name by the original owner keeps resolving to the old owner's address after expiry and re-registration, so transfers intended for the new owner land with the previous owner.
**Insight:** When a registry has separate ownership and resolution mappings, check every mutation path (re-register, transfer, expire) for which mappings each one clears — expiry cleanup in one function but not the re-registration path leaves resolvers stale.
