You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/STAKING.md
+52-4Lines changed: 52 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -79,11 +79,14 @@ First stake for an address (no existing committed stake with balance).
79
79
80
80
- Pulls `amount` of BZZ via `transferFrom`
81
81
- Requires `amount >= MIN_STAKE * 2**height`
82
+
- Reverts `AlreadyStaked()` if the address already has committed stake with balance
83
+
- Reverts `StakingHeightTooLarge()` if `height > MAX_STAKING_HEIGHT`
84
+
- Returns `effectiveFromRound` (same value as in `DepositCreated`)
82
85
- Emits `DepositCreated`
83
86
84
87
#### addTokens(amount)
85
88
86
-
Adds BZZ to an existing stake (queued).
89
+
Adds BZZ to an existing stake (queued). Reverts `InvalidAmount()` if `amount == 0`.
87
90
88
91
#### changeOverlay(setNonce)
89
92
@@ -115,10 +118,13 @@ When contract is **paused**: returns active balance plus amounts from queued `Cr
115
118
116
119
#### freezeDeposit(owner, time)
117
120
121
+
Requires `REDISTRIBUTOR_ROLE` and `whenNotPaused`.
122
+
118
123
- Extends `freezeUntilBlock` to at least `block.number + time` (monotonic — never shortened)
119
-
- Calls `_applyReadyUpdates` first: a **matured** withdrawal at queue head on an **unfrozen** account can pay out in the same tx before the new freeze applies
124
+
- If the account has no stake and no queue: records account-level freeze only and emits `AccountFreezeExtended`
125
+
- Otherwise calls `_applyReadyUpdates` first: a **matured** withdrawal at queue head on an **unfrozen** account can pay out in the same tx before the new freeze applies
120
126
- While frozen: `nodeEffectiveStake` is 0; further due withdrawals are blocked
121
-
- Emits `StakeFrozen` when committed stake exists; otherwise `AccountFreezeExtended` for account-only freeze
127
+
- Emits `StakeFrozen` when committed stake remains after applying ready updates
`Redistribution` reads `overlayOfAddress`, `heightOfAddress`, and `nodeEffectiveStake` (and lookahead variants for eligibility). Commit requires `_stake != 0`. Stake density in winner selection uses the stake recorded at commit time.
241
247
248
+
On claim, `Redistribution` calls `freezeDeposit` on non-revealers and on revealers whose hash/depth disagrees with the selected truth (subject to `penaltyRandomFactor`). Freeze duration scales with `ROUND_LENGTH` and truth depth.
249
+
242
250
Price oracle affects **postage** economics only, not stake effective balance.
-**Redistribution**: Commit/reveal game; holds `REDISTRIBUTOR_ROLE` for penalties
284
+
285
+
## Test coverage
286
+
287
+
Hardhat suite: **177 tests** (~33s). Staking-specific: **51 tests** in `test/Staking.test.ts`. Run `npx hardhat compile && npm test`.
288
+
289
+
Property tests: `src/echidna/EchidnaStakingHarness.sol` (see `echidna/README.md`).
290
+
291
+
### Unit tests (`test/Staking.test.ts`)
292
+
293
+
| Area | What is tested |
294
+
|------|----------------|
295
+
|**Deposit & queue**| Deploy wait params; `createDeposit` delay and activation; inactive until delay; top-up / height / overlay scheduling; lookahead previews; queue full; queue closed after `exit()`; redeposit after exit |
296
+
|**Validation**| Below minimum at deposit; `AlreadyStaked()`; `InvalidAmount()` on `addTokens(0)`; height decrease rejected; height increase below new minimum; `MAX_STAKING_HEIGHT`; invalid constructor wait config |
297
+
|**Withdraw & exit**| Partial withdraw + `applyUpdates` payout; full exit; invalid amounts; below-minimum remainder; withdraw/exit while active in current round (Redistribution commit) |
298
+
|**Freeze**| Effective stake = 0 while frozen; non-withdrawal updates still apply; queued withdrawal blocked until unfreeze; `FrozenWithdrawal()` atomic revert on `applyUpdates`; freeze monotonic; freeze survives exit and `migrateStake`; `OnlyRedistributor()`; `AccountFreezeExtended` on unstaked account; freeze while paused reverts |
299
+
|**Pause & migrate**| Staking blocked when paused; `migrateStake` only when paused (includes queued `CreateDeposit` / `AddTokens`); unpause restores flow |
0 commit comments