Closed code423n4 closed 1 year ago
0xRobocop marked the issue as primary issue
0xRobocop marked the issue as low quality report
Insufficient proof
Incorrect premises:
Lets assume when swapping a SpecifiedToken.X units amount, the calculated yToken output is 7units. When negating signed integer values before casting to unsigned integers, values can increase or decrease astronomically, let assume _swap(...) returns the signed integer +7 cached in result as shown below,
In the context of swapGivenInputAmount
the value returned by _swap
cannot be positive, this is enforced via:
require(result < 0);
JustDravee marked the issue as unsatisfactory: Insufficient proof
Lines of code
https://github.com/code-423n4/2023-08-shell/blob/c61cf0e01bada04c3d6055acb81f61955ed600aa/src/proteus/EvolvingProteus.sol#L548 https://github.com/code-423n4/2023-08-shell/blob/c61cf0e01bada04c3d6055acb81f61955ed600aa/src/proteus/EvolvingProteus.sol#L551 https://github.com/code-423n4/2023-08-shell/blob/c61cf0e01bada04c3d6055acb81f61955ed600aa/src/proteus/EvolvingProteus.sol#L506-L554 https://github.com/code-423n4/2023-08-shell/blob/c61cf0e01bada04c3d6055acb81f61955ed600aa/src/proteus/EvolvingProteus.sol#L288-L303 https://github.com/code-423n4/2023-08-shell/blob/c61cf0e01bada04c3d6055acb81f61955ed600aa/src/proteus/EvolvingProteus.sol#L299-L303 https://github.com/code-423n4/2023-08-shell/blob/c61cf0e01bada04c3d6055acb81f61955ed600aa/src/proteus/EvolvingProteus.sol#L452
Vulnerability details
Impact
A malicious user can drain pool reserves by calling the
swapGivenInputAmount(...)
function during swapping and also during withdrawal by callingwithdrawGivenOutputAmount(...)
andwithdrawGivenInputAmount(...)
during withdrawal leading to a loss of funds.Proof of Concept
during swapping, the
swapGivenInputAmount(...)
function makes a call to_swap(...)
which in turn makes a call to_applyFeeByRounding(...)
although for swaps, if
SpecifiedToken
is X, thenyf - yi
is negative (vice versa) and_applyFeeByRounding(...)
handles that correctly and returns a positive swap output amount that is cached inresult
which is a signed integerHowever, the
swapGivenInputAmount(...)
checks that theresult
is less than zero before proceeding to calculate theoutputAmount
which also is evaluated by first casting and then negating the value of result. this can lead an amount lower than the actualoutputAmount
.The same vulnerability described above is present in the
withdrawGivenOutputAmount(...)
function as shown belowExploit Scenario
Lets assume when swapping a
SpecifiedToken.X
units amount, the calculatedyToken
output is 7units.When negating signed integer values before casting to unsigned integers, values can increase or decrease astronomically, let assume
_swap(...)
returns the signed integer +7 cached inresult
as shown below,when casting
result
to an unsigned integer, firstly the logic negates this signed integer value to -7 before casting and in doing this, the integer is converted to a negative signed value i.e for example from the valueto the value
and then the value
uint256(-7)
is calculated asthe
result
has now been astronomically increased from 7unit of output token amount to a very large value (~5e58) this shows that even a small swap amount can lead to having a astronomical output amount a malicious user only needs two transactions to drain both reserves by swapping X for Y and then Y for X.Tools Used
Manual Review
Recommended Mitigation Steps
In the
swapGivenInputAmount(...)
functionoutputAmount
is not more than the maximum swap amount. as shown belowIn the
withdrawGivenOutputAmount(...)
functionchange the less than sign in the require statement to greater than. as shown below.
Assessed type
Other