Synchronisation lifecycle
ImplementedIn sync, pending, awaiting keeper, paused, unpriceable — what each state means and how it clears.
What each state means, and how it clears.
#States
stateDiagram-v2 [*] --> InSync InSync --> Pending: source balance moves Pending --> AwaitingKeeper: still un-actioned AwaitingKeeper --> InSync: sync executes Pending --> InSync: sync executes Pending --> Skipped: sync evaluates and declines Skipped --> InSync: snapshot accepted anyway AwaitingKeeper --> Expired: pending expiry elapses Expired --> InSync: snapshot accepted without trading
| State | Condition | Clears when |
|---|---|---|
| In sync | Live source balance equals the accepted snapshot for every tracked asset | — |
| Pending | Source balance differs from the snapshot; first seen recently | A keeper syncs, or expiry elapses |
| Awaiting keeper | An actionable divergence nobody has called sync for | A keeper syncs |
| Deposits paused | Operator paused deposits | Operator unpauses |
| Execution paused | Operator paused execution | Operator unpauses |
| NAV unavailable | A held position cannot be priced | Pricing recovers |
Withdrawal in kind is unaffected by every state in this table.
#Pending expiry
A divergence that stays un-actioned past the pending expiry stops being treated as actionable, and the snapshot is accepted without a trade.
This exists because the alternative is a vault that spends forever trying to mirror a trade that has become stale — chasing a price that has moved on is worse than acknowledging the miss.
Note. An early implementation had a bug here worth knowing about: a price failure returned early and marked the state pending, bypassing the expiry lifecycle entirely, so the state could never expire. Price failures now route through the same skip path as every other refusal.
#Elapsed time uses timestamps
Robinhood Chain is an Arbitrum Orbit chain and block.number is an estimate of the L1 block rather than a local counter. Every elapsed-time comparison in the protocol — pending expiry, epoch boundaries, price staleness — uses block.timestamp.
#Snapshots are accepted after the trade
A snapshot is only accepted once the corresponding action succeeds. If a swap reverts, the snapshot is unchanged and the work remains outstanding — so a partially-completed sync leaves the vault in a consistent state rather than believing it has mirrored something it has not.