上下文:我们正在创建一个智能合同,它集成Uniswap将令牌交换给ETH。我们需要确保一次掉期不会影响令牌价格超过3%。
我们需要编写一个函数,输入price_impact: uint、reserve0: uint和reserve1: uint,并输出令牌的最大amount,当在uniswap上交换ETH时,令牌的最大D3将对令牌价格产生给定的价格影响。
那么,是否有人能帮助理解在uniswap交换页面上是如何计算价格影响的,以及如何编写一个函数,该函数将最大数量的令牌替换为具有给定价格影响的ETH?
博士:https://uniswap.org/docs/v2
定价文档:https://uniswap.org/docs/v2/javascript-SDK/pricing
词汇表:https://uniswap.org/docs/v2/protocol-overview/glossary/#docs-header
发布于 2022-08-22 20:43:25
这个问题很晚了,但由于它仍然没有答案,我将编写一个解决方案;它应该可以帮助仍然在UniswapV2数学中挣扎的人们。
因此,价格影响通常被定义为掉期交易引起的价格的相对变化。如果最初的价格是pi,最后是pf,那么价格影响将是PI = (pf-pi)/pi。
按价格计算,我们考虑的是名义价格(不收费),即准备金之间的比率,因此:

用in和out分别表示输入和输出令牌的储量。
最后储备金由下列机构提供:


对于x_in输入量,x_out输出量,可以通过以下公式(取自uniswap的代码)给出:

把所有公式加在一起,我们可以把x_in作为价格影响和初始储备的函数:

通过以下方式:

这一切都写得很扎实--这就是它的样子:
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);
}
}希望我没有犯一些数学错误。希望它能帮到别人!
https://ethereum.stackexchange.com/questions/90066
复制相似问题