Lucene search

K
code423n4Code4renaCODE423N4:2022-12-STEALTH-PROJECT-FINDINGS-ISSUES-112
HistoryJan 22, 2023 - 12:00 a.m.

Upgraded Q -> M from #100 [1674425909347]

2023-01-2200:00:00
Code4rena
github.com
2
issue 100
vulnerability impact
proof of concept
mitigation steps
code review.

Judge has assessed an item in Issue #100 as M risk. The relevant finding follows:

Lines of code
<https://github.com/code-423n4/2022-12-Stealth-Project/blob/fc8589d7d8c1d8488fd97ccc46e1ff11c8426ac2/maverick-v1/contracts/libraries/Bin.sol#L35&gt;
<https://github.com/code-423n4/2022-12-Stealth-Project/blob/fc8589d7d8c1d8488fd97ccc46e1ff11c8426ac2/maverick-v1/contracts/libraries/Bin.sol#L38&gt;

Vulnerability details
Impact
The wrong amount of LP tokens will be minted and the wrong amount of A/B tokens will be deposited.

Proof of Concept
According to the PDF document provided, the number of LP tokens newSupply is calculated using the Table 1 as belows.
Imgur

This is implemented in the function lpTokensFromDeltaReserve() of Bin.sol as belows.

function lpTokensFromDeltaReserve(
    Bin.Instance storage self,
    uint256 _deltaA,
    uint256 _deltaB,
    int32 _activeLowerTick,
    uint256 _existingReserveA,
    uint256 _existingReserveB
) internal view returns (uint256 deltaAOptimal, uint256 deltaBOptimal, uint256 proRataLiquidity) {
    deltaAOptimal = _deltaA;
    deltaBOptimal = _deltaB;
    bool noA = self.state.reserveA == 0;
    bool noB = self.state.reserveB == 0;

    if (self.state.lowerTick &lt; _activeLowerTick || (!noA && noB)) {//@audit case p&lt;p_l, the inequality should be opposite side
        deltaBOptimal = 0;
        proRataLiquidity = noA || self.state.totalSupply == 0 ? deltaAOptimal : Math.mulDiv(deltaAOptimal, self.state.totalSupply, self.state.reserveA, false);
    } else if (self.state.lowerTick &gt; _activeLowerTick || (noA && !noB)) {//@audit case p&gt;p_u, the inequality should be opposite side
        deltaAOptimal = 0;
        proRataLiquidity = noB || self.state.totalSupply == 0 ? deltaBOptimal : Math.mulDiv(deltaBOptimal, self.state.totalSupply, self.state.reserveB, false);
    } else {
        if (_existingReserveA &gt; 0) {
            deltaBOptimal = Math.mulDiv(_existingReserveB, _deltaA, _existingReserveA, false);
        }
        if (deltaBOptimal &gt; _deltaB && _existingReserveB &gt; 0) {
            deltaAOptimal = Math.mulDiv(_existingReserveA, _deltaB, _existingReserveB, false);
            deltaBOptimal = _deltaB;
        }

        proRataLiquidity = (noA && noB) || self.state.totalSupply == 0
            ? Math.max(deltaAOptimal, deltaBOptimal)
            : Math.min(Math.mulDiv(deltaAOptimal, self.state.totalSupply, self.state.reserveA, false), Math.mulDiv(deltaBOptimal, self.state.totalSupply, self.state.reserveB, false));
    }
}

The implementation uses wrong inequalities for the edge cases $p\lt p_l$ and $p\gt p_u$.

Tools Used
Manual Review

Recommended Mitigation Steps
Reverse the inequalities at Bin.sol#L35 and Bin.sol#L38.


The text was updated successfully, but these errors were encountered:

All reactions