兑换时报错 UniswapV2: TRANSFER_FAILED

我的本意是swap兑换时收取滑点,将滑点在兑换成USDT后转入指定地址, 但是现在一兑换就报错UniswapV2: TRANSFER_FAILED 请大佬解惑 交易对就是代币对USDT 0x81243a879538Afc45C6259130F00F307F16e2550是测试链USDT合约 `// SPDX-License-Identifier: MIT pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

interface IPancakeRouter { function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external; function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts); }

interface IPancakePair { function sync() external; }

interface IUniswapFactory { function getPair(address tokenA, address tokenB) external view returns (address pair); function createPair(address tokenA, address tokenB) external returns (address pair); }

contract TokenDistributor { constructor(address token) { IERC20(token).approve(msg.sender, type(uint256).max); // 授权给 router } }

contract BBXToken is ERC20, Ownable, ReentrancyGuard { using Address for address;

uint256 public immutable TOTAL_SUPPLY;
uint256 public buyTax = 1000; // 10%
uint256 public sellTax = 3000; // 30%
address public buyTaxWallet = 0x918f2aF5376a8B83a099a97DAB18b8ee63CFbC7a;
address public sellTaxWallet = 0x918f2aF5376a8B83a099a97DAB18b8ee63CFbC7a;
address public usdtToken = 0x81243a879538Afc45C6259130F00F307F16e2550;
address public liquidityPool;
address public mintSenderAddress = 0x918f2aF5376a8B83a099a97DAB18b8ee63CFbC7a;  // 只允许当前用户铸造代币
uint256 public burnRate = 300;
uint256 public lastBurnTime;
uint256 public lastBurnGapTime = 1 days;
uint256 public mintTotal;
IPancakeRouter public pancakeRouter;
TokenDistributor public _tokenDistributor;

bool private isInSwap;
mapping(address => bool) private isExcludedFromFee;

modifier onlyMint() {
    require(msg.sender == mintSenderAddress, "must be mint sender");
    _;
}

modifier lockTheSwap {
    isInSwap = true;
    _;
    isInSwap = false;
}

constructor(address initialOwner, address _router, address _factory) ERC20("BBX", "BBX") Ownable(initialOwner) {
    TOTAL_SUPPLY = 10_000_000 * 10 ** decimals();
    _mint(initialOwner, 100000 ether);
    mintTotal += 100000 ether;
    isExcludedFromFee[initialOwner] = true;
    isExcludedFromFee[address(this)] = true;
    pancakeRouter = IPancakeRouter(_router);
    lastBurnTime = block.timestamp;
    _tokenDistributor = new TokenDistributor(usdtToken);
    isExcludedFromFee[address(_tokenDistributor)] = true;
    liquidityPool = IUniswapFactory(_factory).createPair(address(this), usdtToken);
    _approve(address(this), liquidityPool, type(uint256).max);
    _approve(address(this), _router, type(uint256).max);
    IERC20(usdtToken).approve(_router, type(uint256).max);
    IERC20(usdtToken).approve(address(this), type(uint256).max);
}

function totalSupply() public view override returns (uint256) {
    return TOTAL_SUPPLY;
}

function mint(address _address, uint256 _amount) external onlyMint {
    require(_amount > 0, "must be greater than 0");
    require(mintTotal + _amount <= TOTAL_SUPPLY, "max mint");
    super._mint(_address, _amount);
    mintTotal += _amount;
}

function transfer(address recipient, uint256 amount) public override returns (bool) {
    if (block.timestamp >= lastBurnTime + lastBurnGapTime) {
        uint256 totalNum = this.balanceOf(liquidityPool);
        uint256 burnNum = totalNum * burnRate / 10000;
        super._transfer(liquidityPool, address(0xdead), burnNum);
        IPancakePair(liquidityPool).sync();
    }

    address sender = msg.sender;

    if (isExcludedFromFee[sender] || isExcludedFromFee[recipient]) {
        super._transfer(sender, recipient, amount);
        return true;
    }

    if (_isBuy(sender)) {
        uint256 taxAmount = (amount * buyTax) / 10000;
        uint256 amountAfterTax = amount - taxAmount;
        uint256 tax1 = (taxAmount * 20) / 30; // 20% 直接转给 buyTaxWallet
        uint256 tax2 = (taxAmount * 10) / 30; // 10% 换 targetToken
        super._transfer(sender, buyTaxWallet, tax1);
        super._transfer(sender, recipient, amountAfterTax);
        if (!isInSwap) {
            super._transfer(sender, address(this), tax2);
            _swapToTargetToken(buyTaxWallet, tax2); // 兑换USDT,再兑换目标代币
        }

    } else if (_isSell(recipient)) {
        uint256 taxAmount = (amount * sellTax) / 10000;
        uint256 amountAfterTax = amount - taxAmount;
        uint256 tax1 = (taxAmount * 20) / 30; // 20% 换 targetToken
        uint256 tax2 = (taxAmount * 10) / 30; // 10% 直接转给 sellTaxWallet
        super._transfer(sender, sellTaxWallet, tax2);
        super._transfer(sender, recipient, amountAfterTax);
        if (!isInSwap) {
            super._transfer(sender, address(this), tax1);
            _swapToTargetToken(buyTaxWallet, tax1); // 兑换USDT,再兑换目标代币
        }

    } else {
        super._transfer(sender, recipient, amount);
    }

    return true;
}

function _isBuy(address sender) private view returns (bool) {
    return sender == liquidityPool;
}

function _isSell(address recipient) private view returns (bool) {
    return recipient == liquidityPool;
}

function _swapToTargetToken(address to, uint256 amount) private lockTheSwap {
    require(balanceOf(address(this)) >= amount, "Not enough tokens");

    address[] memory path1 = new address[](2);
    path1[0] = address(this);
    path1[1] = usdtToken;

    pancakeRouter.swapExactTokensForTokensSupportingFeeOnTransferTokens(
        amount,
        0, // 设置合理的 amountOutMin
        path1,
        address(to),
        block.timestamp + 300
    );

    uint256 usdtBalance = IERC20(usdtToken).balanceOf(address(_tokenDistributor));
    require(usdtBalance > 0, "Swap to USDT failed");
}

function getAmountOutMin(uint256 amountIn, address[] memory path) private view returns (uint256) {
    uint256[] memory amounts = pancakeRouter.getAmountsOut(amountIn, path);
    return amounts[amounts.length - 1];
}

function setLiquidityPool(address pool) external onlyOwner {
    liquidityPool = pool;
    _approve(address(this), liquidityPool, type(uint256).max);
}

function setBuyTaxWallet(address _buyTaxWallet) external onlyOwner {
    buyTaxWallet = _buyTaxWallet;
}

function setSellTaxWallet(address _sellTaxWallet) external onlyOwner {
    sellTaxWallet = _sellTaxWallet;
}

function setTargetToken(address _targetToken) external onlyOwner {
    targetToken = _targetToken;
}

function setUsdtToken(address _usdtToken) external onlyOwner {
    usdtToken = _usdtToken;
}

function setMintSenderAddress(address _mintSenderAddress) external onlyOwner {
    mintSenderAddress = _mintSenderAddress;
}

function setBurnRate(uint256 _burnRate) external onlyOwner {
    burnRate = _burnRate;
}

function setLastBurnGapTime(uint256 _lastBurnGapTime) external onlyOwner {
    lastBurnGapTime = _lastBurnGapTime;
}

function setMintTotal(uint256 _mintTotal) external onlyOwner {
    mintTotal = _mintTotal;
}

function excludeFromFee(address account, bool excluded) external onlyOwner {
    isExcludedFromFee[account] = excluded;
}

receive() external payable nonReentrant {
    require(msg.value > 0, "No BNB sent");
    payable(mintSenderAddress).transfer(msg.value); // 转给 mint sender
}

}`

请先 登录 后评论

1 个回答

小溪
请先 登录 后评论
  • 1 关注
  • 0 收藏,1189 浏览
  • 提出于 2025-03-12 00:09