UniswapV2
大约 2 分钟
UniswapV2
Uniswap V2是一个去中心化交易所(DEX),基于以太坊区块链,允许用户直接在区块链上进行代币交换,而无需中介。
工作原理
Uniswap V2采用了自动做市商(AMM)模型,通过流动性池(liquidity pool)进行交易。用户可以向流动性池添加代币,并根据提供的流动性获得手续费的分成。交易价格由恒定产品公式确定,即 x * y = k
,其中x
和y
分别是池中两种代币的数量,k
是一个常量。
如何使用
- 连接钱包:使用MetaMask等钱包连接到Uniswap网站。
- 选择代币:选择你想交易的代币对。
- 输入金额:输入要交换的代币数量。
- 确认交易:检查交易信息并确认。
Router地址
https://docs.uniswap.org/contracts/v2/reference/smart-contracts/v2-deployments
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
contract UniswapV2SwapExamples {
address private constant UNISWAP_V2_ROUTER =0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
address private constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address private constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
address constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
IUniswapV2Router private router = IUniswapV2Router(UNISWAP_V2_ROUTER);
IERC20 private weth = IERC20(WETH);
IERC20 private dai = IERC20(DAI);
// Swap WETH to DAI
function swapSingleHopExactAmountIn(uint256 amountIn, uint256 amountOutMin)
external
returns (uint256 amountOut)
{
weth.transferFrom(msg.sender, address(this), amountIn);
weth.approve(address(router), amountIn);
address[] memory path;
path = new address[](2);
path[0] = WETH;
path[1] = DAI;
uint256[] memory amounts = router.swapExactTokensForTokens(
amountIn, amountOutMin, path, msg.sender, block.timestamp
);
// amounts[0] = WETH amount, amounts[1] = DAI amount
return amounts[1];
}
// Swap DAI -> WETH -> USDC
function swapMultiHopExactAmountIn(uint256 amountIn, uint256 amountOutMin)
external
returns (uint256 amountOut)
{
dai.transferFrom(msg.sender, address(this), amountIn);
dai.approve(address(router), amountIn);
address[] memory path;
path = new address[](3);
path[0] = DAI;
path[1] = WETH;
path[2] = USDC;
uint256[] memory amounts = router.swapExactTokensForTokens(
amountIn, amountOutMin, path, msg.sender, block.timestamp
);
// amounts[0] = DAI amount
// amounts[1] = WETH amount
// amounts[2] = USDC amount
return amounts[2];
}
// Swap WETH to DAI
function swapSingleHopExactAmountOut(
uint256 amountOutDesired,
uint256 amountInMax
) external returns (uint256 amountOut) {
weth.transferFrom(msg.sender, address(this), amountInMax);
weth.approve(address(router), amountInMax);
address[] memory path;
path = new address[](2);
path[0] = WETH;
path[1] = DAI;
uint256[] memory amounts = router.swapTokensForExactTokens(
amountOutDesired, amountInMax, path, msg.sender, block.timestamp
);
// Refund WETH to msg.sender
if (amounts[0] < amountInMax) {
weth.transfer(msg.sender, amountInMax - amounts[0]);
}
return amounts[1];
}
// Swap DAI -> WETH -> USDC
function swapMultiHopExactAmountOut(
uint256 amountOutDesired,
uint256 amountInMax
) external returns (uint256 amountOut) {
dai.transferFrom(msg.sender, address(this), amountInMax);
dai.approve(address(router), amountInMax);
address[] memory path;
path = new address[](3);
path[0] = DAI;
path[1] = WETH;
path[2] = USDC;
uint256[] memory amounts = router.swapTokensForExactTokens(
amountOutDesired, amountInMax, path, msg.sender, block.timestamp
);
// Refund DAI to msg.sender
if (amounts[0] < amountInMax) {
dai.transfer(msg.sender, amountInMax - amounts[0]);
}
return amounts[2];
}
}
interface IUniswapV2Router {
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapTokensForExactTokens(
uint256 amountOut,
uint256 amountInMax,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
}
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;
}