Part 2

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

`checkFeeDistributionNeeded` Will Not Work With Low Decimal Assets

Summary

The FeeConversionKeeper is a keeper used for automatic fee distribution. It works with two main functions - checkUpkeep and performUpkeep. When checkUpkeep returns true, performUpkeep executes. Inside checkUpkeep there is a call to checkFeeDistributionNeeded to decide whether a distribution is needed or not. However, the function does not work as intended because it makes a call to FeeDistributionBranch::getAssetValue and expects the value do be in base 18. The function returns "the calculated value of the asset in its native units".

Vulnerability Details

The FeeConversionKeeper is a keeper used for automatic fee distribution. It works with two main functions - checkUpkeep and performUpkeep. When checkUpkeep returns true, performUpkeep executes. Inside checkUpkeep there is a call to checkFeeDistributionNeeded to decide whether a distribution is needed or not. However, the function does not work as intended because it makes a call to FeeDistributionBranch::getAssetValue and expects the value do be in base 18. The function returns "the calculated value of the asset in its native units".

/// @notice Calculates the value of a specified asset in terms of its collateral.
/// @dev Uses the asset's price and amount to compute its value.
/// @param asset The address of the asset.
/// @param amount The amount of the asset to calculate the value for.
/// @return value The calculated value of the asset in its native units.
function getAssetValue(address asset, uint256 amount) public view returns (uint256 value) {
// load collateral
Collateral.Data storage collateral = Collateral.load(asset);
// get asset price in 18 dec
UD60x18 priceX18 = collateral.getPrice();
// convert token amount to 18 dec
UD60x18 amountX18 = collateral.convertTokenAmountToUd60x18(amount);
// calculate token value based on price
UD60x18 valueX18 = priceX18.mul(amountX18);
// ud60x18 -> uint256
value = collateral.convertUd60x18ToTokenAmount(valueX18);
}

And

/// @notice Checks if fee distribution is needed based on the asset and the collected fee amount.
/// @param asset The address of the asset being evaluated.
/// @param collectedFee The amount of fee collected for the asset.
/// @return distributionNeeded A boolean indicating whether fee distribution is required.
function checkFeeDistributionNeeded(
address asset,
uint256 collectedFee
)
public
view
returns (bool distributionNeeded)
{
// load keeper data from storage
FeeConversionKeeperStorage storage self = _getFeeConversionKeeperStorage();
/// get asset value in USD
uint256 assetValue = self.marketMakingEngine.getAssetValue(asset, collectedFee);
// if asset value GT min distribution value return true
distributionNeeded = assetValue > self.minFeeDistributionValueUsd;
}

As we can see the minFeeDistributionValueUsd is a fixed value. However, different assets have different collaterals which have different decimals. This means that the current logic will work only for assets with collaterals with decimals equal to 18. If they are less than the assetValue will never be enough to trigger a distribution.

Impact

Non working FeeConversionKeeper which means non converted fees to WETH in the cases in which the decimals of the collateral of a given asset is less than 18.

Tools Used

Manual Review

Recommendations

Either make a call to collateral.convertTokenAmountToUd60x18 for the returned value of getAssetValue or add a new function (for example getAssetValueX18) that will do this internally and return the value in base 18.

Updates

Lead Judging Commences

inallhonesty Lead Judge
10 months ago
inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Appeal created

1337web3 Submitter
10 months ago
inallhonesty Lead Judge
9 months ago
inallhonesty Lead Judge 9 months ago
Submission Judgement Published
Validated
Assigned finding tags:

`checkFeeDistributionNeeded` Will Not Work With Low Decimal Assets

Support

FAQs

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

Give us feedback!