Closed code423n4 closed 1 year ago
All the bins in a given tick have the same reserve ratio. This is enforced by these calculations https://github.com/code-423n4/2022-12-Stealth-Project/blob/fc8589d7d8c1d8488fd97ccc46e1ff11c8426ac2/maverick-v1/contracts/libraries/Bin.sol#L42-L48. So it is fine to use the ratio of the first bin as this will be the same as the ratio of the aggregate.
Moreover, a user has the additional protections discussed in https://github.com/code-423n4/2022-12-Stealth-Project-findings/issues/92#issuecomment-1354018166 to avoid an add-liquidity situation that they do not expect.
gte620v marked the issue as sponsor disputed
As all bins have the same reserve ratio at a tick, it is indifferent to use one bin vs the aggregate of all bins.
I'm going to mark this issue as invalid.
kirk-baird marked the issue as nullified
Lines of code
https://github.com/code-423n4/2022-12-Stealth-Project/blob/fc8589d7d8c1d8488fd97ccc46e1ff11c8426ac2/maverick-v1/contracts/models/Pool.sol#L126
Vulnerability details
Impact
Liquidity can be biased on a specific side (quote vs base) and it is even possible a liquidity provider gets more LP tokens.
Proof of Concept
According to the PDF document provided, the number of LP tokens
newSupply
is calculated using the Table 1 as below.In the document,
reserveA
andreserveB
represent the total amount of the quote token and the base token in a specific price range $[p_l, p_u]$ respectively.In the implementation, the protocol gets the first valid bin and use its reserve amounts for this.
The function
_firstKindAtTickLiquidity()
finds a bin of any kind that is registered.And the kinds of bins are defined as constants to be used in bit operations.
This can lead to a few possible problems in some scenarios. First, the liquidity can be biased into a specific side (base or quote). As we can see from the liquidity calculation table, if either
reserveA
orreserveB
is zero, the user deposit is limited to one side (A or B). So this results in unnecessary bias in the liquidity. Note that if we use the aggregated reserve values, it will be better. For example, let's say there is a bin ofKIND_RIGHT
withreserveA>0, reserveB=0
. Then all deposits for this price range, only quote tokens will be deposited until it is not merged. Second, more LP tokens might be minted. From the table 1, we can see that ifreseveA>0, reserveB>0
, a minimum of two side values are used as an amount of LP tokens. So in a scenario same to the first case, the user will continue getting more LP tokens because only one side is used when either one side's reserve amount is zero.From the conversation with the sponsor, it is understood that it is gassier (but still limited to 4 loops) to use aggregated values but I believe this can lead to a problem that costs more than the gas concern.
Tools Used
Manual Review
Recommended Mitigation Steps
Use the aggregated amounts of all kinds of bins instead of one bin as the reserve amounts while adding liquidity.