Resources

People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!

Nereus Finance Flashloan Attack Analysed and Exploited- 1023

FaithPosted 3 Years Ago
  • Nereus Finance is a lending / borrowing protocol. This allows users to deposit their tokens to earn interest on them and borrow funds from this protocol.
  • Why would somebody want to borrow assets if they can't be under-collateralized? In the case of this protocol, the NXUSD token is a stable coin alternative to USDC. The main way to obtain NXUSD is by borrowing it. For NXUSD, the main purpose of the token is staking it; this means giving a token for somebody else to use in order to earn rewards on it.
  • A liquidity pool (LP) is the main method for exchanging one token for another. An LP consists of one or more tokens. When putting your own funds into the pool, you receive a pair or LP token. This can be used to stake, collateral or many other things. In the case of this project and hack, the pool is USDC-WAVAX and this gives back the JLP token.
  • When calculating the price of a liquidity pool, the price is strictly dependent on the ratio between the tokens in the pool. For instance, if there was a 1:1 ratio, trading for one token would give you an equal amount of the other one. If it was 2:1, then trading for two of one token gets you a single token of the other.
  • The contract JLPWAVAXUSDCOracle is used to calculate the price of JLP. This is done via the following steps:
    1. Get USDC price from an external oracle.
    2. Get Avax (Avalanche) price via an external oracle.
    3. Get the reserves of each token within the contract.
    4. Price is the following formula: JLP = (AvaxReserve * AvaxPrice + USDCReserve * USDCPrice) / totalSupplyJLP
  • This isn't some weird injection issue or anything... it's a math issue where there is a case that is forgotten: an attacker can obtain an insane amount of money quickly via a flash loan. The variables AvaxReserve and USDCReserve are somewhat controllable, since we can swap in and out of the contract. These variables are also part of the price of the JLP token, as mentioned above.
  • If an attacker swaps a ^*&@ ton of one token for another, then the price of the JLP can be drastically skewed in either a high or low direction. To drop it low, we exchange in a large amount of USDC, since it is cheaper. At this point, the exchange rate is much cheaper for the NXUSD (which can be traded from JLP) to borrow WAYYYY more than we should be able to.
  • The author of the post puts the steps above:
    1. Use a flash loan to obtain a large amount of USDC and another currency to acquire JLP.
    2. Acquire JLP tokens at the normal price.
    3. Lower the exchange rate of the JLP token by swapping in a ton of USDC for wrapped AVAX.
    4. Using the JLP from before, use this to borrow the NXUSD. Remember, the exchange rate has been dropped, so we get more tokens than anticipated.
    5. Swap back the WAVAX for USDC to bring the exchange rate back.
    6. Pay back the flash loan after getting a huge profit from the NXUSDC.
  • An interesting note that the author makes... we are simply leaving the JLP in the contract since we profit from the NXUSDC. Unlike the bank coming after you in the real world, the only thing that makes you return the loan is the collateral deposited. Since we made more money than the JLP is worth, we simply leave it in the contract.
  • The author includes a very detailed proof of concept that is explained well with a Hardhat setup. So, how does one fix this problem with the JLP token? Having a Time Weighted Average Price (TWAP) or forcing these steps into multiple blocks would solve the problem. An absolutely amazing post and I look forward to more of these in the future!