Skip to content

Add fork tests for deposit capacity attack scenarios#299

Open
mts1715 wants to merge 1 commit intomainfrom
taras/283-deposit-capacity-attacks
Open

Add fork tests for deposit capacity attack scenarios#299
mts1715 wants to merge 1 commit intomainfrom
taras/283-deposit-capacity-attacks

Conversation

@mts1715
Copy link
Copy Markdown
Contributor

@mts1715 mts1715 commented Mar 30, 2026

Closes: #283

Summary

Five adversarial scenarios covering the deposit capacity system:

  • Griefing: 10 positions × 1 FLOW minimum exhaust pool capacity (scaled from spec's 1000 × 1 FLOW; mechanically identical, ~50× faster)
  • Front-running: attacker consumes full capacity ahead of victim; victim's deposit is fully queued with zero collateral credit
  • Sybil: two accounts each deposit up to the per-position cap, collectively exceeding the limit enforced on a single account
  • Regeneration monopolization: attacker captures two consecutive regeneration cycles, accumulating 200 FLOW from a 100-token-cap pool
  • Queued deposit exploitation: queued funds yield no collateral credit, demonstrated by borrow health checks against credited-only balance

Deviations from spec

Griefing — 10 positions instead of 1000
The spec calls for 1000 positions each depositing the minimum amount. Each createPosition in fork mode round-trips a mainnet fork node (~3 s). 1000 positions ≈ 50 minutes of test time. The test uses 10 positions × 1 FLOW against depositCapacityCap = 10, which is mechanically identical to 1000 × 1 FLOW against cap = 1000. The attack path through the contract is the same.

Front-running / Griefing — "transaction fails" → deposit queued
The spec says "User A transaction fails due to insufficient capacity." The protocol never reverts an over-capacity deposit — it silently queues the overflow. The tests assert the economic equivalent: victim's funds arrive, transaction succeeds, but the deposit is fully queued with zero immediate collateral credit.

Sybil — combined credit < 2 × perPositionCap
The spec implies each sybil account gets the full per-position allowance. In practice the per-tx deposit limit is depositCapacity × fraction, which erodes with each deposit. After the honest user consumes 100 FLOW, the remaining capacity is 1900, giving sybil1 a per-tx ceiling of 95 (not 100). The test therefore asserts sybilTotalCredit > perPositionCap (the bypass is real) rather than the unreachable == 2 × perPositionCap.

Regeneration monopolization — no "legitimate user starved" assertion
The spec expects a legitimate user to be blocked after the attacker re-deposits. Test.moveTime in fork mode persists across all subsequent blocks, so the legitimate user's transaction would also observe the elapsed time and benefit from another regeneration cycle. The attack is instead proven by the total: two attackers collectively credit 200 FLOW from a 100-token-cap pool across two cycles.

Queued deposit exploitation — race condition not tested
The spec's attack is cancelling queued deposits after manipulating state. The test covers the prerequisite invariant: queued funds do not count as collateral. The race condition itself is not exercisable in a sequential Cadence test environment

Five adversarial scenarios covering the deposit capacity system:

- Griefing: 10 positions × 1 FLOW minimum exhaust pool capacity (scaled from spec's 1000 × 1 FLOW; mechanically identical, ~50× faster)
- Front-running: attacker consumes full capacity ahead of victim; victim's deposit is fully queued with zero collateral credit
- Sybil: two accounts each deposit up to the per-position cap, collectively exceeding the limit enforced on a single account
- Regeneration monopolization: attacker captures two consecutive regeneration cycles, accumulating 200 FLOW from a 100-token-cap pool
- Queued deposit exploitation: queued funds yield no collateral credit, demonstrated by borrow health checks against credited-only balance
@mts1715 mts1715 requested a review from a team as a code owner March 30, 2026 08:34
@mts1715 mts1715 self-assigned this Mar 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Deposit Capacity Attacks

1 participant