hats-finance / Common--Stableswap-0xd4d9a2772202ce33b24901d3fc94e95a84b37430

Apache License 2.0
0 stars 0 forks source link

`rated_swap_to` doesn't round in favor of the protocol #13

Open hats-bug-reporter[bot] opened 2 months ago

hats-bug-reporter[bot] commented 2 months ago

Github username: @0x3b Twitter username: 0x3b33 Submission hash (on-chain): 0xd15b074cdd382d969983da9e64c0ae56e2d3898fde23ea5a763fe5655e8c27a5 Severity: medium

Description: Description\ rated_swap_to doesn't round in favor of the protocol and can cause a potential insolvency.

Attack Scenario\ There is an inconsistency between rated_swap_to and rated_swap_from, where the latter always rounds in favor of the protocol:

    let dy = amount_from_rated(r_dy, rates[token_in_id])?
        .checked_add(1)
        .ok_or(MathError::AddOverflow(12))?;

However the same is not true for rated_swap_to

    let (r_amount_swapped, r_fee) = swap_to(
        token_in_id,
        r_token_in_amount,
        token_out_id,
        &r_current_reserves,
        fees,
        amp_coef,
    )?;

    let amount_swapped = amount_from_rated(r_amount_swapped, rates[token_out_id])?;
    let fee = amount_from_rated(r_fee, rates[token_out_id])?;
    Ok((amount_swapped, fee))

Missing rounds down inside rated_swap_to can potentially cause the issue that amount_from_rated is trying to protect from - insolvency.

It's always best to round in favor of the protocol to avoid any edge case scenarios where an insolvency happens.

Recommendation

Round down inside rated_swap_to:

-    let amount_swapped = amount_from_rated(r_amount_swapped, rates[token_out_id])?;
+   let amount_swapped = amount_from_rated(r_amount_swapped, rates[token_out_id])?
+   .checked_sub(1)
+   .ok_or(MathError::SubUnderflow(18))?;
JanKuczma commented 2 months ago

Thank you for your submission.

In rated_swap_to the amount is already rounded down when scaling down to "token precision" in amount_from_rated() (here). There is no need to sub 1 from this amount.