From 6c90bce3a62f9f97514ba8819611872913ba68a2 Mon Sep 17 00:00:00 2001 From: Conner Swenberg Date: Thu, 18 Dec 2025 22:58:51 -0800 Subject: [PATCH] Fix fuzzing for AdConversion.onSend tests --- test/integration/AdConversion.t.sol | 1 + test/unit/hooks/AdConversion/onSend.t.sol | 32 ++++++++++++++++------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/test/integration/AdConversion.t.sol b/test/integration/AdConversion.t.sol index 1fe07df5..266c9c7d 100644 --- a/test/integration/AdConversion.t.sol +++ b/test/integration/AdConversion.t.sol @@ -1007,6 +1007,7 @@ contract AdConversionIntegrationTest is AdConversionTestBase { // Constrain inputs vm.assume(advertiser != address(0) && attributionProvider != address(0)); vm.assume(advertiser != attributionProvider); + vm.assume(publisher != advertiser && publisher != attributionProvider); campaignFunding = bound(campaignFunding, MIN_CAMPAIGN_FUNDING, MAX_CAMPAIGN_FUNDING); attributionAmount = bound(attributionAmount, MIN_ATTRIBUTION_AMOUNT, campaignFunding / 2); feeBps = uint16(bound(feeBps, MIN_FEE_BPS, adConversion.MAX_BPS())); diff --git a/test/unit/hooks/AdConversion/onSend.t.sol b/test/unit/hooks/AdConversion/onSend.t.sol index 0d4db01f..74348676 100644 --- a/test/unit/hooks/AdConversion/onSend.t.sol +++ b/test/unit/hooks/AdConversion/onSend.t.sol @@ -971,8 +971,12 @@ contract OnSendTest is AdConversionTestBase { callHookOnSend(attributionProvider1, testCampaign, address(tokenA), abi.encode(attributions)); // Verify correct fee calculation - assertEq(payouts.length, 1, "Should have one payout"); - assertEq(payouts[0].amount, expectedNetAmount, "Net payout amount should be correct"); + if (feeBps == MAX_FEE_BPS) { + assertEq(payouts.length, 0, "Should have no payouts when fee is max"); + } else { + assertEq(payouts.length, 1, "Should have one payout"); + assertEq(payouts[0].amount, expectedNetAmount, "Net payout amount should be correct"); + } if (expectedFee > 0) { assertEq(fees.length, 1, "Should have one fee distribution when fee > 0"); @@ -1024,15 +1028,19 @@ contract OnSendTest is AdConversionTestBase { (Flywheel.Payout[] memory payouts, Flywheel.Distribution[] memory fees,) = callHookOnSend(attributionProvider1, testCampaign, address(tokenA), abi.encode(attributions)); - // Verify rounding behavior - fee should round DOWN due to integer division - assertEq(payouts.length, 1, "Should have one payout"); - assertEq(payouts[0].amount, expectedNetAmount, "Net amount should account for rounding"); - assertEq(fees.length, 1, "Should have one fee distribution"); assertEq(fees[0].amount, expectedFee, "Fee should be rounded down"); - // Verify the total adds up correctly (no tokens lost to rounding) - assertEq(payouts[0].amount + fees[0].amount, smallAmount, "Total should equal original amount"); + if (feeBps == MAX_FEE_BPS) { + assertEq(payouts.length, 0, "Should have no payouts when fee is max"); + } else { + // Verify rounding behavior - fee should round DOWN due to integer division + assertEq(payouts.length, 1, "Should have one payout"); + assertEq(payouts[0].amount, expectedNetAmount, "Net amount should account for rounding"); + + // Verify the total adds up correctly (no tokens lost to rounding) + assertEq(payouts[0].amount + fees[0].amount, smallAmount, "Total should equal original amount"); + } } /// @dev Verifies fees are accumulated correctly for multiple conversions @@ -1306,8 +1314,12 @@ contract OnSendTest is AdConversionTestBase { // Verify conservation of tokens across the batch assertEq(actualTotalPayouts + actualTotalFees, totalOriginalAmount, "Batch should conserve total token amounts"); - // Verify we have payouts for all attributions - assertGt(payouts.length, 0, "Should have payouts for batch"); + // Verify payouts length is correct based on fee BPS + if (feeBps == MAX_FEE_BPS) { + assertEq(payouts.length, 0, "Should have no payouts when fee is max"); + } else { + assertGt(payouts.length, 0, "Should have payouts for batch"); + } } /// @dev Processes batch with zero fee correctly