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
Add adversarial stress vectors to the FOC Antithesis harness that actively attack the PDP/FWSS/FilecoinPay payment pipeline from the perspective of dishonest clients and SPs. These vectors go beyond happy-path testing, they attempt to steal funds, bypass signature verification, exploit insolvency edge cases, and overwhelm the system with rapid requests.
Motivation
The M4.2 mainnet GA milestone (March 31, 2026) ships with several open items including incomplete audits, unresolved debt handling design, and known audit findings with fix PRs still open.
We need continuous adversarial testing to catch regressions and find new bugs before GA.
What We Test
Active Attacks (stress engine)
A dedicated secondary client wallet with minimal USDFC (0.06) acts as the attacker. It's isolated from the legitimate FOC lifecycle to avoid false positives.
Attack
Persona
What it does
What a finding looks like
Empty Dataset Fee
Deadbeat client
Creates empty datasets via Curio HTTP. Reads client USDFC before and after. Checks funds decreased.
Funds unchanged after confirmed dataset creation means the FWSS burn rail is not extracting the sybil fee. SP is drained 0.1 FIL per request while the client pays nothing.
Insolvency Creation
Deadbeat client
Withdraws all available USDFC from FilecoinPayV1, making the client insolvent. Then attempts to create a new dataset with zero available funds. Re-funds the wallet afterwards for future probes.
Dataset creation succeeds with zero available funds means the validatePayerOperatorApprovalAndFunds check is not enforced. SP provides storage service with zero payment guarantee.
Cross-Payer Replay
Replay attacker
Signs a CreateDataSet EIP-712 message with the attacker's key but encodes the victim (primary FOC client) as the payer in the extraData. Submits via Curio HTTP. Reads victim's funds before and after.
Victim's funds decrease without the victim ever signing means the EIP-712 signature verification does not bind the signer to the payer field. Any address can be charged by anyone who can craft valid extraData.
Burst Creation
Spammer
Fires 3-5 dataset creation requests in rapid succession via Curio HTTP without waiting for on-chain confirmation between requests. Each uses a unique clientDataSetId and fresh EIP-712 signature. Checks how many were accepted and whether fees were charged.
All requests accepted without throttling means no rate limiting exists on the Curio PDP API. An attacker can drain SP FIL at HTTP request speed.
Passive Invariants (foc-sidecar)
The sidecar runs 8 safety checks every 4 seconds against on-chain state:
Check
Type
What it catches
FPV1 solvency
Always
FilecoinPay contract holds less USDFC than the sum of all payer account balances
Rail-to-dataset mapping
Always
Payment rail's reverse mapping points to wrong or deleted dataset
Provider ID consistency
Always
On-chain provider ID from registry doesn't match the ID from DataSetCreated event
Proofset liveness
Always
Active (non-deleted) dataset reports dataSetLive = false on-chain
Deleted dataset not live
Always
Deleted dataset still reports dataSetLive = true on-chain
Proving advancement
Sometimes
Challenge epoch and proven epoch advance over time (proving pipeline working)
Piece accounting
Always
activePieceCount > leafCount for a dataset (should be impossible)
Rate consistency
Always
Dataset with active pieces has zero payment rate on its PDP rail
Architecture
Single deck entry DoPDPGriefingProbe with random internal dispatch across attack vectors
Secondary client wallet removed from general wallet pool (prevents nonce collision with other stress vectors)
All attack assertions use assert.Sometimes (tolerant of Antithesis fault injection where any tx can fail)
Read-only access to FOC primary dataset state (no interference with legitimate FOC lifecycle)
Sidecar assertions use assert.Always for safety invariants
Future Vectors
Settlement drain: Client withdraws USDFC right before settlement epoch, SP's settle tx reverts
Unilateral SP termination: SP terminates client's dataset without consent
Nonce replay after deletion: Reuse clientDataSetId after dataset is deleted
Settlement overpayment: Verify settlement math doesn't overcharge via integer truncation
Summary
Add adversarial stress vectors to the FOC Antithesis harness that actively attack the PDP/FWSS/FilecoinPay payment pipeline from the perspective of dishonest clients and SPs. These vectors go beyond happy-path testing, they attempt to steal funds, bypass signature verification, exploit insolvency edge cases, and overwhelm the system with rapid requests.
Motivation
The M4.2 mainnet GA milestone (March 31, 2026) ships with several open items including incomplete audits, unresolved debt handling design, and known audit findings with fix PRs still open.
We need continuous adversarial testing to catch regressions and find new bugs before GA.
What We Test
Active Attacks (stress engine)
A dedicated secondary client wallet with minimal USDFC (0.06) acts as the attacker. It's isolated from the legitimate FOC lifecycle to avoid false positives.
validatePayerOperatorApprovalAndFundscheck is not enforced. SP provides storage service with zero payment guarantee.Passive Invariants (foc-sidecar)
The sidecar runs 8 safety checks every 4 seconds against on-chain state:
dataSetLive = falseon-chaindataSetLive = trueon-chainactivePieceCount > leafCountfor a dataset (should be impossible)Architecture
DoPDPGriefingProbewith random internal dispatch across attack vectorsassert.Sometimes(tolerant of Antithesis fault injection where any tx can fail)assert.Alwaysfor safety invariantsFuture Vectors
Branch
parth/sybil-fee