Skip to content

Deregister the guardian from AllGuardians and the slot index in resign_guardian — a resigned guardian can never be re-added #303

Description

@N-thnI

Description

Make resign_guardian clean up guardian membership the same way remove_guardian does.

Problem Statement

resign_guardian clears only the membership flag (src/contracts/vault_ops.rs:134-135):

let g_key = DataKey::Guardian(guardian.clone());
env.storage().instance().remove(&g_key);

It never removes the address from DataKey::AllGuardians, nor from the GuardianIndexAt/GuardianIndexOf/GuardianIndexCount slot index — all of which guardian::remove_guardian (src/guardian.rs:62-133) cleans up properly.

Verified against current main: after a guardian resigns, is_guardian is false, but get_snapshot_meta().guardian_count is still 1, get_snapshot().guardians still holds 1 entry, and add_guardian(&admin, &g) returns Err(DuplicateGuardian) — because add_guardian checks all_guardians.contains(guardian) at src/guardian.rs:25, which still holds.

So a guardian who resigns is permanently locked out of the protocol, and the leaked slot inflates guardian_count and get_guardians_page indefinitely.

Proposed Changes

  • Have resign_guardian call guardian::remove_guardian (or a shared deregister_guardian helper) instead of the bare remove(&g_key), so AllGuardians and the slot index are compacted identically
  • Keep the token-refund/timelock logic after deregistration, and preserve the existing NotGuardian early return
  • Add a regression test asserting a resigned address can be re-added

Technical Implementation Scaffolding

  • Target Repository: vero-core-contracts
  • Target Path: src/contracts/vault_ops.rs, src/guardian.rs
  • Branch Naming: fix/issue--resign-guardian-deregister
  • Authority Context: Correctness — guardian membership; locks users out permanently

Acceptance Criteria

  • After resign_guardian, get_snapshot_meta().guardian_count decreases by 1 and the address no longer appears in get_guardians_page(0, 50)
  • add_guardian(admin, g) succeeds after g resigned, and is_guardian(g) is then true
  • resign_guardian and remove_guardian leave byte-identical guardian-index state for the same address

Definition of Done

  • Reviewed by lead maintainer
  • Pull request merged via verified status check

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardThird CampaignCampaign: Third Campaign

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions