feat(security): C-2 — oracle circuit-breaker pause fails window closed on vFDUSD collapse #22
Labels
No labels
enhancement
governance
QA
testing
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
code/ust1-window#22
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Implement only the oracle-level pause / circuit-breaker portion of C-2 from
audits/INTERNAL_KIMIK3_1786162831.md: when a vFDUSD economic collapse (or detected price decrease vs the monotonic on-chain rate) is recognized, the oracle path can halt swaps immediately, instead of waiting for window staleness (~6h) while the stale high rate enables a slow treasury drain.Audit ref: C-2 (recommendation #1 only)
Explicitly out of scope for this issue: emergency rate reset / monotonic bypass; off-chain spot-vs-
exchangeRateStoreddivergence alerter; docs-only risk disclosures (unless needed for the pause UX).Current codebase
contracts/ust1-oracleExecuteMsg::SetPausedUpdateRatewhencfg.pausedStateResponserate/last_update_sec/ day fields — does not surface pausedcontracts/ust1-window/src/contract.rsensure_oracle_freshlast_update_secvsmax_oracle_age_sec; ignores oracle pausedust1-windowSetPausedust1-commonoracle_policy.rsMonotonicViolation) — by designoracle-serviceGap vs C-2 #1: Pausing the oracle today only stops further
UpdateRates. The window keeps minting/redeeming at the last (pre-collapse) rate until the staleness budget expires — exactly the window an attacker needs for the ~rolling-limit/day drain.Why this is needed
Constraints / guardrails
OraclePaused).Config/Statestill readable).Relevant files
contracts/ust1-oracle/src/{msg,contract,state}.rs— pause semantics / query surfacecontracts/ust1-oracle/src/multitest.rs— pause ACL + interaction testscontracts/ust1-window/src/contract.rs—query_oracle_state/ensure_oracle_fresh(or successor)contracts/ust1-window/src/{error,msg}.rs— error + any query aggregationcontracts/ust1-window/src/multitest.rs— deposit/withdraw blocked when oracle pausedoracle-service/src/main.rs(optional) — call pause trigger if in scopedocs/DEPLOYMENT.md— emergency pause runbookRecommended direction
pausedin a query the window already uses, or have window queryConfig/ a combined health query).max_oracle_age_sec).SetPausedas the authority for pause/unpause; optionally add a narrow operatorTripCircuitBreaker/SetPausedif product wants oracle-bot reaction to detected decrease — unpause remains governance-only.action=set_paused,paused=true) already present; ensure window error is operator-visible.Acceptance criteria
paused=true, window deposit and withdraw both revert without waiting for staleness.paused=falseand rate fresh, swaps behave as today.UpdateRateremains blocked while paused (existing behavior preserved).Test plan (all paths)
OracleStale(unchanged).Test plan (attack / hack / abuse vectors)
Verification criteria
last_update_sec.mentioned in commit f312188dd1f8a7c61dc32de5647a58f3e041293e
mentioned in merge request !39
mentioned in merge request !40
MR !40 verification (C-2 #1 / #22)
Verdict: PASS_WITH_NOTES — merging with deploy-order caveat.
AC (in-scope)
Tests (local)
cargo test -p ust1-oracle --lib— 9/9cargo test -p ust1-window --lib— 17/17cargo test -p ust1-integration-tests --lib— 8/8Problems / follow-ups
State.pausedfield; window upgrade against old oracle will fail deserialization.secret_detection.mentioned in commit
c1d19c7329mentioned in commit
deb4453da1mentioned in issue #26
mentioned in issue #27
marked as related to #27
mentioned in issue #28
marked as related to #28
mentioned in commit
695e577065mentioned in merge request !45