Shell Protocol - MohammedRizwan's results

A set of EVM-based smart contracts on Arbitrum One. In a nutshell it is DeFi made simple.

General Information

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

Shell Protocol

Findings Distribution

Researcher Performance

Rank: 19/43

Findings: 1

Award: $97.25

QA:
grade-a

🌟 Selected for report: 0

šŸš€ Solo Findings: 0

Awards

97.2487 USDC - $97.25

Labels

bug
grade-a
QA (Quality Assurance)
sufficient quality report
Q-17

External Links

Summary

Low Risk Issues

NumberIssueInstances
[L‑01]Failed assertion inside divuu() function affecting the divu() functionality in EvolvingProteus.sol3
[L‑02]Misleading comment on function b() calculation1
[L‑03]Use of outdated version of abdk-library1
[L‑04]Misleading comment on withdrawGivenInputAmount() as it uses FEE_DOWN1
[L‑05]Misleading comment on MIN_PRICE_VALUE calculation1

[L‑01] Failed assertion inside 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.

[L‑02] Misleading comment on function b() calculation

There 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();
    }

[L‑03] Use of outdated version of abdk-library

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

[L‑04] Misleading comment on 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(

[L‑05] Misleading comment on MIN_PRICE_VALUE calculation

In 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!

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax Ā© 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter