在LSD和ETH之间进行交换

以下部分详细说明如何使用unshETH的vdAMM将LSD与LSD、ETH或LSD与ETH进行交换。

我们假设inputAmount(以wei单位)、inputLSDAddress和outputLSDAddress分别对应存入的LSD的输入金额、存入的LSD的合约地址和接收的LSD的合约地址。

如果用户从ETH交换到LSD,则inputLSDAddress应为WETH: 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2.

如果用户从LSD交换到ETH,则outputLSDAddress应为WETH: 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2.

所需合约和接口

LSDVault合约地址: 0x51A80238B5738725128d3a3e06Ab41c1d4C05C74

//solidity
interface ILSDVault {
  function swapperAddress() external view returns (address);
}
//ethers.js
const ILSDVaultABI = [
  'function swapperAddress() external view returns (address)',
  'function supportedLSDs(uint256 index) external view returns (address)',
]
const LSDVaultAddress = '0x51A80238B5738725128d3a3e06Ab41c1d4C05C74'
const LSDVaultContract = new ethers.Contract(LSDVaultAddress, ILSDVaultABI, provider)

vdAMM

//solidity
address vdaAMMAddress = ILSDVault(LSDVaultAddress).swapperAddress();
//ethers.js
const vdAMMAddress = await LSDVaultContract.swapperAddress()

vdAMM的当前地址为:

0x35636b85b68c1b4a216110fb3a5fb447a99db14a.

然而,未来可能会发生变化,因此应该从LSDVault合约中动态调用该地址。

//solidity
interface IVdAmm {
   function getDepositFee(uint256 lsdAmountIn, address lsd) external returns(uint256, uint256);
   function swapLsdToLsdCalcs( uint256 amountIn, address lsdIn, address lsdOut) public view returns (uint256, uint256, uint256, uint256);
   function swapLsdToLsd( uint256 amountIn, address lsdIn, address lsdOut, uint256 minAmountOut) external returns (uint256, uint256, uint256);
   function swapLsdToEth( uint256 amountIn, address lsdIn, uint256 minAmountOut) external returns (uint256, uint256, uint256);
   function swapEthToLsd( address lsdOut, uint256 minAmountOut) external payable returns (uint256, uint256, uint256);
}
//ethers.js
const IVdAmmABI = [
  'function getDepositFee(uint256 lsdAmountIn, address lsd) external returns (uint256, uint256)',
  'function swapLsdToLsdCalcs(uint256 amountIn, address lsdIn, address lsdOut) public view returns (uint256, uint256, uint256, uint256)',
  'function swapLsdToLsd(uint256 amountIn, address lsdIn, address lsdOut, uint256 minAmountOut) external returns (uint256, uint256, uint256)',
  'function swapLsdToEth(uint256 amountIn, address lsdIn, uint256 minAmountOut) external returns (uint256, uint256, uint256)',
  'function swapEthToLsd(address lsdOut, uint256 minAmountOut) external payable returns (uint256, uint256, uint256)',
]
const vdAmmContract = new ethers.Contract(vdAMMAddress, IVdAmmABI, provider)

支持的LSDs

// solidity
uint256 i = 0;
address lsdAddress;
while (true) {
  lsdAddress = ILSDVault(LSDVaultAddress).supportedLSDs(i);
  if (lsdAddress == address(0)) {
    break;
  }
  // Process the LSD address here
  i++;
}
// ethers.js
let i = 0
let lsdAddress
while (true) {
  lsdAddress = await LSDVaultContract.supportedLSDs(i)
  if (lsdAddress === '0x0000000000000000000000000000000000000000') {
    break
  }
  console.log(`LSD Address ${i}: ${lsdAddress}`)
  i++
}

目前支持的LSDs如下:

sfrxETH: 0xac3e018457b222d93114458476f3e3416abbe38f

rETH: 0xae78736cd615f374d3085123a210448e74fc6393

wstETH: 0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0

cbETH: 0xbe9895146f7af43049ca1c1ae358b0541ea49704

WETH: 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2

ankrETH: 0xE95A203B1a91a908F9B9CE46459d101078c2c3cb

swETH: 0xf951E335afb289353dc249e82926178EaC7DEd78

未来将添加更多LSDs。

价格发现

1. 获取输出金额(以输入的LSD或ETH为单位)

//solidity
(uint256 outputAmount, _ , _ , _)  = IVdAmm(vdAMMAddress).swapLsdToLsdCalcs(inputAmount, inputLSDAddress, outputLSDAddress);
//ethers.js
const [outputAmount] = await vdAmmContract.swapLsdToLsdCalcs(inputAmount, inputLSDAddress, outputLSDAddress)

提交交易

1. 批准要由unshETHZap花费的LSD(仅适用于输入为LSD的情况)。

//solidity
IERC20(inputLSDAddress).approve(vdAMMAddress, inputAmount);
//ethers.js
const IERC20ABI = ['function approve(address spender, uint256 amount) external returns (bool)']
const LSDTokenContract = new ethers.Contract(inputLSDAddress, IERC20ABI, provider)
await LSDTokenContract.approve(vdAMMAddress, inputAmount)

2. 设置预期的最小输出金额。

//solidity
uint256 slippage_tolerance  = 10;
// A 10 bps tolerance should be enough to take into consideration the differentiation between the time of calculation of the output amount and the actual output amount that will be calculated during the transaction.
uint256 minAmountOut = outputAmount*(10000 - slippage_tolerance)/10000;
//ethers.js
const slippageTolerance = 10
// A 10 bps tolerance should be enough to take into consideration the differentiation between the time of calculation of the output amount and the actual output amount that will be calculated during the transaction.
const minAmountOut = outputAmount.mul(10000 - slippageTolerance).div(10000)

3. 调用相应的交换函数

a) 交换LSD到LSD

//solidity
IVdAmm(vdAMMAddress).swapLsdToLsd(inputAmount, inputLSDAddress, outputLSDAddress, minAmountOut);
//ethers.js
await vdAmmContract.swapLsdToLsd(inputAmount, inputLSDAddress, outputLSDAddress, minAmountOut)

b) 交换LSD到ETH

//solidity
IVdAmm(vdAMMAddress).swapLsdToEth(inputAmount, inputLSDAddress, minAmountOut);
//ethers.js
await vdAmmContract.swapLsdToEth(inputAmount, inputLSDAddress, minAmountOut)

c) 交换ETH到LSD

//solidity
IVdAmm(vdAMMAddress).swapEthToLsd{value:inputAmount}(ouptutLSDAddress, minAmountOut);
//ethers.js
await vdAmmContract.swapEthToLsd(outputLSDAddress, minAmountOut, {
  value: inputAmount,
})