Summary
Once a user sets their vault secret, they are unable to update or reset it. Any subsequent call to set_secret
results in a RESOURCE_ALREADY_EXISTS (code 4004) error
, preventing the user from changing their secret and leaving no opportunity to update it if the secret has been compromised.
Description
User is unable to reset the vault secret. Calling the set_secret
again to set a new secret will result RESOURCE_ALREADY_EXISTS (code 4004) error
, causing the user has no second chance to set another new secret for their vault.
public entry fun set_secret(caller:&signer,secret:vector<u8>){
<@@>! let secret_vault = Vault{secret: string::utf8(secret)};
move_to(caller,secret_vault);
event::emit(SetNewSecret {});
}
Risk
Likelihood:
Impact:
Users are permanently unable to change or update their vault secret once it is set. If the secret is ever compromised, the user has no recovery path, potentially exposing them to long-term security risks.
Proof of Concept
Add the following test in secret_vault.move
:
#[test(owner = @0xcc)]
fun test_owner_unable_to_update_secret(owner: &signer) acquires Vault{
use aptos_framework::account;
account::create_account_for_test(signer::address_of(owner));
let secret = b"chocolate";
set_secret(owner, secret);
let new_secret = b"muffin";
set_secret(owner, new_secret);
let owner_add = signer::address_of(owner);
let owner_vault = borrow_global<Vault>(owner_add);
assert!(owner_vault.secret == string::utf8(new_secret), 2);
}}
In terminal run aptos move test -f test_owner_unable_to_update_secret
:
$ aptos move test -f test_owner_unable_to_update_secret [17:51:55]
...
Running Move unit tests
[ FAIL ] 0x234::vault::test_owner_unable_to_update_secret
Test failures:
Failures in 0x234::vault:
┌── test_owner_unable_to_update_secret ──────
│ error[E11001]: test failure
│ ┌─ /Users/soupy/Documents/codehawks/first-flight/2025-07-secret-vault/sources/secret_vault.move:25:6
│ │
│ 22 │ public entry fun set_secret(caller:&signer,secret:vector<u8>){
│ │ ---------- In this function in 0x234::vault
│ ·
│ 25 │ move_to(caller,secret_vault);
│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Test was not expected to error, but it gave a RESOURCE_ALREADY_EXISTS (code 4004) error with error message: "Failed to move resource into 0000000000000000000000000000000000000000000000000000000000000123". Error originating in the module 0000000000000000000000000000000000000000000000000000000000000234::vault rooted here
│
│
│ stack trace
│ vault::test_owner_unable_to_update_secret(/Users/soupy/Documents/codehawks/first-flight/2025-07-secret-vault/sources/secret_vault.move:53)
│
└──────────────────
Test result: FAILED. Total tests: 1; passed: 0; failed: 1
{
"Error": "Move unit tests failed"
}
FAIL
The test failed indicating that the owner can't update their secret via set_secret
function after the initial set.
Recommended Mitigation
To amend the set_secret
function so it can cater for the user's need to update secret if they need to
public entry fun set_secret(caller:&signer,secret:vector<u8>) acquires Vault{
let caller_add = signer::address_of(caller);
assert!(caller_add == @owner, NOT_OWNER);
if (exists<Vault>(caller_add)) {
let vault = borrow_global_mut<Vault>(caller_add);
vault.secret = secret;
} else {
move_to(caller, Vault{secret: secret});
};
event::emit(SetNewSecret{account: caller_add});
}