Closed code423n4 closed 1 year ago
tick
is capped to MAX_TICK=460540
and never causes overflow. BinMath.sol
gte620v marked the issue as sponsor disputed
tick
is capped toMAX_TICK=460540
and never causes overflow. BinMath.sol
Agreed
This report is well written up however I agree with hansfriese that since tick is capped to 460540 the overflows will not be reachable.
kirk-baird marked the issue as nullified
Lines of code
https://github.com/code-423n4/2022-12-Stealth-Project/blob/fc8589d7d8c1d8488fd97ccc46e1ff11c8426ac2/maverick-v1/contracts/libraries/BinMap.sol#L26 https://github.com/code-423n4/2022-12-Stealth-Project/blob/fc8589d7d8c1d8488fd97ccc46e1ff11c8426ac2/maverick-v1/contracts/libraries/BinMap.sol#L31 https://github.com/code-423n4/2022-12-Stealth-Project/blob/fc8589d7d8c1d8488fd97ccc46e1ff11c8426ac2/maverick-v1/contracts/libraries/BinMap.sol#L36 https://github.com/code-423n4/2022-12-Stealth-Project/blob/fc8589d7d8c1d8488fd97ccc46e1ff11c8426ac2/maverick-v1/contracts/libraries/BinMap.sol#L42 https://github.com/code-423n4/2022-12-Stealth-Project/blob/fc8589d7d8c1d8488fd97ccc46e1ff11c8426ac2/maverick-v1/contracts/libraries/BinMap.sol#L78 https://github.com/code-423n4/2022-12-Stealth-Project/blob/fc8589d7d8c1d8488fd97ccc46e1ff11c8426ac2/maverick-v1/contracts/models/Pool.sol#L538 https://github.com/code-423n4/2022-12-Stealth-Project/blob/fc8589d7d8c1d8488fd97ccc46e1ff11c8426ac2/maverick-v1/contracts/models/Pool.sol#L620
Vulnerability details
Impact
The
BinMap
library performs multiplication onint32
values that can potentially overflow and cause the corresponding function calls to revert. The functions in question are used by essentialPool
methods such asPool.addLiquidity
orPool.swap
and an overflow would cause a permanent DOS to these functions and as a result also to the corresponding pool instance.Proof of Concept
The
BinMap
library performs the following logic in almost all its functions:The variable
tick
describes the currently active tick of the calling pool and is anint32
that is passed as function parameter. The value ofNUMBER_OF_KINDS_32
is 4 and multiplication with it essentially just performs a leftshift by 2 bits. Opposed to a leftshift operation, a multiplication can overflow though, as showcased in the following simple foundry tests:The
BinMap
library is used in thePool.addLiquidity
andPool.swap
early on, e.g. in a call tobinMap.getKindsAtTick(activeTick)
. Those are also the only functions that are able to change the value ofPool.state.activeTick
, hence if those two functions break, the pool instance is rendered unusable indefinitely.A simple example where it is evident that a tick value that high can be actually reached is the following scenario: a malicious actor watches the mempool for calls to
Factory.create
and frontruns the call with the same data except he replaces the_activeTick
param withtype(int32).max
which will causestate.activeTick = _activeTick
right in the constructor of thePool
and cause the DOS described above. Though this kind of griefing can be considered questionable from a cost-perspective, as there is an infinite amount of possible pool configurations, this example serves to highlight the possibility of the issue occuring in practice.Tools Used
Manual review and foundry.
Recommended Mitigation Steps
Replace all occurrences of
tick * NUMBER_OF_KINDS_32
in theBinMap
library withtick << 2
. Alternatively restrict the maximum tick value in thePool
contract.