You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Uniswap V2与SushiSwap中getAmountsIn为何始终高于getAmountsOut?

为什么Uniswap V2/SushiSwap中getAmountsIn返回值高于getAmountsOut?

这是由Uniswap V2(以及fork它的SushiSwap)的恒定乘积做市商模型和交易手续费机制决定的,核心原因如下:

1. 两个函数的计算目标完全不同

  • getAmountsOut:给定你要输入的代币数量,计算扣除手续费后能拿到的目标代币数量。
  • getAmountsIn:给定你想要拿到的目标代币数量,计算需要输入的代币数量(要覆盖手续费,保证最终能拿到目标量)。

2. 手续费的反向放大效应

Uniswap V2的交易手续费是0.3%,这个费用在两个函数的计算中影响方向不同:

  • 调用getAmountsOut(1 WETH, [WETH, USDC])时,输入的1 WETH会先扣除0.3%手续费(实际只有0.997 WETH进入流动性池子),再用恒定乘积公式x*y=k计算能兑换出的USDC数量。
  • 调用getAmountsIn(1 WETH, [USDC, WETH])时,为了确保最终能拿到1 WETH,需要先算出“无手续费情况下需要多少USDC才能换出1 WETH”,然后再除以0.997(因为手续费会从输入的USDC中扣除0.3%,所以必须多输入USDC才能让实际进入池子的金额足够支撑取出1 WETH)。

3. 恒定乘积模型的滑点叠加

即使忽略手续费,恒定乘积模型本身的滑点也会导致:用A换B得到的数量,再用这个数量的B换A,得到的A会少于最初的输入。再叠加手续费的损耗,就会让getAmountsIn的返回值(需要的输入)明显高于getAmountsOut的返回值(能拿到的输出)。

你的测试代码(格式化后)

from helper import *
from decimal import Decimal

wethAddr = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'
usdcAddr = '0xdAC17F958D2ee523a2206206994597C13D831ec7'

amount = uniRouter.functions.getAmountsOut(web3.to_wei(Decimal('1'), 'ether'), [wethAddr, usdcAddr]).call()
amount2 = sushiRouter.functions.getAmountsOut(web3.to_wei(Decimal('1'), 'ether'), [wethAddr, usdcAddr]).call()
amount3 = uniRouter.functions.getAmountsIn(web3.to_wei(Decimal('1'), 'ether'), [usdcAddr, wethAddr]).call()
amount4 = sushiRouter.functions.getAmountsIn(web3.to_wei(Decimal('1'), 'ether'), [usdcAddr, wethAddr]).call()

print(amount[1])
print(amount2[1])
print(amount3[0])
print(amount4[0])

内容的提问来源于stack exchange,提问作者Andrei Cosmin Marica

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 17:55:02