Basin - Udsen'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: 67/74

Findings: 1

Award: $6.07

QA:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

Lines of code

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

Vulnerability details

Impact

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()

Proof of Concept

    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

Tools Used

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.

Assessed type

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

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