闪电贷
大约 1 分钟
闪电贷
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
interface IUniswapV2Callee {
function uniswapV2Call(
address sender,
uint256 amount0,
uint256 amount1,
bytes calldata data
) external;
}
contract UniswapV2FlashSwap is IUniswapV2Callee {
address private constant UNISWAP_V2_FACTORY =
0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f;
address private constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
address private constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
IUniswapV2Factory private constant factory =
IUniswapV2Factory(UNISWAP_V2_FACTORY);
IERC20 private constant weth = IERC20(WETH);
IUniswapV2Pair private immutable pair;
// For this example, store the amount to repay
uint256 public amountToRepay;
constructor() {
pair = IUniswapV2Pair(factory.getPair(DAI, WETH));
}
function flashSwap(uint256 wethAmount) external {
// Need to pass some data to trigger uniswapV2Call
bytes memory data = abi.encode(WETH, msg.sender);
// amount0Out is DAI, amount1Out is WETH
pair.swap(0, wethAmount, address(this), data);
}
// This function is called by the DAI/WETH pair contract
function uniswapV2Call(
address sender,
uint256 amount0,
uint256 amount1,
bytes calldata data
) external {
require(msg.sender == address(pair), "not pair");
require(sender == address(this), "not sender");
(address tokenBorrow, address caller) =
abi.decode(data, (address, address));
// Your custom code would go here. For example, code to arbitrage.
require(tokenBorrow == WETH, "token borrow != WETH");
// about 0.3% fee, +1 to round up
uint256 fee = (amount1 * 3) / 997 + 1;
amountToRepay = amount1 + fee;
// Transfer flash swap fee from caller
weth.transferFrom(caller, address(this), fee);
// Repay
weth.transfer(address(pair), amountToRepay);
}
}
interface IUniswapV2Pair {
function swap(
uint256 amount0Out,
uint256 amount1Out,
address to,
bytes calldata data
) external;
}
interface IUniswapV2Factory {
function getPair(address tokenA, address tokenB)
external
view
returns (address pair);
}
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount)
external
returns (bool);
function allowance(address owner, address spender)
external
view
returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount)
external
returns (bool);
}
interface IWETH is IERC20 {
function deposit() external payable;
function withdraw(uint256 amount) external;
}