Platform: Code4rena
Start Date: 21/08/2023
Pot Size: $36,500 USDC
Total HM: 1
Participants: 43
Period: 7 days
Judge: Dravee
Id: 277
League: ETH
Rank: 19/43
Findings: 1
Award: $97.25
š Selected for report: 0
š Solo Findings: 0
š Selected for report: Udsen
Also found by: 0xSmartContract, 0xmystery, 0xprinc, Fulum, JP_Courses, MatricksDeCoder, Mirror, MohammedRizwan, MrPotatoMagic, Rolezn, Shubham, Testerbot, ast3ros, chainsnake, lanrebayode77, lsaudit, nisedo, plainshift, pontifex, prapandey031
97.2487 USDC - $97.25
Number | Issue | Instances | |
---|---|---|---|
[Lā01] | Failed assertion inside divuu() function affecting the divu() functionality in EvolvingProteus.sol | 3 | |
[Lā02] | Misleading comment on function b() calculation | 1 | |
[Lā03] | Use of outdated version of abdk-library | 1 | |
[Lā04] | Misleading comment on withdrawGivenInputAmount() as it uses FEE_DOWN | 1 | |
[Lā05] | Misleading comment on MIN_PRICE_VALUE calculation | 1 |
divuu()
function affecting the divu()
functionality in EvolvingProteus.sol
EvolvingProteus.sol
has used ABDKMath64x64.sol
which has a potential issue with assert condition. This assert condition is present in divuu()
which is used in divu()
. It is to be noted here divu()
has been extensively used in contract at below locations,
Instance 1
function t(Config storage self) public view returns (int128) { >> return elapsed(self).divu(duration(self)); }
Instance 2
constructor( int128 py_init, int128 px_init, int128 py_final, int128 px_final, uint256 duration ) { // some code >> if (py_init.div(py_init.sub(px_init)) > ABDKMath64x64.divu(uint(MAX_PRICE_RATIO), 1)) revert MaximumAllowedPriceRatioExceeded(); >> if (py_final.div(py_final.sub(px_final)) > ABDKMath64x64.divu(uint(MAX_PRICE_RATIO), 1)) revert MaximumAllowedPriceRatioExceeded(); }
Instance 3
function _getUtility( int256 x, int256 y ) internal view returns (int256 utility) { // some code >> int128 two = ABDKMath64x64.divu(uint256(2 * MULTIPLIER), uint256(MULTIPLIER)); >> int128 one = ABDKMath64x64.divu(uint256(MULTIPLIER), uint256(MULTIPLIER)); // some code }
If you see inside the divu()
in ABDKMath64x64.sol
, divuu()
has been used here which is a major issue
function divu (uint256 x, uint256 y) internal pure returns (int128) { unchecked { require (y != 0); >> uint128 result = divuu (x, y); require (result <= uint128 (MAX_64x64)); return int128 (result); } }
The issue here with divuu()
is with this assert condition which fails in divuu()
function.
function divuu (uint256 x, uint256 y) private pure returns (uint128) { // some code >> assert (xh == hi >> 128); // some code
This issue has been accepted by abdk libraries and seems to be fixed in latest version. Reference link: check here
abdk libraries has fixed this issue with following changes in ABDKMath64x64.sol
function divuu (uint256 x, uint256 y) private pure returns (uint128) { - assert (xh == hi >> 128); - result += xl / y; + result += xh == hi >> 128 ? xl / y : 1;
Alternatively, The library can be upgraded to latest version v3.2 to fix this issue.
b()
calculationThere is a misleading and incorrect comment on calculation of b varibale on curve equation.
/** >> @notice Calculates the b variable in the curve eq which is basically a sq. root of the inverse of x instantaneous price @param self config instance */ function b(Config storage self) public view returns (int128) { return p_min(self).sqrt(); }
Per contest readme, b
variable is calculated as b = sqrt(p_min_current)
, here it is directly taken as square root of p_min_current and does not take the inverse of p_min_current. Therefore the Natspec is incorrect.
/** - @notice Calculates the b variable in the curve eq which is basically a sq. root of the inverse of x instantaneous price + @notice Calculates the b variable in the curve eq which is basically a sq. root of x instantaneous price @param self config instance */ function b(Config storage self) public view returns (int128) { return p_min(self).sqrt(); }
EvolvingProteus.sol has used abdk-library ABDKMath64x64.sol in contract. It has used an old version which is confirmed from package.json and found to be v3.0.0 which is an 2 year old version. When using external libraries in contracts, security is utmost important and use of latest version is recommended.
Update the abdk-libraries version to v3.2
withdrawGivenInputAmount()
as it uses FEE_DOWN
In EvolvingProteus.sol
, withdrawGivenInputAmount()
has used FEE_DOWN
in function which can be checked here, however the Natspec incorrectly mentions the use of FEE_UP
which can be checked here.
/** * @dev Given an input amount of the LP token, we compute an amount of * a reserve token that must be output to decrease the pool's utility in * proportion to the pool's decrease in total supply of the LP token. - * @dev We use FEE_UP because we want to increase the perceived amount of - * reserve tokens leaving the pool and to increase the observed amount of - * LP tokens being burned. + * @dev We use FEE_DOWN because we want to decrease the perceived amount of + * reserve tokens leaving the pool and to decrease the observed amount of + * LP tokens being burned. */ function withdrawGivenInputAmount(
MIN_PRICE_VALUE
calculationIn EvolvingProteus.sol, There is misleading comment on MIN_PRICE_VALUE
which should be corrected per recommendation.
@notice - The minimum price value calculated with abdk library equivalent to 10^12(wei) + The minimum price value calculated with abdk library equivalent to 10^10(wei) */ int256 constant MIN_PRICE_VALUE = 184467440737;
#0 - c4-pre-sort
2023-08-30T04:11:38Z
0xRobocop marked the issue as sufficient quality report
#1 - 0xRobocop
2023-08-30T04:13:50Z
L-05 may be a dup of #227
#2 - c4-judge
2023-09-11T19:41:14Z
JustDravee marked the issue as grade-a
#3 - c4-judge
2023-09-11T23:02:41Z
JustDravee marked the issue as selected for report
#4 - c4-judge
2023-09-13T13:21:37Z
JustDravee marked the issue as not selected for report
#5 - 0xRizwan
2023-09-14T05:10:08Z
Hi @JustDravee
Thanks for the efforts and quick judging the contest. Really appreciate it.
I agree with judging of this report but i would like to highlight one issue as below,
L-01- Failed assertion inside divuu() function affecting the divu() functionality in EvolvingProteus.sol
. This issue has arised to due to buggy and broken library functions used which is basically failing on assetion inside the divuu()
.
This issue has been accepted by abdk libraries and seems to be fixed in latest version. This can be checked here. This was a major change in abdk libraries.
I see this issue has not been raised by any other reports and i believe its breaking protocol functionality wherever divuu()
used in divu()
which is used in shell protocol contracts functions.
Per code4rena Medium defination, I believe this could be a Medium.
2 ā Med: Assets not at direct risk, but the function of the protocol or its availability could be impacted, or leak value with a hypothetical attack path with stated assumptions, but external requirements.
I would like to know your thought on L-01 issue though i respect your judging decision.
Thank you!