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>
<https://github.com/code-423n4/2022-12-Stealth-Project/blob/fc8589d7d8c1d8488fd97ccc46e1ff11c8426ac2/maverick-v1/contracts/libraries/Bin.sol#L38>
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 < _activeLowerTick || (!noA && noB)) {//@audit case p<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 > _activeLowerTick || (noA && !noB)) {//@audit case p>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 > 0) {
deltaBOptimal = Math.mulDiv(_existingReserveB, _deltaA, _existingReserveA, false);
}
if (deltaBOptimal > _deltaB && _existingReserveB > 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