Skip to content

[oracle-verifier] OracleList in instance storage retains soft-deleted oracle addresses — grows without bound #135

Description

@nonsobethel0-dev

Summary

contracts/oracle-verifier/src/lib.rs maintains a Vec<Address> at StorageKey::OracleList in instance storage. add_oracle appends to this list (lines 99–105). remove_oracle sets entry.active = false in the oracle's persistent entry but never removes the address from OracleList (lines 109–119).

Code

// add_oracle (lines 99-105): appends
let mut list: Vec<Address> = env.storage().instance()
    .get(&StorageKey::OracleList).unwrap_or_else(|| Vec::new(&env));
list.push_back(oracle);
env.storage().instance().set(&StorageKey::OracleList, &list);

// remove_oracle (lines 109-119): does NOT touch OracleList
pub fn remove_oracle(env: Env, admin: Address, oracle: Address, data_type: Symbol) {
    Self::require_admin(&env, &admin);
    let key = StorageKey::Oracle(data_type.clone(), oracle.clone());
    let mut entry: OracleEntry = env.storage().persistent().get(&key)...;
    entry.active = false;
    env.storage().persistent().set(&key, &entry);
    // ← OracleList unchanged
}

Impact

  • get_oracles() returns deactivated oracle addresses — callers get a misleading view of the active oracle set
  • Instance storage has a per-entry byte cap; with many oracle rotations the list will overflow
  • Any off-chain monitoring or governance tooling that calls get_oracles to enumerate active participants will see ghost addresses

Fix

In remove_oracle, filter the deactivated address out of OracleList:

let list: Vec<Address> = env.storage().instance().get(&StorageKey::OracleList)...;
let mut pruned: Vec<Address> = Vec::new(&env);
for addr in list.iter() {
    if addr != oracle { pruned.push_back(addr); }
}
env.storage().instance().set(&StorageKey::OracleList, &pruned);

Severity: Medium

Metadata

Metadata

Assignees

Labels

Stellar WaveIssues in the Stellar wave programbugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions