Repository navigation
docs: circle failure handling spec - #188
franrolotti wants to merge 2 commits into
Conversation
Replaces the single terminal decommission path with a graded response (pause -> cure -> eject -> halt) backed by collateral, and makes all value transfers pull-based. Decided: ejection is permissionless once the owner ends the grace; the pause is the grace window and has no timer. Bond sizing and repeat default handling are left open.
BREAD is ERC20VotesUpgradeable with no blacklist, pause, or transfer hooks, so a recipient cannot permanently revert a push transfer. Drop the fund-locking claim and the reverting-recipient claim, which was wrong for any plain ERC20. Phase 1 now rests on gas and cost fairness: BREAD's auto-delegating transfer override makes each transfer several times the cost of a vanilla ERC20, and push means one member funds everyone's refund. Token-restriction risk is retained explicitly as defense in depth. Adds a token assumptions section and a fork-based gas benchmark against real BREAD, since MockERC20 understates transfer cost.
|
I think that we should be looking at the "social layer" too (not only at "mathematical" solutions) A key insight from my conversations with Jean Claude (Winkomun & Paddle) is that he observed how
I got a similar comment after demoing Stacks to RuDee from https://www.equitypicture.com/. They asked: would it be possible to pause the Stacks (vs decommissioning)? I personally also feel the same way regarding our failed Stacks: how can we resume /finish it? Aligned with https://discord.com/channels/649359982424358952/1418564434367873024/1544765137385160796 |
|
I mentioned "CRC as collateral" as a joke, but it can be an interesting avenues to explore
|
Spec only — no executable changes. Adds
docs/circle-failure-handling.md.Why
Today a missed deposit has exactly one outcome: any single member calls
decommission, the circle dies permanently, and the contract pushes every unclaimed round's deposits back in anO(n²)loop. Three problems with that:members × roundsindividual transfers in one transaction. BREAD isERC20VotesUpgradeableand overridestransfer/transferFromto auto-delegate on receipt, so each transfer pays for voting-checkpoint writes on both sides, an external self-call tothis.delegates(recipient), and a full_delegatethe first time an address receives BREAD — several times a vanilla ERC20 transfer. The spec asks for a fork-based gas benchmark to pin down the largest circle the current path can actually wind down.decommissionfunds the entire refund distribution out of their own pocket. Pull-based settlement makes each member pay for their own exit. Holds regardless of any gas limit.On token risk: the usual argument for pull payments — a recipient that can permanently revert a push and brick the loop for everyone — does not apply to this deployment. BREAD has no blacklist, no pause, and no transfer hooks. The spec says so explicitly and does not lean on it. It is retained only as defense in depth, since
setTokenAllowedexists and this is an upgradeable long-lived contract.What the spec proposes
A graded response — pause → cure → eject → halt — backed by collateral, with all value transfers pull-based. Four phases, shipped in order:
halt(O(1)) + per-membersettle. Independent of everything else; ships alone.block.timestamp. ForcesAutomaticSavingCirclesto stop duplicating the round math and call shared views instead.start, forfeited on ejection.circleMembers(indices are payout rounds), with the seized bond backfilling the stalled round first.Phases 1–3 are each independently shippable; phase 4 is optional and can be dropped without stranding the others.
Two design consequences worth reviewer attention:
depositAmount × circleMembers.lengthbreaks once a bond can backfill a shortfall or a member can be ejected mid-rotation. Replaced byroundTotal[id][r]— a round pays out exactly what it collected.haltfor as long as the circle is paused, which is what makes an unbounded owner-controlled grace safe — a passive owner can stall the circle but can never trap the funds. No weaker than today, where any single member candecommissionunilaterally.What this PR needs from reviewers
The point of merging this is to close §8. Two questions block later phases and can't be answered by one person:
depositAmount(covers one missed round, cheap) vs position-scaleddepositAmount × (n − 1 − memberIndex)(full collateralization, closes the "claim early then default" hole, expensive in locked capital). Blocks phase 3.Also open: repeat-default handling (§8.2), bond top-up after backfill (§8.3), an absent-owner backstop so a stalled circle can continue rather than only die (§8.4), and whether
haltduring a pause should need a quorum (§8.5).Phase 1 depends on none of these and can start in parallel with this review.