Skip to content

Latest commit

 

History

History
34 lines (27 loc) · 1.83 KB

015.md

File metadata and controls

34 lines (27 loc) · 1.83 KB

Proud Rusty Mantis

High

Users won't be able to withdraw from a vault even though it has sufficient liquidity

Vulnerability Detail

Upon selling our NUMA, we have the following code:

uint256 tokenAmount = vaultManager.numaToToken(_numaAmount, last_lsttokenvalueWei, decimals, criticalScaleForNumaPriceAndSellFee);
require(lstToken.balanceOf(address(this)) >= tokenAmount, "not enough liquidity in vault");

We convert the NUMA to sell into an LST and check that the vault has sufficient liquidity. That is wrong as we are applying fees to the tokenAmount afterwards which results in users being able to withdraw less than supposed to.

Attack Path

  1. User wants to sell his 1e18 NUMA which is equal to 1e18 LST (1:1 ratio)
  2. The fee is 0.95e18 (indicating 5e16 or 5%)
  3. We calculate the token out, $1e18 * 0.95e18 / 1e18 = 0.95e18$ and we send them out to the user
  4. We calculate the fees to send to the fee receiver like this:
uint feeTransferNum = fees * (1 ether - fee);
uint feeTransferDen = uint(BASE_1000) * 1 ether;
uint256 feeAmount = (feeTransferNum * tokenAmount) / (feeTransferDen);
  1. fees are set to 200, thus result is $200 * (1e18 - 0.95e18) * 1e18 / (1000 * 1e18) = 10 000 000 000 000 000$ and we transfer them out to the fee receiver
  2. Total tokens sent are equal to $10 000 000 000 000 000 + 0.95e18 = 960 000 000 000 000 000$
  3. If the user wanted to sell his 1e18 NUMA, we would have reverted even though we would have had more than enough tokens to satisfy the sale (let's say we have 1e18 - 1 in liquidity), this results in users having stuck funds for an unknown amount of time

Impact

Stuck funds for an unknown amount of time, until liquidity in the vault increases

Mitigation

Remove the check altogether as we would revert either way if the tokens are insufficient