Skip to content

Commit 45cd091

Browse files
committed
Update failure scope
1 parent 4e852dd commit 45cd091

1 file changed

Lines changed: 8 additions & 4 deletions

File tree

docs/vault-rebalancer.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ A Cadence resource that pokes a single Solidity function on an interval via [`Fl
88
## Assumptions
99

1010
- **EVM-side errors don't panic the scheduled tx.** `coa.call` surfaces revert/OOG as a non-successful `EVM.Result`, never as a Cadence panic. The failure model rests on this — without it, an EVM revert would abort the scheduled tx before it can self-reschedule, killing the chain.
11+
- **Off-chain tick liveness monitoring exists.** Several failure modes (scheduler unavailability, fee-vault depletion, COA depletion) are detectable only as missing events; operators must observe staleness and trigger recovery before LTV drifts to liquidation.
1112

1213
## What we require from the EVM contract
1314

1415
- **`rebalance()` is idempotent and self-guarding** — it inspects vault state and either acts or no-ops.
16+
- **`rebalance()` is permissionless** — callable by any EOA.
1517
- **The COA's EVM-side authority is narrow** — restricted to invoking `rebalance()` only (no admin or fund-movement entrypoints). This bounds the blast radius of an admin-compromised config rewrite to liveness impact.
1618

1719
## Design
@@ -23,9 +25,11 @@ One Cadence resource per EVM target, owned by an admin account. Stored at a dete
2325
- On each tick: `coa.call(...)` against the EVM contract; emit one event for the EVM-side outcome; self-reschedule via `FlowTransactionScheduler.schedule(...)` with the current config.
2426
- Self-rescheduling failures (insufficient FLOW, invalid capability) emit an event and halt the loop. The restart entry point is permissionless and idempotent — anyone can resume scheduling once the underlying condition is resolved.
2527

26-
**Scheduler priority.** The rebalancer uses Medium: it defers under slot contention but never rejects at submission. The tick interval is sized to absorb worst-case deferral.
28+
**Scheduler priority.** The rebalancer uses Medium: it defers under slot contention but never rejects at submission (see *Scheduler availability* below).
2729

28-
**Effort and gas sizing.** EVM `gasLimit` bounds the EVM call's worst-case cost; the Cadence `executionEffort` budget is sized to cover that bound plus the self-reschedule tail, with margin skewed larger on the Cadence side. EVM out-of-gas just fails the EVM call (surfaced as a non-successful `EVM.Result`) and the next tick retries, but Cadence out-of-effort would abort the entire scheduled tx atomically — including the EVM call — stopping the chain. Values are calibrated from measured worst-case `rebalance()` cost and must be re-tuned if governance changes Cadence execution-effort weights. The self-reschedule tail also includes an internal recursive slot search in `FlowTransactionScheduler.schedule()` (`calculateScheduledTimestamp`) under Medium-priority contention, which consumes `executionEffort` variably with the distance to the next free slot; margin must accommodate this on top of the EVM call's worst-case cost.
30+
**Effort and gas sizing.** EVM `gasLimit` bounds the EVM call's worst-case cost; the Cadence `executionEffort` budget is sized to cover that bound plus the self-reschedule tail, with margin skewed larger on the Cadence side. EVM out-of-gas just fails the EVM call (surfaced as a non-successful `EVM.Result`) and the next tick retries, but Cadence out-of-effort would abort the entire scheduled tx atomically — including the EVM call — stopping the chain. Values are calibrated from measured worst-case `rebalance()` cost and must be re-tuned if governance changes Cadence execution-effort weights. The self-reschedule tail also includes an internal slot search under Medium-priority contention whose effort consumption grows with distance to the next free slot; margin must accommodate this on top of the EVM call's worst-case cost (see *Scheduler availability*).
31+
32+
**Scheduler availability.** `FlowTransactionScheduler` is best-effort under slot contention — sustained contention can delay the next tick or temporarily halt the self-reschedule loop until manually restarted. Damage is bounded to liveness; the canonical recovery is direct (permissionless) `rebalance()` invocation on the EVM contract. Off-chain tick liveness monitoring is required.
2933

3034
## Failure modes and recovery
3135

@@ -36,8 +40,9 @@ One Cadence resource per EVM target, owned by an admin account. Stored at a dete
3640
| Fee vault depletion (Cadence scheduling fees) | Failure event with insufficient-FLOW reason; absence of subsequent scheduled events triggers alert | Admin tops up; signs tx to re-invoke self-reschedule |
3741
| COA FLOW depletion (EVM-side gas) | Tick events repeat with non-zero EVM error code; off-chain balance script catches drift earlier | Anyone can send FLOW to the COA (permissionless, from either Cadence or EVM) |
3842
| Cadence-side OOE (effort margin too tight) | Absence of expected events for the scheduled tx; rebalancer stops ticking | Admin re-invokes self-reschedule; retune effort margin if recurring |
43+
| Sustained scheduler unavailability | Tick events absent or persistently delayed; tick liveness monitor alerts | Anyone invokes `rebalance()` directly on the EVM contract; permissionless restart resumes ticking once contention clears |
3944

40-
No failure causes immediate solvency loss, but extended outage drifts LTV; under adverse price movement this can lead to Morpho liquidation.
45+
**Failure scope.** No single failure causes immediate solvency loss; failures degrade first to liveness. Prolonged outage can drift LTV and trigger Morpho liquidation under adverse prices, on a horizon set by market parameters and volatility — not by this design.
4146

4247
---
4348

@@ -47,6 +52,5 @@ Possible evolutions of this design — none load-bearing for v0.2:
4752

4853
- **Config hardening.** Multisig/timelock on the setter entitlement, or pushing more fields toward immutability; fully-immutable redeploy-only may require self-replenishing funding to be practical.
4954
- **Self-replenishing funding.** Fee top-ups sourced from a vault-level fee buffer or treasury sweep rather than admin out-of-band top-ups.
50-
- **Off-chain keeper backup.** A second caller of `rebalance()`.
5155

5256
If business logic ever moves to Cadence, the failure model fundamentally changes. The principle worth preserving: split scheduling and business logic into separate scheduled transactions, so a panic in the work doesn't take down the rescheduling loop.

0 commit comments

Comments
 (0)