Platform: Code4rena
Start Date: 28/09/2023
Pot Size: $36,500 USDC
Total HM: 5
Participants: 115
Period: 6 days
Judge: 0xDjango
Total Solo HM: 1
Id: 290
League: ETH
Rank: 98/115
Findings: 1
Award: $4.37
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Bauchibred
Also found by: 0x3b, 0xDetermination, 0xMosh, 0xScourgedev, 0xTheC0der, 0xTiwa, 0xWaitress, 0xdice91, 0xfusion, 0xpiken, 0xprinc, 0xweb3boy, ArmedGoose, Aymen0909, Breeje, Brenzee, Daniel526, DavidGiladi, DeFiHackLabs, Flora, Fulum, HChang26, Hama, IceBear, J4X, Krace, KrisApostolov, Maroutis, Mirror, MohammedRizwan, Norah, PwnStars, SPYBOY, TangYuanShen, Testerbot, ThreeSigma, Tricko, al88nsk, alexweb3, ast3ros, berlin-101, bin2chen, blutorque, btk, d3e4, deth, e0d1n, ether_sky, ge6a, gkrastenov, glcanvas, hals, imare, inzinko, jkoppel, jnforja, joaovwfreire, josephdara, kutugu, lotux, lsaudit, mahdirostami, merlin, n1punp, nadin, neumo, nisedo, nobody2018, oakcobalt, orion, peanuts, pep7siup, pina, ptsanev, rokinot, rvierdiiev, said, santipu_, sashik_eth, seerether, squeaky_cactus, terrancrypt, tonisives, twicek, vagrant, xAriextz, y4y
4.3669 USDC - $4.37
https://github.com/code-423n4/2023-09-venus/blob/main/contracts/Tokens/Prime/Prime.sol#L537 https://github.com/code-423n4/2023-09-venus/blob/main/contracts/Tokens/Prime/Prime.sol#L507
The calculateAPR()
and estimateAPR()
functions currently do not apply decimal scaling to the capital value returned by _capitalForScore()
. Resulting in incorrect calculations, potential integration problems, and UI issues.
The _capitalForScore()
function calculate the capital for calculation of score. Every function that utilizes this value should scale it by the number of vToken decimal. The _calculateScore()
function provides a correct example of this scaling, as shown below:
(uint256 capital, , ) = _capitalForScore(xvsBalanceForScore, borrow, supply, market); capital = capital * (10 ** (18 - vToken.decimals()));
However, the calculateAPR()
and estimateAPR()
functions currently use the capital value directly, without scaling:
(uint256 capital, uint256 cappedSupply, uint256 cappedBorrow) = _capitalForScore( xvsBalanceForScore, borrow, supply, market ); uint256 userScore = Scores.calculateScore(xvsBalanceForScore, capital, alphaNumerator, alphaDenominator);
(, uint256 cappedSupply, uint256 cappedBorrow) = _capitalForScore( xvsBalanceForScore, borrow, supply, address(vToken) ); return _calculateUserAPR(market, supply, borrow, cappedSupply, cappedBorrow, userScore, totalScore);
This can potentially lead to discrepancies in calculations and issues when working with tokens that have different decimal precisions. Users and protocols interacting with the Prime might also face confusion or errors when making decisions based on these values, and UI-related problems when interacting with this view functions.
Manual review
We recommend scaling the returned values like this: capital = capital * (10 ** (18 - vToken.decimals()));
Decimal
#0 - c4-pre-sort
2023-10-05T00:19:54Z
0xRobocop marked the issue as duplicate of #147
#1 - c4-judge
2023-10-31T19:51:02Z
fatherGoose1 changed the severity to QA (Quality Assurance)
#2 - 0xbtk
2023-11-07T17:59:08Z
Hey @fatherGoose1,
I respectfully disagree, estimateAPR()
is a main view function of the Prime contract and it calculates the supply and borrow APR for estimated supply. This issue clearly shows how estimateAPR()
will return incorrect result, and it's important to note that it wasn't documented anywhere at the time of the contest that the estimation should not be taken as a promise.
It's worth noting that a similar issue was previously classified as medium, Hansfriese commented, "It looks like a middle of Medium and Low as it's a view function. Will keep as Medium because it will be used to estimate the profit rate for users."
Reference:
https://github.com/code-423n4/2023-06-angle-findings/issues/28
#3 - fatherGoose1
2023-11-08T19:31:39Z
@0xbtk I also agree that an APR calculation error falls somewhere between Low and Medium. I am sticking with QA as the recommended fix doesn't actually fix the APR calculation. As seen in issue #122, the capital should be scaled by _getUnderlying(market).decimals()
, not vToken.decimals()
. It's helpful that you have flagged the lack of scaling, but since the recommendation does not perform the correct scaling, the APR calculation would still be incorrect.