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
Summary
contracts/oracle-verifier/src/lib.rsmaintains aVec<Address>atStorageKey::OracleListin instance storage.add_oracleappends to this list (lines 99–105).remove_oraclesetsentry.active = falsein the oracle's persistent entry but never removes the address fromOracleList(lines 109–119).Code
Impact
get_oracles()returns deactivated oracle addresses — callers get a misleading view of the active oracle setget_oraclesto enumerate active participants will see ghost addressesFix
In
remove_oracle, filter the deactivated address out ofOracleList:Severity: Medium