feat(escrow): guard release/refund paths with a circuit breaker - #28
Merged
Meshmulla merged 1 commit intoAug 19, 2026
Merged
Conversation
What changed: - Added a circuit breaker to TimeLockedEscrowContract (escrow_contract/src/lib.rs), mirroring the pause/breaker style already used elsewhere in this repo (soroban's circuit_breaker.rs / submission_pause.rs). - release_escrow, batch_release, and refund_escrow now revert with the new EscrowError::CircuitBreakerTripped when the breaker is tripped, while read-only queries (get_escrow, get_challenge, get_dispute, get_accrued_fees, is_circuit_breaker_tripped, get_circuit_breaker_state) keep working. - trip_circuit_breaker/reset_circuit_breaker are restricted to the admin or an optional dedicated breaker guardian address, set via the new set_breaker_guardian admin-only entrypoint. - Added CircuitBreakerTripped/CircuitBreakerReset events and a CircuitBreakerState query type for auditability. - Added tests covering: release/refund blocked while tripped with read paths unaffected, reset restoring normal operation, and unauthorized callers being rejected for both trip and reset.
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a circuit breaker to the escrow contract's highest-value flows so an authorized guardian can halt fund movement instantly if an anomaly or exploit is detected, without blocking read-only queries.
closes #6
TimeLockedEscrowContract::release_escrow,batch_release, andrefund_escrownow check the breaker first and revert with the newEscrowError::CircuitBreakerTrippedwhen tripped.trip_circuit_breaker(caller, reason)/reset_circuit_breaker(caller)are gated to the contract admin or an optional dedicated breaker guardian address (set via the new admin-onlyset_breaker_guardian), mirroring the trip/reset access-control pattern used by the existingcircuit_breaker.rs/submission_pause.rsmodules elsewhere in this repo.get_escrow,get_challenge,get_dispute,get_accrued_fees, plus the newis_circuit_breaker_tripped/get_circuit_breaker_state) remain available regardless of breaker state.CircuitBreakerTripped/CircuitBreakerResetevents for auditability, and aCircuitBreakerStaterecord (reason, actor, timestamp) exposed viaget_circuit_breaker_state.set_emergency_pause/emergency_recoverare untouched).Testing / validation performed
All run locally against the workspace at HEAD of this branch:
cargo fmt --all -- --check— cleancargo clippy --all-targets --all-features -- -D warnings— clean (whole workspace)cargo build --release --target wasm32-unknown-unknown— succeedscargo test— all 18 test binaries pass (including the 3 new circuit-breaker tests), 0 failurescargo test --test escrow_contract_fuzz -p escrow-contract(FUZZ_ITERATIONS=200, as CI runs it) — passesNew tests added in
escrow_contract/tests/escrow_contract.test.rs:circuit_breaker_blocks_release_and_refund_when_tripped— tripped breaker rejectsrelease_escrow/refund_escrowwithCircuitBreakerTripped, whileget_escrow/get_circuit_breaker_statekeep working.circuit_breaker_reset_restores_release_and_refund— reset clears the trip and release proceeds normally.circuit_breaker_only_authorized_role_can_trip_or_reset— an unauthorized caller is rejected; a delegated guardian (set viaset_breaker_guardian) can trip/reset, a stranger cannot.Issue
#6