Secret Vault on Aptos

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

Secret cannot be updated

Root

The flow in the set_secret prevent any update on the secret.

Impact

Secret can only be set Once, meaning that new contract need to be deployed in scenario of wanting to have a different Secret.

Description

The contract main feature for Owner is to have its' Secret. However, the logic in the set_secret only allow Owner to set the secret once with no option to update it, making the need of a new smart contract to be deployed in order to having a different Secret value.

public entry fun set_secret(caller:&signer,secret:vector<u8>){
// Setting the Secret Value of the Vault
let secret_vault = Vault{secret: string::utf8(secret)};
// Putting the Ownership to caller (Owner)
move_to(caller,secret_vault);
// Emit the SetNewSecret Event
event::emit(SetNewSecret {});
}

Risk

Likelihood:

  • Owner can only set the Secret once and can not update it.

Impact:

  • A New contract is needed whenever the Owner wants another Secret Value.

Proof of Concept

Add this code to secret_vault.move

#[test(owner = @0xcc)]
fun test_inputing_secret(owner: &signer) {
use aptos_framework::account;
// Set up test environment
account::create_account_for_test(signer::address_of(owner));
// Set the secret twice
let secret_1 = b"First Secret";
let secret_2 = b"Second Secret";
set_secret(owner, secret_1);
set_secret(owner, secret_2);
}

Running the test will have this result

$ aptos move test 1
INCLUDING DEPENDENCY AptosFramework
INCLUDING DEPENDENCY AptosStdlib
INCLUDING DEPENDENCY MoveStdlib
BUILDING aptos-secret-vault
Running Move unit tests
[ FAIL ] 0x234::vault::test_inputing_secret
Test failures:
Failures in 0x234::vault:
┌── test_inputing_secret ──────
│ error[E11001]: test failure
│ ┌─ /Users/sanada/Documents/blockchain/2025-07-secret-vault/sources/secret_vault.move:188:5
│ │
184 │ public entry fun set_secret(caller:&signer,secret:vector<u8>){
│ │ ---------- In this function in 0x234::vault
│ ·
188move_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 00000000000000000000000000000000000000000000000000000000000000cc". Error originating in the module 0000000000000000000000000000000000000000000000000000000000000234::vault rooted here
│ stack trace
│ vault::test_inputing_secret(/Users/sanada/Documents/blockchain/2025-07-secret-vault/sources/secret_vault.move:239)
└──────────────────
Test result: FAILED. Total tests: 1; passed: 0; failed: 1
{
"Error": "Move unit tests failed"
}

Recommended Mitigation

asdasd

To enhance the contract and preventing unecessary cost of deploying another contract, upsert (update + insert) can be implemented for the set_secret function.

public entry fun set_secret(caller:&signer,secret:vector<u8>) acquires Vault{
- let secret_vault = Vault{secret: string::utf8(secret)};
- move_to(caller,secret_vault);
+ let addr = signer::address_of(caller);
+ // If vault exist
+ if (exists<Vault>(addr)) {
+ // Update existing Vault
+ let vault = borrow_global_mut<Vault>(addr);
+ vault.secret = string::utf8(secret);
+ } else { // If vault not exist, create one
+ // Create a new Vault
+ let vault = Vault { secret: string::utf8(secret) };
+ move_to(caller, vault);
+ };
event::emit(SetNewSecret {});
}

Below is the test created to check whether we can continuously update the Secret

#[test(owner = @0xcc)]
fun test_inputing_secret_after_patching(owner: &signer) acquires Vault {
use aptos_framework::account;
// Set up test environment
account::create_account_for_test(signer::address_of(owner));
// Set the first secret & check
let secret_1 = b"First Secret";
set_secret(owner, secret_1);
let secret_1_set = get_secret(signer::address_of(owner));
debug::print(&secret_1_set);
// Set the second secret & check
let secret_2 = b"Second Secret";
set_secret(owner, secret_2);
let secret_2_set = get_secret(signer::address_of(owner));
debug::print(&secret_2_set);
// Set the third secret & check
let secret_3 = b"Last Secret";
set_secret(owner, secret_3);
let secret_3_set = get_secret(signer::address_of(owner));
debug::print(&secret_3_set);
}

Running the test above will give the result below

$ aptos move test
INCLUDING DEPENDENCY AptosFramework
INCLUDING DEPENDENCY AptosStdlib
INCLUDING DEPENDENCY MoveStdlib
BUILDING aptos-secret-vault
Running Move unit tests
[debug] "First Secret"
[debug] "Second Secret"
[debug] "Last Secret"
[ PASS ] 0x234::vault::test_inputing_secret_after_patching
Test result: OK. Total tests: 1; passed: 1; failed: 0
{
"Result": "Success"
}
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.