Flashswap 学习笔记(附代码)

本文介绍了DeFi领域的创新操作——Flashswap,它利用交易的原子性,在一笔交易中完成借贷与还款。通过智能合约实现瞬间借入资产,进行交换,然后立即偿还,从而在不持有资产的情况下进行交易。示例代码展示了如何在Uniswap上执行Flashswap操作,涉及了UniswapV2Router02、WETH、USDT等代币的交互过程。
摘要由CSDN通过智能技术生成

什么是Flashswap?

利用交易的原子性,可以在这样的同一笔交易中调用智能合约,同时完成借和还,参考下图:

Flashswap流程+代码

流程:

代码

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.5.0;

import "./IERC20.sol";

interface pair {
  function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external ;
}

interface uniRoutr {
  function swapExactTokensForTokens(
      uint amountIn,
      uint amountOutMin,
      address[] calldata path,
      address to,
      uint deadline
      ) external  returns (uint[] memory amounts);

  function getAmountsIn(uint amountOut, address[] calldata path) external returns (uint[] memory amounts);
}

interface IWETH {
  function deposit() external payable;
  function transfer(address to, uint value) external returns (bool);
  function withdraw(uint) external;
}


contract Flashswap {
  // UniswapV2Router02 合约地址
  address public ROUTE = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;

  // UniswapV2Pair 合约地址
  address public USDTWETH = 0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852;
  address public WETH  = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
  address public USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7; 
  address public USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;

  uint256 public swapamount;
  uint256 public ETHamount;

  bytes _data = bytes("flashswap");

  event Blance(uint256 amount);

  constructor() public {
    safeApprove(WETH, ROUTE, uint(-1));
    safeApprove(USDT, ROUTE, uint(-1));
    safeApprove(USDC, ROUTE, uint(-1));
  }

  function deposit() public payable {
    // 获取存款金额
    ETHamount = msg.value;
    // 将ETH存入 WETH 合约
    IWETH(WETH).deposit.value(ETHamount)();
    emit Blance(IERC20(WETH).balanceOf(address(this)));
  }

  function getCurrBlance() public view returns (uint){
    return IERC20(WETH).balanceOf(address(this)); 
  }

  function uniswapV2Call(address sender, uint amount0, uint amount1, bytes memory data) public {
    // 获取当前地址的  借入的USDT余额
    uint256 balance0 = IERC20(USDT).balanceOf(address(this));
    emit Blance(balance0);

    // 创建交易路由 UDST-USDC
    address[] memory path1 = new address[](2);
    path1[0] = USDT;
    path1[1] = USDC;
    // 将USDT换成USDC amounts1[1] 为USDC 
    uint[] memory amounts1 = uniRoutr(ROUTE).swapExactTokensForTokens(balance0, uint(0), path1, address(this), block.timestamp + 1800);
    emit Blance(uint256(amounts1[1]));

    // 创建交易路由 USDC-ETH
    address[] memory path2 = new address[](2);
    path2[0] = USDC;
    path2[1] = WETH;
    // 将USDC换成ETH amounts1[1] 为ETH
    uint[] memory amounts2 = uniRoutr(ROUTE).swapExactTokensForTokens(amounts1[1], uint(0), path2, address(this), block.timestamp + 1800);
    emit Blance(amounts2[1]);

    address[] memory path3 = new address[](2);
    path3[0] = WETH;
    path3[1] = USDT;
    // 获取借入 swapamount USDT 需要还多少ETH
    uint[] memory amounts3 = uniRoutr(ROUTE).getAmountsIn(swapamount, path3);
    emit Blance(amounts3[0]);

    // 向USDTWETH合约还WETH 
    IERC20(WETH).transfer(USDTWETH, amounts3[0]);
    emit Blance(ETHamount - amounts2[0]);
  }

  function swap (uint256 _swapamount) public {
    swapamount = _swapamount; 
    pair(USDTWETH).swap(uint(0), _swapamount, address(this), _data);
  }

  function safeApprove(address token, address to, uint value) internal {
    (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
    require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED');
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值