The set_secret function is intended to store a secret for a user by creating a Vault resource.
The function does not check if a Vault resource already exists at the caller's address. When a user calls set_secret more than once, the existing Vault is replaced, and the original secret is permanently destroyed.
Likelihood:
Reason 1: A user calls set_secret multiple times, accidentally overwriting their secret.
The function's behavior is unintuitive, as users typically expect a "set" function to either update or fail, not silently destroy and replace.
Impact:
Permanent loss of a user's secret data.
Failure of the contract's core promise, which is to securely store a secret.
The following test demonstrates that a user can overwrite their existing Vault.
A user calls set_secret for the first time with an initial secret.
The test verifies the secret is stored correctly.
The user then calls set_secret a second time with a new secret.
The test confirms that the new secret has replaced the original one, proving the first Vault and its contents were destroyed and are now unrecoverable.
The recommended fix is to add a check to ensure a Vault does not already exist for the caller before creating a new one.
This is achieved by adding assert!(!exists<Vault>(signer::address_of(caller)), 2); at the beginning of the set_secret function. This line checks if a Vault resource is already stored under the caller's account. If one exists, the transaction will revert with an error, preventing the overwrite. This change enforces a "create-only" behavior, protecting existing secrets from being lost. To allow for updates, a separate, explicit function should be created.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.