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: 67/74
Findings: 1
Award: $6.07
🌟 Selected for report: 0
🚀 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-
6.0655 USDC - $6.07
https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L413-L444
In the Well._addLiquidity()
function there is no check on array length equality between tokenAmountsIn
array and the _tokens
array. Since the _addLiquidity
function uses for
loop to iterate through the array elements of both tokenAmountsIn
and _tokens
arrays, any array length mismatch could revert the transaction during execution. Hence this would waste lot of gas for the user. Hence user will lose funds as a result.
The same vulnerability can be seen in the following functions as well.
Well.removeLiquidity()
Well.removeLiquidityImbalanced()
function _addLiquidity( uint256[] memory tokenAmountsIn, uint256 minLpAmountOut, address recipient, bool feeOnTransfer ) internal returns (uint256 lpAmountOut) { IERC20[] memory _tokens = tokens(); uint256[] memory reserves = _updatePumps(_tokens.length); if (feeOnTransfer) { for (uint256 i; i < _tokens.length; ++i) { if (tokenAmountsIn[i] == 0) continue; tokenAmountsIn[i] = _safeTransferFromFeeOnTransfer(_tokens[i], msg.sender, tokenAmountsIn[i]); reserves[i] = reserves[i] + tokenAmountsIn[i]; } } else { for (uint256 i; i < _tokens.length; ++i) { if (tokenAmountsIn[i] == 0) continue; _tokens[i].safeTransferFrom(msg.sender, address(this), tokenAmountsIn[i]); reserves[i] = reserves[i] + tokenAmountsIn[i]; } } lpAmountOut = _calcLpTokenSupply(wellFunction(), reserves) - totalSupply(); if (lpAmountOut < minLpAmountOut) { revert SlippageOut(lpAmountOut, minLpAmountOut); } _mint(recipient, lpAmountOut); _setReserves(_tokens, reserves); emit AddLiquidity(tokenAmountsIn, lpAmountOut, recipient); }
https://github.com/code-423n4/2023-07-basin/blob/main/src/Well.sol#L413-L444
Manual Review and VSCode
Hence it is recommended to add the array length check between above mentioned tokenAmountsIn
and _tokens
arrays at the beginning of the _addLiquidity
function. So that, in the event of an array length mismatch the transaction will revert at the very beginning before going into for
loop execution. This will save the user on gas wastage.
Invalid Validation
#0 - c4-pre-sort
2023-07-11T09:18:05Z
141345 marked the issue as primary issue
#1 - c4-pre-sort
2023-07-11T09:24:07Z
141345 marked the issue as low quality report
#2 - c4-judge
2023-08-03T21:21:40Z
alcueca changed the severity to QA (Quality Assurance)
#3 - alcueca
2023-08-05T10:16:00Z
Just checking that arrays passed as parameter are of the right length is nice DevEx, but that's it.
#4 - c4-judge
2023-08-05T10:16:05Z
alcueca marked the issue as grade-b