Secret Vault on Aptos

First Flight #46
Beginner FriendlyWallet
100 EXP
View results
Submission Details
Severity: low
Valid

Resource Already Exists — Users Cannot Update Secret

Resource Already Exists — Users Cannot Update Secret

Description

  • Normally, a secret vault function should either:

    • create a new vault if none exists, or

    • update the existing vault if one already exists.

  • In the current implementation:

public entry fun set_secret(caller: &signer, secret: vector<u8>) {
let secret_vault = Vault { secret: string::utf8(secret) };
move_to(caller, secret_vault); // ❌ will fail if resource already exists
event::emit(SetNewSecret {});
}

  • The call to move_to will abort automatically with a RESOURCE_ALREADY_EXISTS error if the caller already has a Vault.

  • Since no prior check is performed, users cannot update their secret once it’s set — the contract locks them out permanently after the first use.

Risk

Likelihood:

  • Reason 1: This occurs every time a user with an existing vault calls set_secret.

  • Reason 2: Since most users will eventually want to update their secret, this bug is guaranteed to surface.

Impact:

  • Impact 1: Users are unable to update their stored secret after the first transaction (denial of service for legitimate use).

  • Impact 2: Creates poor UX and may force redeployment or contract migration, undermining trust in the application.

Proof of Concept

// User Alice sets a secret the first time
set_secret(&signer_alice, b"my first secret"); // ✅ success
// Alice tries to update her secret
set_secret(&signer_alice, b"new secret");
// ❌ aborts: RESOURCE_ALREADY_EXISTS (Vault already exists at Alice’s address)

Recommended Mitigation

public entry fun set_secret(caller: &signer, secret: vector<u8>) {
- let secret_vault = Vault{secret: string::utf8(secret)};
- move_to(caller, secret_vault);
+ // Remove old vault if exists, then replace
+ if (exists<Vault>(signer::address_of(caller))) {
+ let _old = move_from<Vault>(signer::address_of(caller));
+ };
+ let secret_vault = Vault{ secret: string::utf8(secret) };
+ move_to(caller, secret_vault);
event::emit(SetNewSecret {});
}
Updates

Lead Judging Commences

bube Lead Judge 15 days ago
Submission Judgement Published
Validated
Assigned finding tags:

The `secret` can not be updated

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.