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
Rank: 22/74
Findings: 2
Award: $81.25
🌟 Selected for report: 1
🚀 Solo Findings: 0
🌟 Selected for report: 0xprinc
Also found by: 0x11singh99, 0xAnah, 0xWaitress, 0xkazim, 2997ms, 33audits, 404Notfound, 8olidity, CRIMSON-RAT-REACH, CyberPunks, DanielWang888, Deekshith99, Eeyore, Eurovickk, Inspecktor, JGcarv, John, Jorgect, Kaysoft, LosPollosHermanos, MohammedRizwan, Qeew, QiuhaoLi, Rolezn, TheSavageTeddy, Topmark, Trust, Udsen, a3yip6, alexzoid, bigtone, codegpt, erebus, fatherOfBlocks, ginlee, glcanvas, hunter_w3b, josephdara, kaveyjoe, kutugu, mahdirostami, max10afternoon, oakcobalt, peanuts, pfapostol, ptsanev, qpzm, radev_sw, ravikiranweb3, sces60107, seth_lawson, te_aut, twcctop, zhaojie, ziyou-
22.777 USDC - $22.78
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
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()); }
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
reserveJBefore
in Well.sol/_swapFrom()
and alsoreserveIBefore
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
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
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
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();
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 timesRecomendation : 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
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
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
MultiFlowPump.sol/_capReserve()
https://github.com/code-423n4/2023-07-basin/blob/main/src/pumps/MultiFlowPump.sol#L210
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
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
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
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.
🌟 Selected for report: SM3_SS
Also found by: 0x11singh99, 0xAnah, 0xSmartContract, 0xn006e7, 0xprinc, DavidGiladi, ElCid, JCN, K42, MIQUINHO, Raihan, Rolezn, SAAJ, SY_S, Strausses, TheSavageTeddy, bigtone, erebus, hunter_w3b, josephdara, lsaudit, mahdirostami, oakcobalt, peanuts, pfapostol, seth_lawson
58.4732 USDC - $58.47
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