Incorrect amount taken users may lead to paying excess during erc20 swaps #126
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
downgraded by judge
Judge downgraded the risk level of this issue
duplicate-12
🤖_07_group
AI based duplicate group recommendation
satisfactory
satisfies C4 submission criteria; eligible for awards
sufficient quality report
This report is of sufficient quality
Lines of code
https://github.com/code-423n4/2024-08-superposition/blob/4528c9d2dbe1550d2660dac903a8246076044905/pkg/seawater/src/lib.rs#L290
Vulnerability details
Impact
Users are charged more than the calculated
amount_in
and excess tokens taken from the user is not refunded leading to loss of funds for the users.Proof of Concept
swap_2_internal_erc20
allows users to swap tokens between two pools. The function queries theswap_2_internal
function which performs the two step swap, first pool to usdc tokens, then usdc tokens to second pool. The thing about this function is that it acts as a two way step involving the amalgamation of a pseudo "swapPoolATokensForExactUSDCTokens" and "swapExactUSDCTokensForPoolBTokens". As can be seen below, thisamount
specified by the user is passed in to theswap_2_internal
function and eventually returned as theoriginal_amount
parameter.The function first attempts to swap tokens in for usdc, passing in the various params includiding the
amount
passed in fromswap_2_internal_erc20
which is the amount specified by the user. After this, theamount_in
parameter is returned from theswap
function. Further down the line, we can see thatamount_in
is checked to ensure its psitive before its finally returned as the result of the function.Now, during the first swap, it can be observed that the original
amount
of tokens specified by the user is not necessarily be theamount_in
that is returned during the swap. For the most part, its either the calculated amount or the difference between the amount specified by the user, and the calculated remaining amount. As such, in certain cases, due to what ever conditions, theamount_0
returned duringswap
(which is now returned asamount_in
inswap_2_internal
), may sometimes differ from theamount
specified by the user which is now returned asoriginal_amount
Establishing this, we can now go through
swap_2_internal_erc20
, specfically, afterswap_2_internal
has been queried. We can see that, as established above, theoriginal_amount
which is the amount specified by the user andamount_in
which is the actual amount of tokens swapped is returned. As such, we'd expect that when token is being taken from the caller, it will be the amount swapped, which in this case is ouramount_in
parameter. However, this is not so (see @Audit tag), the original amount specified by the user is taken.Due to this error, uses are sometimes made to pay way more for the swap than is actually intended as rather than take the exact amount that was used during the swap, the amount the user specified is taken instead, leading to a potential loss of funds.
For extra context, we can observe the
swap_internal
function in which thetake_amount
is set as amount_0 returned from swap, and notamount
sent in by the user. This handles cases in which these amounts are not the same.Also, the comment on the
Ok((amount_in, amount_out))
points out thatamount - amount_in
need to be returned to the user, but this is not done.Tools Used
Manual code review
Recommended Mitigation Steps
Update the code to take
amount_in
instead from the user.Assessed type
Context
The text was updated successfully, but these errors were encountered: