SunSwap v3兑换简介
SunSwap V3兑换协议核心概念: 做市商原理、流动性池及兑换
背景
尽管SunSwap V2在去中心化交易领域取得了巨大成功,但它也存在一些局限性。其中一个主要问题是流动性的利用率低。SunSwap V3引入了集中资金利用率的概念,允许流动性提供者将资金集中在特定价格范围内。这意味着他们可以更有效地提供流动性,并在价格波动较大的区间内获得更高的收益。
为了解决这个问题,SUN.io团队开发了SunSwap V3。SunSwap V3于2023年6月推出,引入了一种新的交易模型,称为"集中流动性"。在SunSwap V3中,流动性提供者可以选择在特定价格范围内提供资金,而不是将资金固定在一个交易对中。这样可以提高流动性的效率,并为交易者提供更好的价格选择。SunSwap V3引入了动态手续费模型,使流动性提供者能够在不同价格范围内设置不同的手续费率。这样可以提高流动性提供者的收益,并激励他们提供更多的流动性。
原理简介
基于恒定乘积公式来推演兑换的逻辑, 以x和y代表两种代币(假设为X和Y)的数量,则:
p=y/x L 被称作流动性。池子中的流动性是两种 token 资产数量的组合。我们知道,按照公式,两种代币数量乘积为k,因此我们可以用xy来衡量池子流动性。L 实际上是x和y的几何平均数。
y/x是token0和token1的价格。由于池子里两种代币的价格互为倒数,我们在计算中仅使用其中一个(SunSwap V3使用的是y/x)。
同样的L也表示了输出数量的变化与p的变化关系:
L=ΔPΔy 证明:
L=ΔPΔy L=P1−P0y1−y0 (P1−P0)xy=y1−y0 (y1/x1−y0/x0)xy=y1−y0 因为xy=x0y0=x1y1,故:
(y12−y02)=y1−y0 y1−y0=y1−y0 合约地址
Factory
主网合约地址: TThJt8zaJzJMhCEScH7zWKnp5buVZqys9x
nile测试网合约地址:TUTGcsGDRScK1gsDPMELV2QZxeESWb1Gac
SwapRouter
主网合约地址: TJ4NNy8xZEqsowCBhLvZ45LCqPdGjkET5j
注意:旧 Router 合约地址 TQAvWQpT9H916GckwWDJNhYZvQMkuRL7PN 已弃用。
nile测试网合约地址:TFkswj6rUfK3cQtFGzungCkNXxD2UCpEVD
NonfungiblePositionManager
主网合约地址: TLSWrv7eC1AZCXkRjpqMZUmvgd99cj7pPF
nile测试网合约地址:TPQzqHbCzQfoVdAV6bLwGDos8Lk2UjXz2R
与合约交互
我们利用TronWeb与合约交互, 初始化TronWeb实例后, 就能很方便的与线上合约交互
const TronWeb = require('tronweb')
const privateKey = process.env.PRIVATE_KEY
const apiKey = process.env.API_KEY
var tronWeb = new TronWeb({
fullHost: "https://api.trongrid.io",
headers: { "TRON-PRO-API-KEY": apiKey },
privateKey: privateKey,
})
查询信息
获取流动性地址
名称:getPool(address,address,uint24)
参数:token0地址,token1地址,fee率
>>> let contract = await tronWeb.getContract('TThJt8zaJzJMhCEScH7zWKnp5buVZqys9x')
>>> await contract.methods.getPool('TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t',‘TPYmHEhy5n8TCEfYGqW2rPxsghSfzghPDn’,100).call()
0x839538A1B5E9B57C639035A453E07C9A4309F9D9
获取pool的信息
调用合约:pool合约(通过factory可以获得该合约地址)
返回值: 1、当前价格(获取的价格进行平方除以2的192次方获得当前价格);2、当前所在tick;3、观测值数组的最新更新索引;4、当前存储的观测值的最大数量;5、在观察中触发的下一个要存储的最大观测值数;6、当前协议费占提款时掉期费的百分比;7、池子是否已锁定
>>> let contract = await tronWeb.getContract('TSUUVjysXV8YqHytSNjfkNXnnB49QDvZpx')
>>> await contract.methods.slot0().call()
[
sqrtPriceX96: BigNumber { _hex: '0x4714a6b4d8e3d1ab6bcfbe0c', _isBigNumber: true },
tick: -25629,
observationIndex: 0,
observationCardinality: 1,
observationCardinalityNext: 1,
feeProtocol: 0,
unlocked: true
]
获取用户tokenId
名称:tokenOfOwnerByIndex(address,uint256)
调用合约:NonfungiblePositionManager
>>> let contract = await tronWeb.getContract('TLSWrv7eC1AZCXkRjpqMZUmvgd99cj7pPF')
>>> await contract.methods.tokenOfOwnerByIndex('TF5MekHgFz6neU7zTpX4h2tha5miPDUj3z',0).call()
1
获取用户流动性
调用合约:NonfungiblePositionManager
返回值: 1、nonce;2、tokenId授权地址;3、池子中token0地址;4、池子中token1地址;5、池子fee率;6、选择的position的最低值;7、选择的position最高值;8、流动性;9、10、截至对单个头寸的最后一次操作时总头寸的费用增长;11、12、截至上次计算,该头寸欠多少未收集的代币
>>> let contract = await tronWeb.getContract('TLSWrv7eC1AZCXkRjpqMZUmvgd99cj7pPF')
>>> await contract.methods.positions (1).call()
[
nonce: 0
operator: T9yD14Nj9j7xAB4dbGeiX9h8unkKHxuWwb
token0: TF9io9LGyjuK3uTpr73pAaQ5m9scxd9xvr
token1: TK8E3sFhBt3EB6gTT6d6co8RMB6DFUnNwE
fee: 3000
tickLower: -283380
tickUpper: -269520
liquidity: 1390641886550414128
feeGrowthInside0LastX128: 0
feeGrowthInside1LastX128: 540564213145032425660083902
tokensOwed0: 0
tokensOwed1: 0
]
执行交易
交易
名称:exactInput(ExactInputParams)
参数:[path的encode,用户地址,deadline]
>>> let contract = await tronWeb.getContract('TQAvWQpT9H916GckwWDJNhYZvQMkuRL7PN')
>>> await contract.methods.exactInput(['0xe518c608a37e2a262050e10be0c9d03c7a0877f3000bb843c42f702b0a11565c46e34022aab677d7bd8ae3','TF5MekHgFz6neU7zTpX4h2tha5miPDUj3z',1662825600])
添加流动性
名称:increaseLiquidity(IncreaseLiquidityParams)
调用合约:NonfungiblePositionManager
参数:[tokenId,token0添加的数量,token1添加数量,token0最小添加量,token1最小添加量,deadline]
>>> let contract = await tronWeb.getContract('TLSWrv7eC1AZCXkRjpqMZUmvgd99cj7pPF')
>>> await contract.methods.increaseLiquidity(1,'1000000000000000000','1000000000000000000',1,1,1662825600)
降低流动性
名称:decreaseLiquidity(DecreaseLiquidityParams)
调用合约:NonfungiblePositionManager
参数:[tokenId,需要移除的流动性,获得最小token0数量,获得最小token1数量,deadline]
>>> let contract = await tronWeb.getContract('TLSWrv7eC1AZCXkRjpqMZUmvgd99cj7pPF')
>>> await contract.methods.decreaseLiquidity(1,'1390641886550414128',1,1,1662825600)
获取奖励
名称:collect(CollectParams)
调用合约:NonfungiblePositionManager
参数:[tokenId,接受奖励地址,获得token0的最大奖励,获得token1的最大奖励]
>>> let contract = await tronWeb.getContract('TLSWrv7eC1AZCXkRjpqMZUmvgd99cj7pPF')
>>> await contract.methods.collect(1,'TF5MekHgFz6neU7zTpX4h2tha5miPDUj3z',‘100000000000000000000000000’,‘100000000000000000000000000’)