@zoand
2023-08-01 09:41
字数 6163
阅读 421
platon
合约名称 | 测试环境(PLATON Testnet) | 生产环境(PLATON Mainnet) |
---|---|---|
DipoleFactory | 0x0b428E9f0CAC5A1D04609F5a6D3d5205F1eA152F | 0x74Dd7b2dC60070516f26AcC30a5C734D3c87B2c9 |
DipoleRouter | 0x38EC1D8267b9A26b73716395618FE9ae777656d3 | 0x78b674FBC75c43c3D91A35fFFA938268040C1990 |
WLAT | 0xCC9fBAB49C29B3FF536A3d94873e988cC4A572aF | 0x02406D561069cBed27eF8Ea20AFD41779A90e2Bf |
合约名称 | 生产环境 | 测试环境 |
---|---|---|
DipoleFactory | 0x74Dd7b2dC60070516f26AcC30a5C734D3c87B2c9 | |
DipoleRouter | 0x78b674FBC75c43c3D91A35fFFA938268040C1990 | |
CombinedSwapAddRemoveLiquidity | 0x4041C496f0Dcf2aDCBb74bDF98667ce4895b361e | |
Multicall | 0x74581a687cdfF1C3A64a4C66063AcD9f404B2D18 | |
SmartChefFactory | 0x0eb5a41AC2d6790335022a90656df5E364d0233F | |
initHash | 0x8703d5f89be31a934ef8defce2c3d63a8f2a1217066ba898b6a34481a55527a0 |
当输入代币为SCGT
时,需要调用SCGT
合约的approve
方法,向DipoleRouter
合约授权一定数量的SCGT
,使DipoleRouter
合约有权限从钱包地址中转出SCGT
进行后续操作
参数名 | 类型 | 备注 |
---|---|---|
spender | address | DipoleRouter合约地址 |
value | uint | 授权数量 |
LAT
,输出SCGT
(swapExactETHForTokens)参数名 | 类型 | 备注 |
---|---|---|
amountOutMin | uint | 最小输出代币数量 |
path | address[] | 兑换路径上token地址的数组,[wlat地址,scgt地址] |
to | address | 接收地址 |
deadline | uint | 交易超时时间戳(毫秒级) |
LAT
,输出指定数量SCGT
(swapETHForExactTokens)参数名 | 类型 | 备注 |
---|---|---|
amountOut | uint | 指定输出代币数量 |
path | address[] | 兑换路径上token地址的数组,[wlat地址,scgt地址] |
to | address | 接收地址 |
deadline | uint | 交易超时时间戳(毫秒级) |
SCGT
,输出LAT
(swapExactTokensForETH)参数名 | 类型 | 备注 |
---|---|---|
amountIn | uint | 指定输入代币数量 |
amountOutMin | uint | 最小输出ETH数量 |
path | address[] | 兑换路径上token地址的数组,[scgt地址,wlat地址] |
to | address | 接收地址 |
deadline | uint | 交易超时时间戳(毫秒级) |
SCGT
,输出指定数量LAT
(swapTokensForExactETH)参数名 | 类型 | 备注 |
---|---|---|
amountOut | uint | 指定输出ETH数量 |
amountInMax | uint | 最大所需SCGT数量 |
path | address[] | 兑换路径上token地址的数组,[scgt地址,wlat地址] |
to | address | 接收地址 |
deadline | uint | 交易超时时间戳(毫秒级) |
假设交易前交易对中LAT
和SCGT
的数量分别为a、b,手续费为0.0025x(不考虑多跳)
交易中输入代币和输出代币的数量分别为x和y,根据乘积恒定公式:
需要注意一下,DipolePair合约中有两对属性,token0/token1和reserve0/reserve1分别表示两个token地址和对应的reserve,并且token0和reserve0 、 token1和reserve1是一一对应的。
token0和token1是根据两个token地址对应的十六进制的大小确定的,token0 < token1
通过调用DipoleFactory
合约的getPair
方法获取
这里两个token address参数没有顺序要求
参数名 | 类型 | 备注 |
---|---|---|
token0Address | address | WLAT 地址 |
token1Address | address | SCGT 地址 |
返回值:address类型的pair合约地址
通过调用DipolePair
合约的getReserves
方法获取(无参数)
返回值
_reserve0
对应token0的reserve,_reserve1
对应token1的reserve
属性名 | 类型 | 备注 |
---|---|---|
_reserve0 | uint | token0的reserve |
_reserve1 | uint | token1的reserve |
通过调用DipoleRouter
合约的getAmountOut
接口获取
上一步得到的reserves需要判断一下哪个是wlat,哪个是scgt
参数名 | 类型 | 备注 |
---|---|---|
amountIn | uint | 输入token数量 |
reserveIn | uint | 输入token reserve,此处为交易对中WLAT 的reserve |
reserveOut | uint | 输出token reserve,此处为交易对中SCGT 的reserve |
通过调用DipoleRouter
合约的getAmountIn
接口获取
上一步得到的reserves需要判断一下哪个是wlat,哪个是scgt
参数名 | 类型 | 备注 |
---|---|---|
amountOut | uint | 输出token数量 |
reserveIn | uint | 输入token reserve,此处为交易对中WLAT 的reserve |
reserveOut | uint | 输出token reserve,此处为交易对中SCGT 的reserve |
假设交易前输入代币t和输出代币的数量分别为a、b,手续费为0.0025x(不考虑多跳)
交易中输入代币和输出代币的数量分别为x和y,根据乘积恒定公式:
lat对另一代币在交易前的市场价和预估的交易价格分别是
以指定输入为例,指定输出同理
const routerAddr = '0x714377e2443aAaF9e1Fcdf77358639c9E01f68E6'
const factoryAddr = '0xF386b1DCc39cC40aa8f22c03FD6929F17021f6eE'
const wlatAddr = '0xa0C63FAC4e5425F4721FF3258c3FA5B381152F73'
const scgtAddr = '0x01cE844128ECa5e94fA9763f829f5A8ed8D3C956'
const amount = '1000000000000000000' // 1个(decimals为18)
const deadline = '1652976000000'
const to = '0x324b790ABbC496fFba372d7FBe6FA6eE68c5c675'
const router = await DipoleRouter.at(routerAddr)
const factory = await DipoleFactory.at(factoryAddr)
const scgt = await MockBEP20.at(scgtAddr)
以输入
LAT
输出SCGT
为例,反向同理
async function getAmountOut() {
// 获取交易对地址
const pairAddress = await factory.getPair(wlatAddr, scgtAddr)
const pair = await DipolePair.at(pairAddress)
// 获取reserves
const { _reserve0, _reserve1 } = await pair.getReserves()
// 根据token地址排序确定哪个是wlat,哪个是scgt
const [ wlatReserve, scgtReserve ] =
web3.utils.toBN(wlatAddr).lt(scgtAddr)
? [ _reserve0, _reserve1 ]
: [ _reserve1, _reserve0 ]
console.log('wlat reserve:', web3.utils.fromWei(wlatReserve).toString())
console.log('scgt reserve:', web3.utils.fromWei(scgtReserve).toString())
// 获取输出token数量
const outputAmount = await router.getAmountOut(amount, wlatReserve, scgtReserve)
console.log('output', web3.utils.fromWei(outputAmount).toString())
}
wlat reserve: 200
scgt reserve: 1500
output 7.444122439333822559
LAT
转SCGT
async function swaExactLATForSCGT() {
const params = [
0,
[ wlatAddr, scgtAddr ],
to,
deadline
]
// 估算调用swapExactETHForTokens接口所需gas
const gas = await router.swapExactETHForTokens.estimateGas(...params, { value: amount })
console.log('gas:', gas)
params.push({
value: amount,
gas,
gasPrice: '100000000000'
})
// 执行交易
const result = await router.swapExactETHForTokens(...params)
console.log(result)
}
SCGT
转LAT
输入token不是
LAT
时,需要先对输入token进行授权
async function swapExactSCGTForLAT() {
const params = [
amount,
0,
[ scgtAddr, wlatAddr ],
to,
deadline
]
// 授权
await scgt.approve(router.address, amount)
// 估算调用swapExactTokensForETH接口所需gas
const gas = await router.swapExactTokensForETH.estimateGas(...params)
console.log('gas:', gas)
params.push({
gas,
gasPrice: '100000000000'
})
// 执行交易
const result = await router.swapExactTokensForETH(...params)
console.log(result)
}
gas: 147653
{
tx: '0x2631b267686f501a38b8a45e20c7eb5e7f7477fa727dcd1ea30053bd0755e5a7',
receipt: {
blockHash: '0xd2f64dfc5e553a76c8ae724074b45d80ab896727c878254d4169d5d0c3c8ade3',
blockNumber: 19997437,
contractAddress: null,
cumulativeGasUsed: 107389,
from: '0x324b790ABbC496fFba372d7FBe6FA6eE68c5c675',
gasUsed: 107389,
logs: [],
logsBloom: '0x00200000000000000000000080080000000000000000000000080000400800000000000000000000000000000000000000000000000000000000000000200000000000000000000000000008000010200000000100400000000000000000000040000000000000000000000000000000000000000000040000000010000000000000000000000000000020000000000000000000000000080000004000000000020000000000000000000000000000000000200200000000000000000000000000000002000000000000000000000000000000200000001020000002000000001030000200000000000000000000000040000040000000800000000000000000',
status: true,
to: '0x4378dAF745E9053f6048c4f78c803f3bC8829703',
transactionHash: '0x2631b267686f501a38b8a45e20c7eb5e7f7477fa727dcd1ea30053bd0755e5a7',
transactionIndex: 0,
rawLogs: [ [Object], [Object], [Object], [Object], [Object], [Object] ]
},
logs: []
}