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: 53/72
Findings: 2
Award: $11.32
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: osmanozdemir1
Also found by: 0xCiphky, Audinarey, Banditx0x, CRYP70, Cryptor, D1r3Wolf, KupiaSec, LokiThe5th, Sathish9098, Skylice, ThenPuli, Topmark, Udsen, ZanyBonzy, baice, ether_sky, fatherOfBlocks, foxb868, grearlake, hihen, hubble, hunter_w3b, lanrebayode77, leegh, lsaudit, minhtrng, nocoder, onchain-guardians, ptsanev, ro1sharkm, seaton0x1, sivanesh_808, t4sk, tapir, tpiliposian, ustas
11.3163 USDC - $11.32
- /// @notice Calculates the amount of liquidity for a given amount of token0 and liquidityChunk + /// @notice Calculates the amount of liquidity for a given amount of token1 and liquidityChunk
Loss of precision in Math.getLiquidityForAmount1()
report:Minting... 0x0000000000000000000000000000000000123456 Liquidity to mint 18767501621118 Token0: -567114396 Token1: -254483561326829482 Removed liq: 0 Added liq: 18767501621118 SFPM: 999999999999991608 Burning... 0x0000000000000000000000000000000000123456 Liquidity to burn 18767501621118 Token0: 567114395 Token1: 254483561326829481 Removed liq: 0 Added liq: 0 SFPM: 0
SFPM
balances. Users can mint any amount of any SFPM
tokens before they'll actually pay for the liquidity because _mint()
in mintTokenizedPosition()
contains a callback right after the balances change. It is better to move the minting to the end of the execution.function mintTokenizedPosition( uint256 tokenId, uint128 positionSize, int24 slippageTickLimitLow, int24 slippageTickLimitHigh ) external ReentrancyLock(tokenId.univ3pool()) returns (int256 totalCollected, int256 totalSwapped, int24 newTick) { // create the option position via its ID in this erc1155 - _mint(msg.sender, tokenId, positionSize); // @audit-info can mint any amount of any tokenId and receive a callback emit TokenizedPositionMinted(msg.sender, tokenId, positionSize); // validate the incoming option position, then forward to the AMM for minting/burning required liquidity chunks (totalCollected, totalSwapped, newTick) = _validateAndForwardToAMM(tokenId, positionSize, slippageTickLimitLow, slippageTickLimitHigh, MINT); + _mint(msg.sender, tokenId, positionSize); }
uniswapV3MintCallback()
with ERC777 tokens (the project supports them). When Alice calls mintTokenizedPosition()
the following will happen:
_mint()
;_createLegInAMM()
calculates and updates the liquidity held by Alice;_mintLiquidity()
calls UniswapV3Pool.mint()
;uniswapV3MintCallback()
;SFPM
(s_accountLiquidity
mapping) instead of the standard ERC1155 to determine the liquidity held by Alice, they will still be vulnerable to this reentrancy.
Solution here is to update the liquidity after the payment.#0 - c4-judge
2023-12-14T17:00:14Z
Picodes marked the issue as grade-b
#1 - ustas-eth
2023-12-29T17:52:04Z
Given the following rule from the C4 documentation:
All issues which identify the same functional vulnerability will be considered duplicates regardless of effective rationalization of severity or exploit path.
Number 4 of the current QA is a duplicate of https://github.com/code-423n4/2023-11-panoptic-findings/issues/519 because it describes the root cause of the issue: the possibility of reentrancy in the Uniswap hook.
#2 - Picodes
2024-01-01T16:38:23Z
@ustas-eth the possibility of reentrancy in the Uniswap hook is too vague.
There is no mention of the real root cause here which is the update of s_accountFeesBase
after the hook. There is also no description of a High severity impact.