Part 2

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

Single market failure blocks entire upkeep

Summary

The FeeConversionKeeper::performUpkeep function iterates over an array of marketIds and attempts to convert accumulated fees to WETH using the convertAccumulatedFeesToWeth function for each market. However, the current implementation does not handle failures in individual market conversions properly.

[src/external/chainlink/keepers/fee-conversion-keeper/FeeConversionKeeper.sol]
109 // call FeeDistributionBranch::convertAccumulatedFeesToWeth
110 function performUpkeep(bytes calldata performData) external override onlyForwarder {
111 FeeConversionKeeperStorage memory self = _getFeeConversionKeeperStorage();
112
113 IMarketMakingEngine marketMakingEngine = self.marketMakingEngine;
114
115 // decode performData
116 (uint128[] memory marketIds, address[] memory assets) = abi.decode(performData, (uint128[], address[]));
117
118 // convert accumulated fees to weth for decoded markets and assets
119 for (uint256 i; i < marketIds.length; i++) {
-> 120 marketMakingEngine.convertAccumulatedFeesToWeth(marketIds[i], assets[i], self.dexSwapStrategyId, "");
121 }
122 }

Vulnerability Details

In the convertAccumulatedFeesToWeth function, the following checks are made for each market in the loop:

[src/market-making/branches/FeeDistributionBranch.sol]
161 // reverts if the market hasn't received any fees for the given asset
162 (bool exists, uint256 receivedFees) = market.receivedFees.tryGet(asset);
163 if (!exists) revert Errors.MarketDoesNotContainTheAsset(asset);
-> 164 if (receivedFees == 0) revert Errors.AssetAmountIsZero(asset);

If any market doesn't have fees for the given asset (i.e., receivedFees is zero or the asset doesn't exist for that market), the performUpkeep function will revert. This causes the entire loop to fail, even if the other markets have accumulated fees and should proceed with the conversion.

Impact

If the upkeep process fails due to a market not having fees, valid fee conversions for other markets are also missed.

Recommendations

Modify the performUpkeep function to catch errors for each market individually. If one market fails, log the error and continue processing the rest of the markets without reverting the entire function call.

Updates

Lead Judging Commences

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

Support

FAQs

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