# How does Uniswap calculate price impact without fee on the swap page?

Context: We are creating a smart contract which integrates Uniswap DEX for swapping Tokens to ETH. We need to make sure one swap does not impact the token price more than 3%.

We are in need to write a function which takes in input the `price_impact: uint`, `reserve0: uint` and `reserve1: uint` and outputs the maximum `amount` of tokens which when swapped for ETH on uniswap will have the given price impact on the token price.

So, can someone please help in understanding how is the price impact calculated on the uniswap swap page, and also in writing a function which ouputs maximum number of tokens to be swapped for ETH which would have the given price impact?

Exchange: https://uniswap.org

Pricing Docs: https://uniswap.org/docs/v2/javascript-SDK/pricing

• Do you want the solution in solidity or javascript (since your are linking to the js SDK) ? You need to fetch reserve for the pair, then solve the equation which would imo look like something like this `reserveB - getAmountOut(x) = reserveB B*0.97` whereas reserveB = token reserve. getAmountOut : github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/… Nov 11, 2020 at 23:46

Late to the question, but since it's still unanswered I'll write a solution; it should help people still struggling with UniswapV2 math.

So, the price impact is usually defined as the relative variation of price due to a swap. If the price initially was `pi` and finally `pf`, the price impact will be PI = (pf-pi)/pi.

By price we are considering the nominal price (no fees), which is the ratio between the reserves, so:

with `in` and `out` indicating the reserves of input and output tokens respectively.

The final reserves are given by:

with `x_in` the input amount, and `x_out` the output amount, which can be given by the following formula (taken from uniswap's code):

Putting all the formulas together we can take `x_in` as a function of the price impact and the initial reserves:

with:

Writing it all in solidity this is how it looks:

``````pragma solidity ^0.8.0;

// https://github.com/Uniswap/v2-core/blob/v1.0.1/contracts/libraries/Math.sol
import '/path/to/Math.sol';

// https://github.com/Uniswap/v2-periphery/blob/master/contracts/libraries/UniswapV2Library.sol
import '/path/to/UniswapV2Library.sol';

contract UniswapV2Helper {
address private constant UniV2Factory = ...;
address private constant WETH = ...;

uint256 private constant PRICE_IMPACT_DECIMALS = 18;  // for integer math

// @notice Get max amount of tokens without impacting the price more than maxPriceImpact
//         Swap output is WETH
// @param tokenIn Address of ERC20 to swap
// @param maxPriceImpact Price impact with 'PRICE_IMPACT_DECIMALS' decimals
function getMaxAmountIn(address tokenIn, uint256 maxPriceImpact) public returns(uint256) {
require(maxPriceImpact < 10**PRICE_IMPACT_DECIMALS, "maxPriceImpact too many decimals");

// get reserves
(uint256 reserveIn, /*uint256 reserveOut*/) = UniswapV2Library.getReserves(UniV2Factory, tokenIn, WETH);

return _getMaxAmountIn(reserveIn, maxPriceImpact);
}

function _getMaxAmountIn(uint256 R, uint256 maxPriceImpact) public pure returns(uint256) {
uint256 p = 10**(PRICE_IMPACT_DECIMALS*2)/(maxPriceImpact + 10**PRICE_IMPACT_DECIMALS);

uint256 temp = 9*p*p + 4*1000*997*p*(10**PRICE_IMPACT_DECIMALS);
uint256 sqrt = Math.sqrt(temp);

return (sqrt - 1997*p)*R/(2*997*p);
}
}
``````

Hopefully I didn't make some math mistakes. Hope it helps someone!