RebateFi Hook

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

_isReFiBuy Returns Incorrect Buy/Sell Direction

Root + Impact

Description

  • Normal Behavior:
    The _isReFiBuy function is intended to determine whether a swap is a buy of ReFi based on which token is currency0 and the zeroForOne flag:

    • zeroForOne = true → swapping currency0 for currency1

    • zeroForOne = false → swapping currency1 for currency0

    Observed Issue:
    The current implementation returns the wrong boolean values, effectively inverting buy/sell logic for ReFi swaps:

  • If ReFi is currency0, _isReFiBuy incorrectly returns true when zeroForOne = true (selling ReFi instead of buying).

If ReFi is currency1, _isReFiBuy incorrectly flips the logic as well.

function _isReFiBuy(PoolKey calldata key, bool zeroForOne) internal view returns (bool) {
bool IsReFiCurrency0 = Currency.unwrap(key.currency0) == ReFi;
if (IsReFiCurrency0) {
return zeroForOne; // WRONG
} else {
return !zeroForOne; // WRONG
}
}

Risk

Likelihood:

  • Any swap involving ReFi will trigger the incorrect buy/sell flag.

Automated scripts, frontend integrations, or liquidity pools will all rely on this logic.

Impact:

  • Users buying ReFi are incorrectly charged a 0.3% fee, which should be 0%.

Users selling ReFi are incorrectly charged 0% fee, which should be 0.3%.

  • Breaks intended economic design of the protocol and could cause loss of trust or financial imbalance.

Proof of Concept

// ReFi is currency0
PoolKey memory key = PoolKey({
currency0: ReFi,
currency1: USDC,
fee: 300
});
// Swapping USDC for ReFi (zeroForOne = false) → should be a buy
bool isBuy = _isReFiBuy(key, false);
// Buggy code returns false (wrong, user is buying ReFi)
// Fixed code returns true
// ReFi is currency1
PoolKey memory key2 = PoolKey({
currency0: USDC,
currency1: ReFi,
fee: 300
});
// Swapping USDC for ReFi (zeroForOne = true) → should be a buy
bool isBuy2 = _isReFiBuy(key2, true);
// Buggy code returns false (wrong, user is buying ReFi)
// Fixed code returns true

Recommended Mitigation

- if (IsReFiCurrency0) {
- return zeroForOne;
- } else {
- return !zeroForOne;
+ if (IsReFiCurrency0) {
+ return !zeroForOne;
+ } else {
+ return zeroForOne;
Updates

Lead Judging Commences

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

Inverted buy/sell logic when ReFi is currency0, leading to incorrect fee application.

Support

FAQs

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

Give us feedback!