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: 14/43
Findings: 3
Award: $441.46
🌟 Selected for report: 1
🚀 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
result
require block is inconsistent with NatSpec commentlibusb
dependency can be a security riskresult
require block is inconsistent with NatSpec commentresult
require block and Natspec comment are inconsistent, correct it if the error is caused by the comment here, if the formula is incorrect, this is an important issue
src\proteus\EvolvingProteus.sol: 271 */ 272: function swapGivenInputAmount( 273: uint256 xBalance, 274: uint256 yBalance, 275: uint256 inputAmount, 276: SpecifiedToken inputToken 277: ) external view returns (uint256 outputAmount) { 278: // input amount validations against the current balance 279: require( 280: inputAmount < INT_MAX && xBalance < INT_MAX && yBalance < INT_MAX 281: ); 282: 283: _checkAmountWithBalance( 284: (inputToken == SpecifiedToken.X) ? xBalance : yBalance, 285: inputAmount 286: ); 287: 288: int256 result = _swap( 289: FEE_DOWN, 290: int256(inputAmount), 291: int256(xBalance), 292: int256(yBalance), 293: inputToken 294: ); 295: // amount cannot be less than 0 296: require(result < 0); // @audit => NatSpec comment and require is inconsistent 297: 298: // output amount validations against the current balance 300: outputAmount = uint256(-result); 301: _checkAmountWithBalance( 302: (inputToken == SpecifiedToken.X) ? yBalance : xBalance, 303: outputAmount 304: ); 305: }
libusb
dependency can be a security riskWhen the libusb
dependency is checked from the npm site, it does not provide any references, links to github or versions, creates a malicious dependency security risk, I recommend checking it and documenting what it serves
https://www.npmjs.com/package/libusb?activeTab=readme
package.json: 26: }, 27: "dependencies": { 28: "libusb": "^0.0.0-pre" 29: } 30 }
In the NatSpec comment, x price should be less than y price. But in the formula there is also in the equation
src\proteus\EvolvingProteus.sol: 253 254: // at all times x price should be less than y price 255: if (py_init <= px_init) revert InvalidPrice(); 256: if (py_final <= px_final) revert InvalidPrice();
According to the scope information of the project, it is stated that it be used Layer2 Arbitrum
README.md: Which blockchains will this code be deployed to, and are considered in scope for this audit?: Arbitrum
The problem with this is that Arbitrum is Compatible with 0.8.20 and newer. Contracts compiled with these versions will result in a non-functional or potentially damaged version that does not behave as expected.
Although the project was compiled with 0.8.10, in a possible live deploy time, it may be compiled with a different compile version and this may cause it to not work on the Arbitrum network, this risk should be documented and included in the project's deploy checklist
At the start of the project, the system may need to be stopped or upgraded, I suggest you have a script beforehand and add it to the documentation. This can also be called an " EMERGENCY STOP (CIRCUIT BREAKER) PATTERN ".
https://github.com/maxwoe/solidity_patterns/blob/master/security/EmergencyStop.sol
Use event-emit when setting the startup items in the project's constructor.
This is recommended so that Web3 Dapps and Analysis tools can monitor the set data and the project.
src\proteus\EvolvingProteus.sol: 242 */ 243: constructor( 244: int128 py_init, 245: int128 px_init, 246: int128 py_final, 247: int128 px_final, 248: uint256 duration 249: ) { 250: // price value checks 251: if (py_init >= MAX_PRICE_VALUE || py_final >= MAX_PRICE_VALUE) revert MaximumAllowedPriceExceeded(); 252: if (px_init <= MIN_PRICE_VALUE || px_final <= MIN_PRICE_VALUE) revert MinimumAllowedPriceExceeded(); 253: 254: // at all times x price should be less than y price 255: if (py_init <= px_init) revert InvalidPrice(); 256: if (py_final <= px_final) revert InvalidPrice(); 257: 258: // max. price ratio check 259: if (py_init.div(py_init.sub(px_init)) > ABDKMath64x64.divu(uint(MAX_PRICE_RATIO), 1)) revert MaximumAllowedPriceRatioExceeded(); 260: if (py_final.div(py_final.sub(px_final)) > ABDKMath64x64.divu(uint(MAX_PRICE_RATIO), 1)) revert MaximumAllowedPriceRatioExceeded(); 261: 262: config = LibConfig.newConfig(py_init, px_init, py_final, px_final, duration); 263: }
#0 - c4-pre-sort
2023-08-30T04:39:07Z
0xRobocop marked the issue as high quality report
#1 - c4-sponsor
2023-09-01T18:58:14Z
ishaansinghal (sponsor) confirmed
#2 - c4-judge
2023-09-11T19:39:25Z
JustDravee marked the issue as grade-a
🌟 Selected for report: lsaudit
Also found by: 0x11singh99, 0x4non, 0xAnah, 0xSmartContract, 0xhacksmithh, JP_Courses, Jorgect, MrPotatoMagic, Sathish9098, epistkr, pfapostol, pontifex
22.4575 USDC - $22.46
The project is generally efficient in terms of gas optimizations, many generally accepted gas optimizations have been implemented, gas optimizations with minor effects are already mentioned in automatic finding, but gas optimizations will not be a priority considering code readability and code base size
Gas Optimization Recommendations
1- The highest gas expenditure in the project occurs when creating pool instances, if wish the architecture here was design like the singleton architecture in UniswapV4, gas savings will be close to 90%.
2- The most important gas usage of the contract subject to the audit is the ABDKMath64x64.sol
library that it uses. More gas optimized prb-math may be preferred
detailed gas comparisons are available on the project's github link
Gas estimations based on the v2.0.1 and the v3.0.0 releases.
SD59x18 | Min | Max | Avg | UD60x18 | Min | Max | Avg | |
---|---|---|---|---|---|---|---|---|
abs | 68 | 72 | 70 | n/a | n/a | n/a | n/a | |
avg | 95 | 105 | 100 | avg | 57 | 57 | 57 | |
ceil | 82 | 117 | 101 | ceil | 78 | 78 | 78 | |
div | 431 | 483 | 451 | div | 205 | 205 | 205 | |
exp | 38 | 2797 | 2263 | exp | 1874 | 2742 | 2244 | |
exp2 | 63 | 2678 | 2104 | exp2 | 1784 | 2652 | 2156 | |
floor | 82 | 117 | 101 | floor | 43 | 43 | 43 | |
frac | 23 | 23 | 23 | frac | 23 | 23 | 23 | |
gm | 26 | 892 | 690 | gm | 26 | 893 | 691 | |
inv | 40 | 40 | 40 | inv | 40 | 40 | 40 | |
ln | 463 | 7306 | 4724 | ln | 419 | 6902 | 3814 | |
log10 | 104 | 9074 | 4337 | log10 | 503 | 8695 | 4571 | |
log2 | 377 | 7241 | 4243 | log2 | 330 | 6825 | 3426 | |
mul | 455 | 463 | 459 | mul | 219 | 275 | 247 | |
pow | 64 | 11338 | 8518 | pow | 64 | 10637 | 6635 | |
powu | 293 | 24745 | 5681 | powu | 83 | 24535 | 5471 | |
sqrt | 140 | 839 | 716 | sqrt | 114 | 846 | 710 |
Gas estimations based on the v3.0 release of ABDKMath. See my abdk-gas-estimations repo.
Method | Min | Max | Avg |
---|---|---|---|
abs | 88 | 92 | 90 |
avg | 41 | 41 | 41 |
div | 168 | 168 | 168 |
exp | 77 | 3780 | 2687 |
exp2 | 77 | 3600 | 2746 |
gavg | 166 | 875 | 719 |
inv | 157 | 157 | 157 |
ln | 7074 | 7164 | 7126 |
log2 | 6972 | 7062 | 7024 |
mul | 111 | 111 | 111 |
pow | 303 | 4740 | 1792 |
sqrt | 129 | 809 | 699 |
#0 - c4-pre-sort
2023-08-30T03:43:54Z
0xRobocop marked the issue as sufficient quality report
#1 - JustDravee
2023-09-11T20:10:21Z
To me it seems that these tables prove that ABDKMaths is most often the right choice. Nice that it was mentioned in the analysis report too. However it failed to be precise enough or talk about some big savings we've seen in other reports for the codebase so I can only accept this as rank B given the unique take on gas savings
#2 - c4-judge
2023-09-11T20:10:26Z
JustDravee marked the issue as grade-b
🌟 Selected for report: 0xSmartContract
Also found by: 0xmystery, Udsen, carrotsmuggler, catellatech, ihtishamsudo, moneyversed, oakcobalt, pfapostol, plainshift, rjs
321.7538 USDC - $321.75
List | Head | Details |
---|---|---|
a) | The approach I followed when reviewing the code | Stages in my code review and analysis |
b) | Analysis of the code base | What is unique? How are the existing patterns used? |
c) | Test analysis | Test scope of the project and quality of tests |
d) | Centralization risks | How was the risk of centralization handled in the project, what could be alternatives? |
e) | Systemic risks | Potential systemic risks in the project |
f) | Competition analysis | What are similar projects? |
g) | Security Approach of the Project | Audit approach of the Project |
h) | Other Audit Reports and Automated Findings | What are the previous Audit reports and their analysis |
i) | Gas Optimization | Gas usage approach of the project and alternative solutions to it |
j) | Other recommendations | What is unique? How are the existing patterns used? |
k) | New insights and learning from this audit | Things learned from the project |
First, by examining the scope of the code, I determined my code review and analysis strategy. https://github.com/code-423n4/2023-08-shell
Accordingly, I analyzed and audited the subject in the following steps;
Number | Stage | Details | Information |
---|---|---|---|
1 | Compile and Run Test | Installation | Test and installation structure is simple, cleanly designed |
2 | Architecture Review | The Proteus-AMM explainer provides a high-level overview of the Project system and the describe the core components. | Provides a basic architectural teaching for General Architecture |
3 | Graphical Analysis | Graphical Analysis with Solidity-metrics | A visual view has been made to dominate the general structure of the codes of the project. |
4 | Slither Analysis | Slither Report | The project does not currently have a slither result, a slither control was created from scratch |
5 | Test Suits | Tests | In this section, the scope and content of the tests of the project are analyzed. |
6 | Manuel Code Review | Scope | Top-down analysis of codes according to architectural design, IDE used: VsCode |
7 | Project White Paper | WhitePaper | |
8 | Infographic | Figma | I made Visual drawings to understand the hard-to-understand mechanisms |
9 | Special focus on Areas of Concern | Areas of Concern | Evolving Proteus's algorithm has six parameters that determine liquidity concentration |
Invariant tests can be great tools for shaking out invalid assumptions, complex edge cases, and unexpected interactions in a smart contract system. But it can also be challenging to channel the fuzzer's unconstrained chaos into a suite of meaningful, reliable tests.
Number | Head | Test Details |
---|---|---|
1) | Token balance check | The differences in pool token balances after a swap is same as the differences in user token balances after factoring in the fee |
2) | Token supply check | Utility & utility/lp token supply does not decrease after swap |
3) | Deposit check | For a deposit, utility will always increase, and util/lp does not decrease |
4) | Withdraw check | For a withdraw, utility will always decrease, and util/lp does not decrease |
5) | Soft invariant | x price decreases over time & y price stays constant |
6) | Soft invariant | when x price increases over time & y price stays constant |
7) | Soft invariant | when y price decreases over time & x price stays constant |
8) | Soft invariant | when y price increases over time & x price stays constant |
9) | Soft invariant | when x & y prices both increase with time |
10) | Soft invariant | when x & y prices both decrease with time |
11) | Soft invariant | when x & y prices both stay constant |
Number | Head | Test Details |
---|---|---|
1) | Soft invariant | when x price increases over time & y price decrease |
2) | Soft invariant | when y price increases over time & x price decreases |
There is no centrality risk in the controlled scope.
We can talk about a systemic risk here because there are some Layer2 special cases. If Arbitrum is compile Compatible with 0.8.20 and newer. Contracts compiled with these versions will result in a non-functional or potentially damaged version that does not behave as expected. The default behavior of the compiler will be to use the latest version which means it will compile with version 0.8.20 which will produce broken code by default.
According to the given code, this problem does not exist, but it should be taken care of while deploying. <br />
Other projects with a similar structure to the project; 1 - dfx finance
2- Gamma
3- Osmosis
However, with its mathematical modeling, the Shell Protocol is unique.
1- Most important security point of Shell protocol is contracts are non-custodial, meaning NOBODY (not even the core team or the Shell DAO) is able to access the funds held in any of the core contracts.
2- Proteus Pool Safeguards System ; A pool's deployer can assign a wallet the ability to freeze the pool in case of an emergency. LPs may still withdraw their tokens, but swaps and deposits are disabled. The Shell core team controls a 2/3 multi-signature wallet, the ShellMultiSig, that can freeze trading on Proteus pools assigned to it.
3- On-Chain Monitoring System ; Shell conducts on-chain security monitoring with Forta. Anyone can subscribe to updates from the Shell Forta bot. This bot tracks Shell transactions in which wrapping, unwrapping, swapping, depositing, or withdrawals occur over a threshold amount. If transactions occur with unusually high token amounts, the bot sends out an alert. https://app.forta.network/bot/0x7f9afc392329ed5a473bcf304565adf9c2588ba4bc060f7d215519005b8303e3
4- First they did the main audit from a reputable auditing organization like Trail of Bits and resolved all the security concerns in the report https://github.com/trailofbits/publications/blob/master/reviews/ShellProtocolv2.pdf
5- They manage the 2nd audit process with an innovative audit such as Code4rena, in which many auditors examine the codes.
6- They was set the $ 100,000 ImmuneFi reward https://immunefi.com/bounty/shellprotocol/
1- By distributing the project to testnets, ensuring that the audits are carried out in onchain audit. (This will increase coverage)
2- After the project is published on the mainnet, there should be emergency action plans (not found in the documents)
3- No Pause Mechanism This is a chaotic situation, which can be thought of as a choice between decentralization and security. Having a pause mechanism makes sense in order not to damage user funds in case of a possible problem in the project.
4- No Upgradability There are use cases of the Upgradable pattern in defi projects using mathematical models, but it is a design and security option.
Automated Findings: https://github.com/code-423n4/2023-08-shell/blob/main/bot-report.md Especially Low detections in the Automated Finding Report should be taken into account;
Other Audit Reports (TrailOfBits):
Here is a summary of the issues found in the audit report with Exposure Anlysis and Category details: Audit Report TrailOfBits <img width="654" alt="image" src="https://github.com/code-423n4/2023-08-shell/assets/104318932/422c099c-7b57-4493-826e-6885fc1f20d8">
The project is generally efficient in terms of gas optimizations, many generally accepted gas optimizations have been implemented, gas optimizations with minor effects are already mentioned in automatic finding, but gas optimizations will not be a priority considering code readability and code base size
Gas Optimization Recommendations
1- The highest gas expenditure in the project occurs when creating pool instances, if wish the architecture here was design like the singleton architecture in UniswapV4, gas savings will be close to 90%.
2- The most important gas usage of the contract subject to the audit is the ABDKMath64x64.sol
library that it uses. More gas optimized prb-math may be preferred
detailed gas comparisons are available on the project's github link
Gas estimations based on the v2.0.1 and the v3.0.0 releases.
SD59x18 | Min | Max | Avg | UD60x18 | Min | Max | Avg | |
---|---|---|---|---|---|---|---|---|
abs | 68 | 72 | 70 | n/a | n/a | n/a | n/a | |
avg | 95 | 105 | 100 | avg | 57 | 57 | 57 | |
ceil | 82 | 117 | 101 | ceil | 78 | 78 | 78 | |
div | 431 | 483 | 451 | div | 205 | 205 | 205 | |
exp | 38 | 2797 | 2263 | exp | 1874 | 2742 | 2244 | |
exp2 | 63 | 2678 | 2104 | exp2 | 1784 | 2652 | 2156 | |
floor | 82 | 117 | 101 | floor | 43 | 43 | 43 | |
frac | 23 | 23 | 23 | frac | 23 | 23 | 23 | |
gm | 26 | 892 | 690 | gm | 26 | 893 | 691 | |
inv | 40 | 40 | 40 | inv | 40 | 40 | 40 | |
ln | 463 | 7306 | 4724 | ln | 419 | 6902 | 3814 | |
log10 | 104 | 9074 | 4337 | log10 | 503 | 8695 | 4571 | |
log2 | 377 | 7241 | 4243 | log2 | 330 | 6825 | 3426 | |
mul | 455 | 463 | 459 | mul | 219 | 275 | 247 | |
pow | 64 | 11338 | 8518 | pow | 64 | 10637 | 6635 | |
powu | 293 | 24745 | 5681 | powu | 83 | 24535 | 5471 | |
sqrt | 140 | 839 | 716 | sqrt | 114 | 846 | 710 |
Gas estimations based on the v3.0 release of ABDKMath. See my abdk-gas-estimations repo.
Method | Min | Max | Avg |
---|---|---|---|
abs | 88 | 92 | 90 |
avg | 41 | 41 | 41 |
div | 168 | 168 | 168 |
exp | 77 | 3780 | 2687 |
exp2 | 77 | 3600 | 2746 |
gavg | 166 | 875 | 719 |
inv | 157 | 157 | 157 |
ln | 7074 | 7164 | 7126 |
log2 | 6972 | 7062 | 7024 |
mul | 111 | 111 | 111 |
pow | 303 | 4740 | 1792 |
sqrt | 129 | 809 | 699 |
Logic similar to singleton pattern similar to Uniswapv4 can be used in a project, this is a gas-optimized and innovative solution (Expressed for the overall project, not for the audit contract)
The use of assembly in project codes is very low, I especially recommend using such useful and gas-optimized code patterns; https://github.com/dragonfly-xyz/useful-solidity-patterns/tree/main/patterns/assembly-tricks-1
It is seen that the latest versions of imported important libraries such as Openzeppelin are not used in the project codes, it should be noted. https://security.snyk.io/package/npm/@openzeppelin%2Fcontracts/
A good model can be used to systematically assess the risk of the project, for example this modeling is recommended; https://www.notion.so/Smart-Contract-Risk-Assessment-3b067bc099ce4c31a35ef28b011b92ff#7770b3b385444779bf11e677f16e101e
Here are my other suggestions for corrections, the details of which are in my QA Report (I didn't want to write it here again)
result
require block is inconsistent with NatSpec commentlibusb
dependency can be a security riskForkEvolvingProteus.t.sol
invariant tests are extensive, quality invariant tests in a high-mathematical computational project are remarkable, the project developers did a great jobABDKMath64x64.sol
library13 hours
#0 - c4-pre-sort
2023-08-31T05:32:51Z
0xRobocop marked the issue as high quality report
#1 - 0xRobocop
2023-08-31T05:40:43Z
In my point of view, although the report does not touch a core area of concern specific to the code like #69. The report is pretty complete in terms of security as an holistic approach.
#2 - viraj124
2023-09-04T07:00:28Z
few observations
regarding the invariant not test when prices move in opposite directions the reason for that is the behaviour is not consistent hence we kept that out of scope for the audit & we won't be using that price configuration in the near future
Regarding singleton behaviour, all our accounting for all different pools is done in the ocean so that compensates for deploying different contracts for each pool that being said we might change that in the future if needed but for now due to the architecture of the ocean and for us to support more defi primitives like lending and option markets and not just be limited to amm's we decided not to go with the singleton pool deployment approach
#3 - c4-sponsor
2023-09-04T07:00:35Z
viraj124 (sponsor) acknowledged
#4 - c4-judge
2023-09-11T20:21:29Z
JustDravee marked the issue as grade-a
#5 - c4-judge
2023-09-11T23:02:56Z
JustDravee marked the issue as selected for report