Repository navigation
Add fuzz tests for funds adding up when squeezing - #364
BhariGowda wants to merge 1 commit into
Conversation
The three existing conservation fuzz tests in Streams.t.sol all move funds with receiveStreams only, so squeezing was never covered by them. Squeezing is the one path that writes negative amtDeltas, which makes it the part of the accounting most worth fuzzing. The two new tests assert that squeezed plus withdrawn plus received equals the balance the sender started with. The first repeats squeezing at two fuzzed points that can fall in different cycles, the second squeezes both before and after the receivers list is replaced mid-stream, so the history has two entries and the currCycleConfigs slot mapping is exercised. Both pass at 50000 runs, the count CI uses on pushes. They use at most 10 receivers because squeezing every receiver in a list is quadratic and the squeezing logic does not depend on the list length.
|
Reopening with a fix to the tests themselves. They passed, but they were barely exercising the path they exist to cover. Squeezing only reaches back to the start of the current cycle, so the squeezable window is The fix gives the squeeze tests their own sanitizer instead of the generic one.
The runs that still squeeze zero are empty receiver lists (10.4%), zero balances (1.6%) and squeeze times landing exactly on a cycle boundary, which gives a zero length window. I left those in rather than filtering them out. I also corrected a factual error in the description. It justified the 10 receiver cap by claiming longer lists were already covered by Verification: Slither reports 0 findings, One note on CI, so a red check here is not misread. The Tests run on this PR failed without executing a single job. This repo has had two |
The three conservation fuzz tests in
Streams.t.sol(testFundsStreamedToReceiversAddUp,testFundsStreamedToReceiversAddUpAfterStreamsUpdateandtestFundsStreamedFromSendersAddUp) all take funds out withreceiveStreams. None of them squeeze, so squeezing was not covered by any of the funds adding up checks. It is the only path that writes negativeamtDeltas, so it looked like the gap most worth closing.This adds two tests asserting the same property those three assert, that squeezed plus withdrawn plus received equals the balance the sender started with.
testFundsSqueezedAndReceivedAddUpsqueezes twice at independently fuzzed times, each up to three cycles long. The two squeezes can land in the same cycle or in different ones, and the second one can fall after the streams have already run out.testFundsSqueezedAcrossStreamsUpdatesAddUpsqueezes once, replaces the receivers list mid-stream, then squeezes both the old and the new list against a two entry history. This covers thecurrCycleConfigsslot mapping in_squeezeStreamsResultand stalenextSqueezedvalues being clamped up to the current cycle start.Both pass at 50000 runs, the count CI uses on pushes.
The two tests cap the receivers list at 10 instead of the 100 the existing tests use. Squeezing every receiver in a list is quadratic, and at 100 these two cost more than the existing three combined. At 10 they finish in 81s at 50000 runs, with mean gas of 0.9M and 1.6M against 8.1M for
testFundsStreamedToReceiversAddUpAfterStreamsUpdate. The squeezing logic does not depend on the list length, and longer lists are already covered bytestStreamsWithManyReceiversCanBeSqueezed.No source changes.
forge testis green at 380 tests,forge fmt --checkpasses and Slither reports nothing.