RebateFi Hook

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

SellFee is not calculated correctly, which leads to on-chain data incorrectly recorded.

SellFee is not calculated correctly, which leads to on-chain data incorrectly recorded.

Description

  • _beforeSwap calculates sellFee with the wrong denominator.

  • However, while the fee returned by the function is correct, the feeAmount emitted in the ReFiSold event is incorrect.

function _beforeSwap(address sender, PoolKey calldata key, SwapParams calldata params, bytes calldata)
internal
override
returns (bytes4, BeforeSwapDelta, uint24)
{
bool isReFiBuy = _isReFiBuy(key, params.zeroForOne);
uint256 swapAmount =
params.amountSpecified < 0 ? uint256(-params.amountSpecified) : uint256(params.amountSpecified);
uint24 fee;
if (isReFiBuy) {
fee = buyFee;
emit ReFiBought(sender, swapAmount);
} else {
fee = sellFee;
@> uint256 feeAmount = (swapAmount * sellFee) / 100000; //@audit 3000/100000 is 3%, should be 0.3%
emit ReFiSold(sender, swapAmount, feeAmount);
}
return (BaseHook.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, fee | LPFeeLibrary.OVERRIDE_FEE_FLAG);
}

Risk

Likelihood:

  • This error occurs on every swap identified as a "sell" of the ReFi token.

Impact:

  • The primary impact is the emission of incorrect on-chain data. The ReFiSold event reports a feeAmount that is 10 times larger than the amount corresponding to the intended 0.3% fee.

Proof of Concept

The test case test_BuyReFi_ZeroFeeserves as a proof of concept for this issue, as the logic inversion causes a "buy" to be processed by the "sell" logic branch. The log trace shows the ReFiSold event being emitted with an incorrect fee amount:

│ │ │ │ ├─ [7225] ReFiSwapRebateHook::beforeSwap(PoolSwapTest: [0x2e234DAe75C793f67A35089C9d99245E1C58470b], PoolKey({ currency0: 0x0000000000000000000000000000000000000000, currency1: 0x212224D2F2d262cd093eE13240ca4873fcCBbA3C, fee: 8388608 [8.388e6], tickSpacing: 60, hooks: 0xF398DeAF12Ba47830ECA5a881175a3690A90F080 }), SwapParams({ zeroForOne: true, amountSpecified: -10000000000000000 [-1e16], sqrtPriceLimitX96: 4295128740 [4.295e9] }), 0x)
│ │ │ │ │ ├─ emit ReFiSold(seller: PoolSwapTest: [0x2e234DAe75C793f67A35089C9d99245E1C58470b], amount: 10000000000000000 [1e16], fee: 300000000000000 [3e14])
│ │ │ │ │ └─ ← [Return] 0x575e24b4, 0, 4197304 [4.197e6]

Let's analyze the emitted values:

  • swapAmount: 10000000000000000 (1e16)

  • emitted feeAmount: 300000000000000 (3e14)

The sellFee is 3000 (representing 0.3%), but the code calculates the feeAmount using an incorrect denominator of 100,000:

feeAmount = (swapAmount * sellFee) / 100000
feeAmount = (1e16 * 3000) / 100000 = 3e14

This calculation results in a 3% fee, not the intended 0.3%. The correct calculation requires a denominator of 1,000,000:

correctFeeAmount = (1e16 * 3000) / 1000000 = 3e13

The emitted feeAmount (3e14) is ten times larger than the correct amount (3e13), confirming the bug.

Recommended Mitigation

function _beforeSwap(address sender, PoolKey calldata key, SwapParams calldata params, bytes calldata)
internal
override
returns (bytes4, BeforeSwapDelta, uint24)
{
bool isReFiBuy = _isReFiBuy(key, params.zeroForOne);
uint256 swapAmount =
params.amountSpecified < 0 ? uint256(-params.amountSpecified) : uint256(params.amountSpecified);
uint24 fee;
if (isReFiBuy) {
fee = buyFee;
emit ReFiBought(sender, swapAmount);
} else {
fee = sellFee;
- uint256 feeAmount = (swapAmount * sellFee) / 100000;
+ uint256 feeAmount = (swapAmount * sellFee) / 1000000;
emit ReFiSold(sender, swapAmount, feeAmount);
}
return (BaseHook.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, fee | LPFeeLibrary.OVERRIDE_FEE_FLAG);
}
Updates

Lead Judging Commences

chaossr Lead Judge 12 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!