RebateFi Hook

First Flight #53
Beginner FriendlyDeFi
100 EXP
View results
Submission Details
Severity: low
Valid

Fee Misreporting in Event

Incorrect fee denominator used when calculating feeAmount for the ReFiSold event, causing the hook to report a fee 10× larger than the actual intended sell fee.

Description

  • The RebateFi hook is designed to apply reduced fees on buys and standard (0.3%) or premium fees on sells. These fee amounts are meant to be accurately reflected in emitted events so off-chain systems, dashboards, analytics, and monitoring tools can correctly understand user behavior, measure selling pressure, and adjust sell fees accordingly.

  • The hook calculates the feeAmount emitted in the ReFiSold event using an incorrect denominator (100_000). When sellFee is set to values intended to represent Uniswap’s fee units (millionths), the event reports a fee that is 10× higher than the fee actually charged. While the on-chain swap execution is correct, the event misrepresents protocol behavior and misleads any system relying on events for economic logic, revenue tracking, user analytics, or anti-dump detection.

// Root cause in the codebase with @> marks to highlight the relevant section
uint24 public sellFee = 3000;
// ....
function _beforeSwap(
address sender,
PoolKey calldata key,
SwapParams calldata params,
bytes calldata
) internal override returns (bytes4, BeforeSwapDelta, uint24) {
// ....
@> uint256 feeAmount = (swapAmount * sellFee) / 100000;
// ....
}

Risk

Likelihood:

  • The issue occurs whenever a sell transaction is executed, because sellFee is interpreted in millionths while the event calculation always divides by 100_000, producing a 10× inflated fee in every ReFiSold event.

  • Any off-chain analytics, dashboards, bots, or monitoring tools that read these events will consistently consume incorrect fee data, since events are their primary data source.

Impact:

  • Off-chain systems will misinterpret normal sells as significantly larger or more heavily penalized, disrupting RebateFi’s intended economic model and potentially flagging legitimate behavior as “dumping.”

  • Fee analytics, revenue reporting, user dashboards, or incentive mechanisms relying on event data will produce incorrect outputs, damaging protocol reliability and potentially leading to incorrect business or governance decisions.

Proof of Concept

  1. Set sellFee to 3000 in the RebateFi hook, which is intended to represent 0.3% of the swap amount.

  2. Execute a sell transaction of swapAmount = 1000 tokens through the hook.

  3. Observe the emitted ReFiSold event: feeAmount = (swapAmount * sellFee) / 100_000;

  4. Calculation: feeAmount = 1000 * 3000 / 100_000 = 30

  5. Compare with the actual intended fee: Actual fee = 1000 * 0.3% = 3

  6. Result: The event reports a fee 10× higher than the actual fee charged.

function test_ReFiSold_Event_Reports10xInflatedFee() public {
uint256 swapAmount = 0.01 ether;
vm.startPrank(user1);
reFiToken.approve(address(swapRouter), type(uint256).max);
vm.recordLogs();
SwapParams memory params = SwapParams({
zeroForOne: false,
amountSpecified: -int256(swapAmount),
sqrtPriceLimitX96: TickMath.MAX_SQRT_PRICE - 1
});
PoolSwapTest.TestSettings memory testSettings = PoolSwapTest
.TestSettings({takeClaims: false, settleUsingBurn: false});
swapRouter.swap(key, params, testSettings, ZERO_BYTES);
Vm.Log[] memory logs = vm.getRecordedLogs();
uint256 emittedAmount;
uint256 emittedFee;
for (uint i = 0; i < logs.length; i++) {
if (
logs[i].topics[0] ==
keccak256("ReFiSold(address,uint256,uint256)")
) {
(emittedAmount, emittedFee) = abi.decode(
logs[i].data,
(uint256, uint256)
);
break;
}
}
uint256 correctFee = (emittedAmount * 3000) / 1_000_000; // 3000 pips = 0.3%
assertEq(emittedFee, correctFee * 10, "Fee should be 10x actual"); // actual fee is 10x than correct
vm.stopPrank();
}

Recommended Mitigation

Update the fee calculation denominator in the ReFiSold event emission to match Uniswap v4's fee unit system. Uniswap v4 represents fees in hundredths of a basis point (pips) with a denominator of 1,000,000, where 3000 = 0.3%. The current implementation uses 100,000 as the denominator, causing the event to report fees that are 10× higher than actual. Correcting the denominator to 1,000,000 ensures the emitted feeAmount accurately reflects the fee percentage.

- uint256 feeAmount = (swapAmount * sellFee) / 100000;
+ uint256 feeAmount = (swapAmount * sellFee) / 1_000_000;
Updates

Lead Judging Commences

chaossr Lead Judge 11 days ago
Submission Judgement Published
Validated
Assigned finding tags:

Incorrect denominator (100000 instead of likely 1000000 or 10000) in fee calculation for ReFiSold event.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!