Labels: type: bug, type: api-design, difficulty: intermediate, area: reward-engine
Why this matters now
The README documents set_oracle as "Replace the entire oracle roster with a single oracle" and also lists it under the function table for reward-engine twice (both as an admin function and under the oracle management section). In the contract, set_oracle (verification.rs line ~149) overwrites Oracles with a single-element Vec, silently dropping every oracle added via add_oracle. A multi-oracle operator who calls set_oracle to rotate one oracle accidentally removes all others with no warning and no event. This is a liveness risk — if set_oracle is called by mistake in a production multi-oracle setup, all but one oracle lose their ability to submit proofs with no on-chain record of the removal.
Key Challenges
set_oracle emits no OracleRemovedEvent for the oracles it silently drops; this is inconsistent with remove_oracle which always emits one.
- Two competing mental models exist:
set_oracle (replace roster) vs add_oracle/remove_oracle (roster management). One must be canonical. The recommended fix is to either: (a) remove set_oracle and require callers to use add_oracle/remove_oracle, or (b) make set_oracle emit OracleRemovedEvent for every evicted oracle and OracleAddedEvent for the new one.
- The README lists
set_oracle twice — the docs must be corrected to match whichever model is chosen.
Acceptance Criteria
Relevant files / functions
| File |
Symbol |
contracts/reward-engine/src/verification.rs |
set_oracle, add_oracle, remove_oracle |
Out of scope
- Multi-oracle consensus logic
- Changes to
add_oracle / remove_oracle behaviour
Labels:
type: bug,type: api-design,difficulty: intermediate,area: reward-engineWhy this matters now
The README documents
set_oracleas "Replace the entire oracle roster with a single oracle" and also lists it under the function table forreward-enginetwice (both as an admin function and under the oracle management section). In the contract,set_oracle(verification.rsline ~149) overwritesOracleswith a single-element Vec, silently dropping every oracle added viaadd_oracle. A multi-oracle operator who callsset_oracleto rotate one oracle accidentally removes all others with no warning and no event. This is a liveness risk — ifset_oracleis called by mistake in a production multi-oracle setup, all but one oracle lose their ability to submit proofs with no on-chain record of the removal.Key Challenges
set_oracleemits noOracleRemovedEventfor the oracles it silently drops; this is inconsistent withremove_oraclewhich always emits one.set_oracle(replace roster) vsadd_oracle/remove_oracle(roster management). One must be canonical. The recommended fix is to either: (a) removeset_oracleand require callers to useadd_oracle/remove_oracle, or (b) makeset_oracleemitOracleRemovedEventfor every evicted oracle andOracleAddedEventfor the new one.set_oracletwice — the docs must be corrected to match whichever model is chosen.Acceptance Criteria
set_oracleis removed (breaking) and the docs updated, ORset_oracleemitsOracleRemovedEventfor every oracle it evicts.test_set_oracle_evicts_existing_oracles_with_eventsasserts the eviction events fire.set_oracleentry).Relevant files / functions
contracts/reward-engine/src/verification.rsset_oracle,add_oracle,remove_oracleOut of scope
add_oracle/remove_oraclebehaviour