From f61942e30a0171604ea43c11117cb9a8b79a6970 Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Wed, 17 Jun 2026 14:54:34 +0200 Subject: [PATCH 1/2] Primary name testcase that fails --- .../src/contracts/reverse_resolver.rs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/casper-name-contracts/src/contracts/reverse_resolver.rs b/casper-name-contracts/src/contracts/reverse_resolver.rs index 64bd7f9..f97f6a4 100644 --- a/casper-name-contracts/src/contracts/reverse_resolver.rs +++ b/casper-name-contracts/src/contracts/reverse_resolver.rs @@ -252,6 +252,37 @@ mod tests { assert_eq!(reverse_resolver.get_primary_name(&user), None); } + #[test] + fn test_set_primary_name_after_burn_and_remint_fails() { + let (mut ctx, mut reverse_resolver) = setup(); + let (admin, user) = (ctx.admin, ctx.alice); + + // Register the name and set it as the primary name. + ctx.with_name_registered(admin, user, TOKEN_TEST); + ctx.set_caller(user); + ctx.default_resolver + .set_resolution(DOMAIN_TEST.to_string(), Some(user)); + reverse_resolver.set_primary_name(DOMAIN_TEST.to_string()); + assert_eq!( + reverse_resolver.get_primary_name(&user), + Some(DOMAIN_TEST.to_string()) + ); + + // Burn the name. This invalidates its resolution. + ctx.admin_burn(vec![TOKEN_TEST]); + assert_eq!(reverse_resolver.get_primary_name(&user), None); + + // Mint a new token with the same name. It has a fresh resolver with no + // resolution set, so it cannot be set as the primary name. + ctx.with_name_registered(admin, user, TOKEN_TEST); + ctx.set_caller(user); + let result = reverse_resolver.try_set_primary_name(DOMAIN_TEST.to_string()); + assert_eq!( + result.unwrap_err(), + Error::ResolutionForPrimaryNameNotFound.into() + ); + } + fn setup() -> (TestContext, ReverseResolverHostRef) { let ctx = TestContext::install_and_setup(); let reverse_resolver = ReverseResolver::deploy( From 5c7e0da35fdacf460e04a61af8c71a4f0dac9ffd Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Wed, 17 Jun 2026 15:22:06 +0200 Subject: [PATCH 2/2] Testcase for reminting the same token and setting it as primary name --- .../src/contracts/reverse_resolver.rs | 61 ++++++++++++++++--- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/casper-name-contracts/src/contracts/reverse_resolver.rs b/casper-name-contracts/src/contracts/reverse_resolver.rs index f97f6a4..171b43b 100644 --- a/casper-name-contracts/src/contracts/reverse_resolver.rs +++ b/casper-name-contracts/src/contracts/reverse_resolver.rs @@ -73,6 +73,12 @@ impl ReverseResolver { fn existing_resolution(&self, name: &str) -> Option
{ let token_name = utils::extract_token_name(name)?; let token_id = self.token_id(token_name); + + // Check if the token ID is valid and if it has a resolver set. If not, return None. + if !self.name_token.is_token_valid(token_id) { + return None; + } + let resolver_address = self.name_token.resolver(token_id)?; ResolverContractRef::new(self.env(), resolver_address).resolve(name.to_owned()) } @@ -253,11 +259,11 @@ mod tests { } #[test] - fn test_set_primary_name_after_burn_and_remint_fails() { + fn test_set_new_primary_name_after_old_one_burned() { let (mut ctx, mut reverse_resolver) = setup(); let (admin, user) = (ctx.admin, ctx.alice); - // Register the name and set it as the primary name. + // Register a name and set it as the primary name. ctx.with_name_registered(admin, user, TOKEN_TEST); ctx.set_caller(user); ctx.default_resolver @@ -268,18 +274,57 @@ mod tests { Some(DOMAIN_TEST.to_string()) ); - // Burn the name. This invalidates its resolution. + // Burn the name backing the primary name. The primary name no longer + // resolves, so it reads as None instead of reverting. ctx.admin_burn(vec![TOKEN_TEST]); assert_eq!(reverse_resolver.get_primary_name(&user), None); - // Mint a new token with the same name. It has a fresh resolver with no - // resolution set, so it cannot be set as the primary name. + // Register a fresh name with a resolution and set it as the new primary + // name. This must succeed even though the previous primary was burned. + ctx.with_name_registered(admin, user, TOKEN_TEST2); + ctx.set_caller(user); + ctx.default_resolver + .set_resolution(DOMAIN_TEST2.to_string(), Some(user)); + reverse_resolver.set_primary_name(DOMAIN_TEST2.to_string()); + assert_eq!( + reverse_resolver.get_primary_name(&user), + Some(DOMAIN_TEST2.to_string()) + ); + } + + #[test] + fn test_set_primary_name_after_burn_and_remint() { + let (mut ctx, mut reverse_resolver) = setup(); + let (admin, user) = (ctx.admin, ctx.alice); + + // Register a name, set its resolution and make it the primary name. ctx.with_name_registered(admin, user, TOKEN_TEST); ctx.set_caller(user); - let result = reverse_resolver.try_set_primary_name(DOMAIN_TEST.to_string()); + ctx.default_resolver + .set_resolution(DOMAIN_TEST.to_string(), Some(user)); + reverse_resolver.set_primary_name(DOMAIN_TEST.to_string()); assert_eq!( - result.unwrap_err(), - Error::ResolutionForPrimaryNameNotFound.into() + reverse_resolver.get_primary_name(&user), + Some(DOMAIN_TEST.to_string()) + ); + + // Burn the name. The primary name no longer resolves. + ctx.admin_burn(vec![TOKEN_TEST]); + assert_eq!(reverse_resolver.get_primary_name(&user), None); + + // Re-mint the same name. The fresh token has no resolution yet, so the + // primary name still does not resolve. + ctx.with_name_registered(admin, user, TOKEN_TEST); + assert_eq!(reverse_resolver.get_primary_name(&user), None); + + // Set the resolution again and re-set the primary name. It succeeds. + ctx.set_caller(user); + ctx.default_resolver + .set_resolution(DOMAIN_TEST.to_string(), Some(user)); + reverse_resolver.set_primary_name(DOMAIN_TEST.to_string()); + assert_eq!( + reverse_resolver.get_primary_name(&user), + Some(DOMAIN_TEST.to_string()) ); }