Basin - 0xprinc's results

A composable EVM-native decentralized exchange protocol.

General Information

Platform: Code4rena

Start Date: 03/07/2023

Pot Size: $40,000 USDC

Total HM: 14

Participants: 74

Period: 7 days

Judge: alcueca

Total Solo HM: 9

Id: 259

League: ETH

Basin

Findings Distribution

Researcher Performance

Rank: 22/74

Findings: 2

Award: $81.25

QA:
grade-a
Gas:
grade-a

🌟 Selected for report: 1

🚀 Solo Findings: 0

1. No need to write Aquifer.sol/wellImplementation() getter function instead make the mapping wellImplementations as a public state variable.

wellImplementations : https://github.com/code-423n4/2023-07-basin/blob/main/src/Aquifer.sol#L25 Aquifer.sol/wellImplementation() : https://github.com/code-423n4/2023-07-basin/blob/main/src/Aquifer.sol#L86

2. No need to introduce a new local variable in this function Well.sol/tokens(), directly return the tokens array.

This is the optimised code https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L84

    function tokens() public pure returns (IERC20[] memory) {         
        return _getArgIERC20Array(LOC_VARIABLE, numberOfTokens());
    }

3. Well.sol/_swapFrom() function using the some lines of code same as written in another function getSwapOut(), which is increasing the codesize and deployment cost, instead call the function getSwapOut() inside the _swapFrom()

https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L222C9-L228C80 https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L246C9-L253C92

4. No need to introduce a new variable named as reserveJBefore in Well.sol/_swapFrom() and also

reserveIBefore in Well.sol/swapTo() We can just use

amountOut  = reserve[j] - (_calcReserve(...))

and

amountIn = (_calcReserve(...)) - reserve[i];

https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L227 https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L277

5. Well.sol/swapTo() function using the some lines of code same as written in another function getSwapIn(), which is increasing the codesize and deployment cost, instead call the function getSwapIn() inside swapTo()

https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L272C9-L278C80 https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L312C9-L318C91

6. Function Well.sol/_getIJ() will always revert for two equal token addresses due to an if-else condition.

https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L742

Rather change the else if to if

7. In MultiFlowPump.sol/update() use slot.readLastReserves() to get the value of numberOfReserves instead of using reserves.length

https://github.com/code-423n4/2023-07-basin/blob/main/src/pumps/MultiFlowPump.sol#L73C9-L80C87

A better version of update() function can be this

    function update(uint256[] calldata reserves, bytes calldata) external {
        PumpState memory pumpState;

        // All reserves are stored starting at the msg.sender address slot in storage.
        bytes32 slot = _getSlotForAddress(msg.sender);

        // Read: Last Timestamp & Last Reserves
        (uint256 numberOfReserves , pumpState.lastTimestamp, pumpState.lastReserves) = slot.readLastReserves();

8. The non-zero reserve condition is used in MultiFlowPump.sol/_init() and MultiFlowPump.sol/update(). Since _init() function is called by only upadate() function, this will be waste to check this same validation two times

Recomendation : remove any of these check occurence.

https://github.com/code-423n4/2023-07-basin/blob/main/src/pumps/MultiFlowPump.sol#L86 https://github.com/code-423n4/2023-07-basin/blob/main/src/pumps/MultiFlowPump.sol#L153

9. Can use numberOfReserves instead of byteReserves.length, this saves the calculation of bytesReserves.length in MultiFlowPump.sol/_init()

https://github.com/code-423n4/2023-07-basin/blob/main/src/pumps/MultiFlowPump.sol#L162

10. MultiFlowPump.sol/_capReserve() can be set as a pure function since this doesn't view any state of chain.

https://github.com/code-423n4/2023-07-basin/blob/main/src/pumps/MultiFlowPump.sol#L199

11. Minor typo in commenting in MultiFlowPump.sol/_capReserve()

https://github.com/code-423n4/2023-07-basin/blob/main/src/pumps/MultiFlowPump.sol#L210

12. Better to declare the return variable as emaReserves instead of reserves as it gives more information about the return value in MultiFlowPump.sol/readLastInstantaneousReserves()

https://github.com/code-423n4/2023-07-basin/blob/main/src/pumps/MultiFlowPump.sol#L222

13. updating lastReserves[i] by using _capReserves() is not consistent in functions MultiFlowPump.sol/readInstantaneousReserves() and MultiFlowPump.sol/update()

https://github.com/code-423n4/2023-07-basin/blob/main/src/pumps/MultiFlowPump.sol#L119 https://github.com/code-423n4/2023-07-basin/blob/main/src/pumps/MultiFlowPump.sol#L256

14. Better to declare the return variable as cumulativeReserves instead of reserves as it gives more information about the return value in MultiFlowPump.sol/readLastCumulativeReserves()

https://github.com/code-423n4/2023-07-basin/blob/main/src/pumps/MultiFlowPump.sol#L267

15. No need to introduce a new local variable in this function MultiFlowPump.sol/readCumulativeReserves(), directly return the tokens array.

https://github.com/code-423n4/2023-07-basin/blob/main/src/pumps/MultiFlowPump.sol#L280

directly return using

    return abi.encode(byteCumulativeReserves);

#0 - c4-pre-sort

2023-07-13T14:18:40Z

141345 marked the issue as high quality report

#1 - c4-sponsor

2023-08-03T17:01:14Z

publiuss marked the issue as sponsor confirmed

#2 - c4-judge

2023-08-05T10:36:17Z

alcueca marked the issue as grade-a

#3 - c4-judge

2023-08-05T20:40:41Z

alcueca marked the issue as selected for report

#4 - alcueca

2023-08-11T20:02:32Z

4 seems invalid. 6 actually protects the protocol from same-token issues. The sponsor accepted making this explicit in the documentation, at least.

#5 - publiuss

2023-08-23T23:39:52Z

For reference: 1 No remediation 2 No remediation 3 No remediation 4 No remediation 5 No remediation 6 Added Documentation 7 No remediation 8 Addressed 9 Somewhat Addressed 10 No remediation 11 Addressed 12 Addressed 13 No remediation - This is intentional 14 Addressed 15 No remediation

#6 - PaperParachute

2023-09-12T17:17:02Z

Just a note that C4 is excluding the invalid entries from the official report. In this case part 4. For this reason I have edited the sponsors comment below the findings to be numbered 1 through 14 with 4 excluded as well so it makes sense.

Awards

58.4732 USDC - $58.47

Labels

bug
G (Gas Optimization)
grade-a
low quality report
G-04

External Links

1. Directly write 0 instead of n in LibLastReserveBytes.sol/readLastReserves(bytes32), this will save gas of one MLOAD operation.

https://github.com/code-423n4/2023-07-basin/blob/main/src/libraries/LibLastReserveBytes.sol#L80

#0 - c4-pre-sort

2023-07-12T07:33:09Z

141345 marked the issue as low quality report

#1 - c4-judge

2023-08-05T11:31:51Z

alcueca marked the issue as grade-a

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