Tadle

Tadle
DeFiFoundry
27,750 USDC
View results
Submission Details
Severity: medium
Invalid

The `SystemConfig::getPlatformFeeRate` returns `basePlatformFeeRate` for any user if their `userPlatformFeeRate[_user]` is 0, which can conflict the intention of the protocol owner if the 0 fee is intentionally set for someone as a promotion

Summary

In the function SystemConfig::updateUserPlatformFeeRate(), the protocol owner has the authority to set any number as the platform fee for any individual user, as long as _platformFeeRate <= Constants.PLATFORM_FEE_DECIMAL_SCALER. This means it's totally reasonable in business sense that, the protocol owner has full authority to set it as a very low number for certain users, likely in the event of a marketing promotion for a limited period of time. He can set it as 1 (effectively 0.0001% in this protocol), which is an extremely small number just next to 0; or he can set it to 0 directly, meaning free platform fee for now. The updateUserPlatformFeeRate() function totally allow the owner to do that.

However, the logic in the function SystemConfig::getPlatformFeeRate() returns basePlatformFeeRate (which is 0.5% by default according to the natspec) for any user if their userPlatformFeeRate[_user] is 0. It's obvious that the design behind this line of code is to prepare for the uninitialized cases, where all the uint256 numbers are falsely number 0 by default; however, it cannot distinguish the cases where the protocol owner intentionally wanted to use the number 0 as a promotion for certain users.

Vulnerability Details

Let's take a look at the code below:

function getPlatformFeeRate(address _user) external view returns (uint256) {
if (userPlatformFeeRate[_user] == 0) {
return basePlatformFeeRate;
}
return userPlatformFeeRate[_user];
}

We can compare the two cases below:

  1. The protocol owner set the platform fee as 1 for a certain user, then the function getPlatformFeeRate will return 1, which means 0.0001% in business term.

  2. The protocol owner set the platform fee as 0 for a certain user as a promotion rate for a limited time, but the function getPlatformFeeRate will return basePlatformFeeRate, which by default is 0.5% in business term.

The protocol owner input two very close numbers (1 and 0) in cases above, but the return values are drastically different.

Impact

In the real world, a free platform fee for a limited time is a common marketing campaign. However, this bug in the code leads to the consequence that the protocol owner is unable to set it as 0 for anybody, and the best number he can use is 1 (0.0001%), which itself is a weird number to use. This logical bug invalidates the intended functionality of customizable user-specific fee rates. It's business impact makes it an M severity issue.

Tools Used

Manual Review

Recommendations

  • A clear distinction needs to be managed between users who should not have any fee (0% rate) and those whose fee rate has not been set (and therefore should inherit the basePlatformFeeRate).

  • To resolve this, a separate flag or marker could be used to indicate users with explicitly no fees

Updates

Lead Judging Commences

0xnevi Lead Judge
about 1 year ago
0xnevi Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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