合约构造阶段调用UniswapV2 addLiquidityETH添加流动性失败排查
问题:ERC20构造函数中调用UniswapV2 addLiquidityETH失败,单独调用正常
在ERC20合约的构造函数中调用UniswapV2的addLiquidityETH方法添加流动性时,交易在Router执行IUniswapV2Pair(pair).mint(to)步骤时回滚失败;但合约部署完成后,通过单独交易调用该方法则可成功执行。在Goerli测试网、以太坊主网及本地预编译Uniswap环境中测试,均返回Error: Transaction reverted without a reason string错误。
构造函数中调用_addLiquidity导致失败的代码示例
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol"; import "@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol"; contract SwappableLiquidityInDeploy is ERC20 { IUniswapV2Router02 private immutable _uniswapV2Router; address private immutable _uniswapV2Pair; constructor(address uniswapV2Router_) ERC20("Swappable", "SWAP") payable { uint256 initialBalance = 100000000 * 10 ** decimals(); _mint(address(this), initialBalance); _uniswapV2Router = IUniswapV2Router02(uniswapV2Router_); _uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory()).createPair( address(this), _uniswapV2Router.WETH() ); _addLiquidity(msg.value, initialBalance); } function _addLiquidity(uint256 ethAmount, uint256 tokenAmount) internal { _approve(address(this), address(_uniswapV2Router), tokenAmount); _uniswapV2Router.addLiquidityETH{value: ethAmount}( address(this), tokenAmount, 0, 0, address(this), block.timestamp ); } }
先部署再调用方法添加流动性成功的代码示例
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol"; import "@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol"; contract SwappableLiquidityInFunction is ERC20 { IUniswapV2Router02 private immutable _uniswapV2Router; address private immutable _uniswapV2Pair; constructor(address uniswapV2Router_) ERC20("Swappable", "SWAP") payable { uint256 initialBalance = 100000000 * 10 ** decimals(); _mint(address(this), initialBalance); _uniswapV2Router = IUniswapV2Router02(uniswapV2Router_); _uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory()).createPair( address(this), _uniswapV2Router.WETH() ); } function addLiquidityMock() public payable { _addLiquidity(msg.value, totalSupply()); } function _addLiquidity(uint256 ethAmount, uint256 tokenAmount) internal { _approve(address(this), address(_uniswapV2Router), tokenAmount); _uniswapV2Router.addLiquidityETH{value: ethAmount}( address(this), tokenAmount, 0, 0, address(this), block.timestamp ); } }
内容的提问来源于stack exchange,提问作者vittominacori
相关产品推荐
相关产品推荐

