Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: medium
Invalid

Misassignment of the assetOut Parameter When Processing `WETH` Fees

Summary

In the receiveMarketFee function, when the fee is already in WETH, the contract incorrectly passes address(0) as the assetOut parameter to the _handleWethRewardDistribution function. This misassignment disrupts the market's internal fee accounting, potentially leading to misallocated or locked rewards.

Vulnerability Details

In the receiveMarketFee function, when the fee is already in WETH the contract immediately calls the internal reward distribution function. However, it passes an incorrect parameter for the assetOut (i.e. the output asset of the swap) by using address(0) instead of the actual WETH address.

The _handleWethRewardDistribution function uses its second parameter (assetOut) when calling market.receiveWethReward(...) to update the market’s internal fee accounting. In the case of non‑WETH fees swapped later via convertAccumulatedFeesToWeth, a proper asset address is passed to denote that the reward is in WETH. Passing address(0) in the direct WETH case means that the market’s bookkeeping might be misled—for example, it may:

  • Fail to clear or update the received fee balance correctly for that asset, leading to duplicated conversions

This inconsistency between the two paths direct WETH fees versus converted fees may result in rewards being misallocated or even locked—rendering a portion of the collected fees unrecoverable by the protocol or its intended stakeholders.

Code Snippet:

if (asset == MarketMakingEngineConfiguration.load().weth) {
// if asset is weth, we can skip straight to handling the weth reward distribution
_handleWethRewardDistribution(market, address(0), amountX18); // <-- @audit : Passing address(0) for assetOut when fee is already in WETH.
} else {
// update [asset => received fees] mapping
market.depositFee(asset, amountX18);
}

Impact

Fees may be misallocated or locked, rendering them unrecoverable by the protocol or its stakeholders.

Tools Used

  • Manual code review

  • Solidity compiler (solc) for syntax and semantic checks

  • Foundry or Hardhat for testing and validation (recommended)

Recommendations

When the fee asset is already WETH, the function should pass the WETH address (i.e. the same asset value returned by MarketMakingEngineConfiguration.load().weth) to _handleWethRewardDistribution. This ensures that the underlying market logic in market.receiveWethReward correctly identifies the reward asset for further processing.

Updates

Lead Judging Commences

inallhonesty Lead Judge
10 months ago
inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!