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
Follow-up to audit L01 (#2623), now documented in NatSpec. This tracks the optional mitigation the audit recommends: an explicit dust-accounting or sweep mechanism so the orphaned rounding residue isn't permanent.
Background
pullTokens rounds lossy float→fixed-decimal conversions up (the contract never receives less than it credits); pushTokens rounds down (never sends more than it debits). This keeps the orderbook solvent — real token balance is always ≥ the sum of vault balances — but every lossy conversion leaves a sub-token-unit residue belonging to no vault. Over high volume / unusual decimals this accumulates as orphaned dust with no recovery path. Bounded by < 1 base unit per conversion; never an insolvency risk.
The hard part: there is no per-token total
Vault balances live in sVaultBalances[owner][token][vaultId] (nested mapping); there is no aggregate of total obligation per token, so the sweepable excess balanceOf(this, token) − Σ(vault balances) cannot be computed on-chain today (summing all vaults is infeasible). Any sweep needs a new per-token total-obligation accumulator maintained on every balance-changing path (deposit, withdraw, the pull/push above, the vault-0 settlements, clear) so that
is exact and can only ever release the provable excess above all vault obligations.
Design questions
Recipient: protocol treasury, a configured address, or a permissionless caller (sweep-as-incentive)?
Accumulator correctness (main risk): it must be updated in the fixed-decimal units actually transferred (the rounded amounts, not the float) on every path, so it matches balanceOf. Getting it wrong either traps more dust or — worse — lets a sweep dip into vault-backed balance.
Gas: one extra SSTORE per balance change vs. leaving dust orphaned.
Rebasing / fee-on-transfer tokens: balanceOf diverges from the accumulator independently of rounding — decide whether sweep covers those or only rounding dust.
Acceptance
A sweep/accounting path that can only ever move the provable un-vaulted excess.
Invariant test: after arbitrary deposit/withdraw/take/clear sequences, balanceOf ≥ sTotalObligation; sweeping releases exactly balanceOf − sTotalObligation and never breaks a subsequent legitimate withdraw.
Severity: Low (no insolvency; tiny amounts) — accounting/UX quality improvement.
it would actually be possible to both account this exactly and also be conservative
whenever tokens actually move and there is a precision loss the remainder could be tracked per sender/receiver as a future credit to realize the next time tokens move for that user
Activity
linear commentedon Jun 6, 2026
RAI-889
thedavidmeister commentedon Jun 10, 2026
it would actually be possible to both account this exactly and also be conservative
whenever tokens actually move and there is a precision loss the remainder could be tracked per sender/receiver as a future credit to realize the next time tokens move for that user
fix(raindex): clamp dust-credit pull to the vault obligation near the…
thedavidmeister commentedon Oct 27, 2026
Ruling: the dust credit ledger (#2702) lands in V8, not the V7 release.