0%

Project-CoolErc20-four_way-区分买卖添加移除流动性行为的代币

Pre:

Erc20代币在买卖、添加/移除流动性的多个行为的过程中,都会调用到Transfer()函数,在代码层面上是只有转移的行为。那么如何在solidity里区分这几个行为呢?如果能够区分这几个行为的话,就能实现某些功能的定制化,例如税收等。

github仓库地址: https://github.com/jerrychan807/cool-erc20/tree/main/four_way

Token转移:

token发生转移时,会有发送方sender,接收方recipient可以把Buy、Sell、AddLiquidity、RemoveLiquidity分类为下面两种情况。

  1. sender为Pair,recipient为Token

1
2
Buy:
Usdt ——> Pair ——> Token
1
2
RemoveLiquidity:
LpToken ——> Pair ——> Usdt、Token
  1. sender为Token,recipient为Pair

1
2
Sell:
Token ——> Pair ——> Usdt
1
2
AddLiquidity:
Usdt、Token ——> Pair ——> LpToken
行为 sender recipient
Buy Pair Token
Sell Token Pair
AddLiquidity Token Pair
RemoveLiquidity Pair Token

那如何在smart contract里区分这四种行为呢?

在smart contract里区分:

关键的判断代码如下:

1
2
3
4
5
6
7
8
// 查询uniswap储备量
// 实例化pair
IUniswapV2Pair uniswapV2Pair = IUniswapV2Pair(uniswapV2PairAddress);
// 获取上一次swap的结果
(uint112 reserve0, uint112 reserve1,) = uniswapV2Pair.getReserves();
// Buy: Usdt↑ Token↓
if ((address(this) == uniswapV2Pair.token0() && IERC20(usdtAddress).balanceOf(uniswapV2PairAddress) > reserve1)
|| (address(this) == uniswapV2Pair.token1() && IERC20(usdtAddress).balanceOf(uniswapV2PairAddress) > reserve0)) {}

通过储备量的变化情况,来区分开这四种行为。

测试情况:

手动测试网测试:

行为 Fee
Buy 5%
Sell 10%
AddLiquidity 5%
RemoveLiquidity 10%
行为 Result tx
Buy ok tx
Sell fail tx
AddLiquidity ok tx
RemoveLiquidity ok tx

hardhat测试:

也是Sell这一步骤没能成功

一些知识点:

Uniswap的getreserves获取储备量函数

可以通过getreserves()获取pair里两类币种的储备量。

行为 reserve0(USDT)储备量变化 reserve1(XToken)储备量变化
Buy
Sell
AddLiquidity
RemoveLiquidity

在合约里调用其他合约

interface + 地址

1
2
3
4
5
import "./IUniswapV2Factory.sol";
// bsc testnet addr
address v2FactoryAddress = 0x182859893230dC89b114d6e2D547BFFE30474a21;
IUniswapV2Factory uniswapv2Factory = IUniswapV2Factory(v2FactoryAddress);
uniswapV2PairAddress = uniswapv2Factory.createPair(address(this), usdtAddress);

验证多合约源码:

  1. etherscan、bscscan直接将多个源代码文件上传即可

  2. 使用Hardhat验证 Solidity 源码 (Ethereum or BSC)

Refs: