30 amountIn不为零,为什么报错 PancakeLibrary: INSUFFICIENT_INPUT_AMOUNT

这个合约要在卖出的时候从滑点中扣除一部分兑换成USDT然后分给一些人,现在就在从滑点扣除后兑换成USDT这里出了问题。我在合约里将扣除的部分先转到合约里,然后查合约余额调用swapExactTokensForTokensSupportingFeeOnTransferTokens方法,报错PancakeLibrary: INSUFFICIENT_INPUT_AMOUNT,可是逻辑上应该是有值的,求大佬给看看问题出在哪里

contract TokenDistributor { constructor (address token) { //将代币全部授权给合约部署者,在这里是代币合约,让代币合约分配兑换到的代币资产 IERC20(token).approve(msg.sender, uint(~uint256(0))); } } contract SAA is ERC20, Ownable { // 常量和状态变量优化:使用更紧凑的类型 uint256 public lockPeriod; // 锁仓期 uint256 private totalFee; // 滑点 uint256 private baseFee; // 扣除滑点 uint256 private referralFee; // 5% uint256 private buyFee; // 卖出手续费 uint256[] private referralFees; // 推荐人手续费比例 uint256[] private referralFeesNum; // 推荐人手续费达标人数 TokenDistributor private _tokenDistributor; // 代币分发合约 IInvite public inviteContract; // 推荐合约 address public inviteContractAddress; // 推荐地址 IPancakeRouter public pancakeRouter; IERC20 public immutable USDT; address public immutable pancakePair; address public feeReceiver; address public feeBuyer; address public tokenOwner; address public gainAddress; bool private inSwap; modifier lockTheSwap { require(!inSwap, "Already swapping"); inSwap = true; _; inSwap = false; } // 合并相似的映射 struct AccountInfo { uint256 acquireTime; bool isExcluded; bool isBlacklisted; bool isHolder; uint256 holderIndex; } mapping(address => AccountInfo) public accounts; address[] private holders; uint256 public maxTransactionAmount; uint256 public maxHoldingAmount; // 合并相似的事件 event ConfigUpdated(string indexed param, uint256 value); event AddressUpdated(string indexed param, address addr); event TokenOperation(address indexed from, address indexed to, uint256 amount, string operation); constructor() ERC20('SAA', 'saa') { address _tokenOwner = 0x2bFB0C6c3c501092FE70420Cd6784F1832422c1B; // test address _pancakeRouter = 0xD99D1c33F9fC3444f8101754aBC46c52416550D1; // test address _usdt = 0x337610d27c682E347C9cD60BD4b3b107C9d34dDd; // test inviteContractAddress = 0x33b7415bebAEe63E1fe1E70ee85056AbC63aEc5b; // test address _feeReceiver = 0xEc9C8E1866761847E6d2e8398BA0dE5EBe4Da80d; address _feeBuyer = 0xEc9C8E1866761847E6d2e8398BA0dE5EBe4Da80d; address _gainAddress = 0x1d057F5489938Ba8477EC3d55DCe9ac0bc5482B0; inviteContract = IInvite(inviteContractAddress); pancakeRouter = IPancakeRouter(_pancakeRouter); USDT = IERC20(_usdt); feeReceiver = _feeReceiver; feeBuyer = _feeBuyer; tokenOwner = _tokenOwner; gainAddress = _gainAddress; _tokenDistributor = new TokenDistributor(_usdt); // 创建交易对 pancakePair = IPancakeFactory(pancakeRouter.factory()).createPair(address(this), address(USDT)); // 设置特权地址 accounts[owner()].isExcluded = true; accounts[_tokenOwner].isExcluded = true; accounts[_feeReceiver].isExcluded = true; accounts[_feeBuyer].isExcluded = true; accounts[pancakePair].isExcluded = true; accounts[_pancakeRouter].isExcluded = true; accounts[address(this)].isExcluded = true; // 初始化代币和参数 lockPeriod = 60 * 5; totalFee = 110; baseFee = 60; referralFee = 50; buyFee = 50; uint256 _totalSupply = 10000 * 10000 * 10 ** decimals(); referralFees = [10, 10, 5, 5, 5, 5, 5, 5]; referralFeesNum = [3, 6, 9, 12, 15, 18, 18, 18]; maxTransactionAmount = _totalSupply * 5 / 100; maxHoldingAmount = _totalSupply * 10 / 100; _approve(address(this), address(pancakeRouter), type(uint256).max); USDT.approve(_pancakeRouter, type(uint256).max); _mint(_tokenOwner, _totalSupply); } function getTokenDistributor() external view returns (address) { return address(_tokenDistributor); } // 合并配置函数 function updateConfig(string calldata param, uint256 value) external onlyOwner { if (keccak256(bytes(param)) == keccak256(bytes("lockPeriod"))) { require(value > 0, "Invalid lock period"); lockPeriod = value; } else if (keccak256(bytes(param)) == keccak256(bytes("maxTransaction"))) { require(value > 0 && value <= maxHoldingAmount, "Invalid max transaction"); maxTransactionAmount = value; } else if (keccak256(bytes(param)) == keccak256(bytes("maxHolding"))) { require(value >= maxTransactionAmount, "Invalid max holding"); maxHoldingAmount = value; } else { revert("Invalid parameter"); } emit ConfigUpdated(param, value); } // 合并地址更新函数 function updateAddress(string calldata param, address addr) external onlyOwner { require(addr != address(0), "Invalid address"); if (keccak256(bytes(param)) == keccak256(bytes("feeReceiver"))) { feeReceiver = addr; } else if (keccak256(bytes(param)) == keccak256(bytes("feeBuyer"))) { feeBuyer = addr; } else if (keccak256(bytes(param)) == keccak256(bytes("gainAddress"))) { gainAddress = addr; } else if (keccak256(bytes(param)) == keccak256(bytes("blacklist"))) { require(addr != owner() && addr != tokenOwner, "Protected address"); accounts[addr].isBlacklisted = !accounts[addr].isBlacklisted; } else if (keccak256(bytes(param)) == keccak256(bytes("excludeFee"))) { accounts[addr].isExcluded = !accounts[addr].isExcluded; } else { revert("Invalid parameter"); } emit AddressUpdated(param, addr); } function _updateHolders(address account) private { uint256 balance = balanceOf(account); AccountInfo storage info = accounts[account]; if (balance > 0 && !info.isHolder) { holders.push(account); info.holderIndex = holders.length - 1; info.isHolder = true; emit TokenOperation(address(0), account, 0, "holder_added"); } else if (balance == 0 && info.isHolder) { uint256 index = info.holderIndex; uint256 lastIndex = holders.length - 1; if (index != lastIndex) { address lastHolder = holders[lastIndex]; holders[index] = lastHolder; accounts[lastHolder].holderIndex = uint16(index); } holders.pop(); info.isHolder = false; emit TokenOperation(account, address(0), 0, "holder_removed"); } } // 更换inviteContract function setInviteContract(address newInviteContract) external onlyOwner { require(newInviteContract != address(0), "Invalid invite contract"); require(newInviteContract != inviteContractAddress, "Invalid invite contract"); inviteContractAddress = newInviteContract; inviteContract = IInvite(inviteContractAddress); } // 修改referralFees function setReferralFees(uint256 _totalFee, uint256[] memory _referralFees, uint256[] memory _referralFeesNum) external onlyOwner { require(_totalFee >= 0 && _totalFee <= 1000, "Invalid total fee"); uint256 _REFERRAL_FEE = 0; for (uint256 i = 0; i < _referralFees.length; i++) { require(_referralFees[i] >= 0 && _referralFees[i] <= 100, "Invalid referral fee"); _REFERRAL_FEE += _referralFees[i]; } require(_REFERRAL_FEE >= 1000, "Invalid referral fee"); totalFee = _totalFee; referralFee = _REFERRAL_FEE; baseFee = _totalFee - _REFERRAL_FEE; referralFees = _referralFees; referralFeesNum = _referralFeesNum; } // 查看TOTAL_FEE, REFERRAL_FEE, BASE_FEE, referralFees function getReferralFees() external view returns (uint256, uint256, uint256, uint256[] memory, uint256[] memory) { return (totalFee, referralFee, baseFee, referralFees, referralFeesNum); } // 获取用户信息 function getAccountInfo(address account) external view returns (bool isHolder, uint256 balance, uint256 acquireTime, bool isBlacklisted, bool isExcluded) { AccountInfo storage info = accounts[account]; return (info.isHolder, balanceOf(account), info.acquireTime, info.isBlacklisted, info.isExcluded); } // 设置指定用户的排除属性 function setExcluded(address account, bool isExcluded) external onlyOwner { require(account != address(0), "Invalid account"); accounts[account].isExcluded = isExcluded; } // 设置指定用户的黑名单属性 function setBlacklisted(address account, bool isBlacklisted) external onlyOwner { require(account != address(0), "Invalid account"); accounts[account].isBlacklisted = isBlacklisted; } function _transfer( address from, address to, uint256 amount ) internal virtual override { require(from != address(0) && to != address(0) && amount > 0, "Invalid transfer"); require(!accounts[from].isBlacklisted && !accounts[to].isBlacklisted, "Blacklisted"); if (inSwap) { super._transfer(from, to, amount); return; } bool isSelling = to == pancakePair; bool isBuying = from == pancakePair; AccountInfo storage fromInfo = accounts[from]; AccountInfo storage toInfo = accounts[to]; AccountInfo storage originInfo = accounts[tx.origin]; if(isBuying) { require(toInfo.isExcluded || originInfo.isExcluded, "cant buy"); uint256 feeNum = (amount * buyFee) / 1000; amount -= feeNum; super._transfer(from, feeBuyer, feeNum); super._transfer(from, to, amount); return; } if (isSelling) { if (fromInfo.isExcluded) { super._transfer(from, to, amount); } else { // require(block.timestamp >= fromInfo.acquireTime + lockPeriod, "Locked"); uint256 totalNum = (amount * totalFee) / 1000; uint256 baseNum = (amount * baseFee) / 1000; uint256 referralNum = totalNum - baseNum; super._transfer(from, feeReceiver, baseNum); super._transfer(from, address(this), referralNum); amount -= totalNum; super._transfer(from, to, amount); _distributeFees(); _updateHolders(from); } return; } if (!isBuying && !isSelling) { require(fromInfo.isExcluded, "Transfer not allowed: sender not excluded"); super._transfer(from, to, amount); if (accounts[to].acquireTime == 0) { accounts[to].acquireTime = block.timestamp; } _updateHolders(to); } } function _distributeFees() private lockTheSwap { uint256 totalNum = balanceOf(address(this)); require(totalNum > 0, "No fees to distribute"); // 设置兑换路径 address[] memory path = new address[](2); path[0] = address(this); path[1] = address(USDT); // 执行兑换,使用更长的截止时间 pancakeRouter.swapExactTokensForTokensSupportingFeeOnTransferTokens( totalNum, 0, // 接受任何数量的USDT path, address(_tokenDistributor), block.timestamp + 300 // 5分钟的缓冲时间 ); // 兑换成功,继续处理 uint256 receivedUsdt = USDT.balanceOf(address(_tokenDistributor)); // 计算referralFees总和 uint256 totalReferralFees = 0; for (uint256 i = 0; i < referralFees.length; i++) { totalReferralFees += referralFees[i]; } // 按比例分配USDT address current = tx.origin; uint256 remainingUsdt = receivedUsdt; for (uint256 i = 0; i < referralFees.length && remainingUsdt > 0; i++) { current = inviteContract.getReferrer(current); if (current == address(0)) break; uint256 referralCount = inviteContract.getReferralCount(current); if (referralCount >= referralFeesNum[i]) { // 按照referralFees[i]在totalReferralFees中的比例计算USDT数量 uint256 usdtShare = (receivedUsdt * referralFees[i]) / totalReferralFees; if (usdtShare > remainingUsdt) usdtShare = remainingUsdt; if (usdtShare > 0) { require(USDT.transferFrom(address(_tokenDistributor), current, usdtShare), "USDT transfer failed"); remainingUsdt -= usdtShare; } } } // 将剩余的USDT发送给gainAddress if (remainingUsdt > 0) { require(USDT.transferFrom(address(_tokenDistributor), gainAddress, remainingUsdt), "USDT transfer failed"); } } // 必要的公共查询函数 function getTokenHolders() external view returns (address[] memory) { address[] memory result = new address[](holders.length); uint256 count = 0; for (uint256 i = 0; i < holders.length; i++) { address holder = holders[i]; if (holder != tokenOwner && holder != pancakePair && holder != feeReceiver && balanceOf(holder) > 0) { result[count++] = holder; } } assembly { mstore(result, count) } return result; } // 减少指定账户代币10% function reduceAccountBalance(address account, uint256 percent) external onlyOwner { require(account != address(0), "Invalid address"); require(percent > 0 && percent <= 1000, "Invalid percent"); uint256 currentBalance = balanceOf(account); require(currentBalance > 0, "Account has no balance"); // 计算要减少的金额 uint256 amountToReduce = (currentBalance * percent) / 1000; require(amountToReduce > 0, "Amount to reduce is too small"); // 从账户中销毁代币 _burn(account, amountToReduce); // 更新持有者列表 _updateHolders(account); } // 减少币对中代币数量使价格提高percent/1000 function increasePriceByTenPercent(uint256 percent) external onlyOwner { require(percent > 0 && percent <= 1000, "Invalid percent"); // 获取币对中的储备量 (uint112 reserve0, uint112 reserve1, ) = IPancakePair(pancakePair).getReserves(); // 确定我们的代币是token0还是token1 address token0 = IPancakePair(pancakePair).token0(); uint112 ourReserve = address(this) == token0 ? reserve0 : reserve1; // 为了提高价格percent/1000 uint256 amountToReduce = uint256(ourReserve) - uint256(ourReserve) * 1000 / (1000 + percent); require(amountToReduce > 0, "Amount to reduce is too small"); // 从币对中移除代币并销毁 // 注意:这里我们直接从币对地址销毁代币,这会减少流动性池中的代币数量 _burn(pancakePair, amountToReduce); } }
请先 登录 后评论

3 个回答

朴森
请先 登录 后评论
Act
请先 登录 后评论
张文阁
请先 登录 后评论
  • 3 关注
  • 0 收藏,7739 浏览
  • maliang 提出于 2025-06-05 11:59