Platform: Code4rena
Start Date: 27/11/2023
Pot Size: $60,500 USDC
Total HM: 7
Participants: 72
Period: 7 days
Judge: Picodes
Total Solo HM: 2
Id: 309
League: ETH
Rank: 31/72
Findings: 1
Award: $104.17
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: hash
Also found by: 0xCiphky, Neon2835, Topmark, Udsen, critical-or-high, lanrebayode77, ptsanev
104.1662 USDC - $104.17
In the _createLegInAMM
function, the removedLiquidity
variable may overflow. Once this happens, it can cause significant errors, resulting in a very large value for the removedLiquidity
variable.
The variable removedLiquidity
is referenced in the function _getPremiaDeltas
to calculate the premium. A serious error in the variable 'removedLiquidity' will cause a significant error in the calculation of the user's premium.
The following is a partial code excerpt from the _createLegInAMM
function:
unchecked { // did we have liquidity already deployed in Uniswap for this chunk range from some past mint? // s_accountLiquidity is a LeftRight. The right slot represents the liquidity currently sold (added) in the AMM owned by the user // the left slot represents the amount of liquidity currently bought (removed) that has been removed from the AMM - the user owes it to a seller // the reason why it is called "removedLiquidity" is because long options are created by removing -ie.short selling LP positions uint128 startingLiquidity = currentLiquidity.rightSlot(); uint128 removedLiquidity = currentLiquidity.leftSlot(); uint128 chunkLiquidity = _liquidityChunk.liquidity(); if (isLong == 0) { // selling/short: so move from msg.sender *to* uniswap // we're minting more liquidity in uniswap: so add the incoming liquidity chunk to the existing liquidity chunk updatedLiquidity = startingLiquidity + chunkLiquidity; /// @dev If the isLong flag is 0=short but the position was burnt, then this is closing a long position /// @dev so the amount of short liquidity should decrease. if (_isBurn) { removedLiquidity -= chunkLiquidity; } }
Note the statement: removedLiquidity -= chunkLiquidity;
is contained in the unchecked{}
code block, which means solidity will not check for integer overflow. If chunkLiquidity
is greater than removedLiquidity
, then removedLiquidity
will become a very large number due to integer underflow.
Manual audit
Add a conditional judgment before the statement removedLiquidity -= chunkLiquidity;
if (_isBurn) { + if(chunkLiquidity > removedLiquidity) revert('overflow'); removedLiquidity -= chunkLiquidity; }
Under/Overflow
#0 - c4-judge
2023-12-13T06:48:19Z
Picodes marked the issue as duplicate of #516
#1 - Picodes
2023-12-13T06:48:44Z
No valid scenario is described
#2 - c4-judge
2023-12-26T21:53:43Z
Picodes changed the severity to 2 (Med Risk)
#3 - c4-judge
2023-12-26T21:54:41Z
Picodes marked the issue as satisfactory
#4 - c4-judge
2023-12-26T21:54:56Z
Picodes marked the issue as partial-50
#5 - c4-judge
2023-12-26T21:55:02Z
Picodes marked the issue as partial-25