I use this calls:

IUniswapV2Router(uniswapV2Router).getAmountOut(tokenAmount, reserve1, reserve0) // Uniswap V2 token price

(uint160 sqrtPriceX96, , , , , , ) = uniswapV3Pool.slot0(); // Uniswap V3 token price

To get the current token prices, and then use these prices to handle logic inside function.

  1. Is it possible to manipulate the pool values (inside 1 block) to make positive influence on the outputs of these functions? (like make ETH/USD output price temporarily go +1000%?)

  2. Is it possible to manipulate the pool values (inside 1 tx) to wrap my public function (e.g. convince it that the price of ETH/USD is +1000% when function calls getAmountOut() or sqrtPriceX96)?

  3. If 1. and 2. are possible — whats are the best practices to safely get the V2 and V3 prices, making them immutable to flash swap/loan attacks? (e.g. writing in storage, skipping a few blocks: I'm able to trade-off for anything)

2 Answers 2

  1. Yes, but not with a flashloan on its own, since flashloans must be repaid in the same transaction.
  2. Yes.
  3. Uniswap pools have built-in Oracles. Uniswap v2 pools have a TWAP oracle. Uniswap v3 pools have oracles for time-weighted average ticks and liquidity depth.

Flash loans have to be paid in the same transaction, not just the same block. So I don't think you would have an issue from a flash loan.

What you describe sounds like a sandwich attack taking multiple transactions across a block. Where for instance if a buyer doesn't correctly set a slippage value, a bot can drive up the price in one transaction, have the buyer get a poor execution price in the next, and then sell back into the pool to pocket the difference in the final transaction.

To protect against that you should have some check for a minimum output amount like the routers do and set an amount that isn't so tight as to cause a revert if an organic trade lands before yours but tight enough to make it unprofitable to sandwich.

Can also use a service like flashbots protect to hide your transactions from sandwichers searching a mempool.

I don't think you need to worry about calling reserves from within an atomic operation that is performing either some safety check, or that is guaranteed to revert on unprofitability.

  • What if I create 4-step function, where at step 1) I take the flash loan from pool; 2) purchase a lot of TOKEN with borrowed WETH in WETH/TOKEN pair, surging the price; 3) call the function where getAmountOut() used to check current WETH/TOKEN price; 4) swap TOKEN back to WETH/TOKEN pair and return borrowed WETH?
    – blockson
    Commented Apr 8 at 9:01
  • 1
    You could not sandwhich anyone else this way as you've paid back the tokens before the next transaction can act on the state.
    – Maka
    Commented Apr 8 at 10:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.