PETRODAO.SOL
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/math/Math.sol";
interface IERC1363Receiver {
function onTokenTransfer(address from, uint256 amount, bytes calldata data) external returns (bool);
}
interface IERC1363Spender {
function onApprovalReceived(address owner, uint256 amount, bytes calldata data) external returns (bool);
}
// 接收方回调接口
interface ITokenReceiver {
function tokenReceived(address from, uint256 amount) external returns (bool);
}
// ---------- Custom Errors (reduce runtime bytecode size) ----------
error TransfersDisabled();
error SenderRestricted();
error AddressBlocked();
error AmountZero();
error InsufficientUnlocked();
error InsufficientBalance();
error TimeNotInFuture();
error BadAddress();
error LengthMismatch();
error EmptyArray();
error Overflow();
error BadIndex();
error LockAlreadyRemoved();
error NoLocks();
error NoNative();
error NativeTokenTransferFailed();
error CannotRecoverSelf();
error MintExceedsMaxSupply();
error BurnExceedsSupply();
error RateTooHigh();
error NotExists();
error Expired();
error LocksMax();
error TransferCallbackFailed();
error ApprovalCallbackFailed();
error BadMax();
contract PetroDAO is ERC20, Ownable, ReentrancyGuard {
uint256 public constant MAX_TOTAL_SUPPLY = 3000000000000 * (10 ** 18); // 30000亿代币
uint256 public maxSupply;
bool public transfersEnabled = true; // 全局转账开关
mapping(address => bool) public transferDisabled; // 记录被禁止转账的账户
mapping(address => bool) public transferBlocked; // 记录无法发送 & 接收的账户
// 记录哪些地址启用了自动回调
mapping(address => bool) public transferOnCallEnabled;
// 手续费配置(PPQ:千千万亿分比,分母 1e15)与白名单
// FEE_DENOMINATOR = 1,000,000,000,000,000 (1e15)
uint256 public constant FEE_DENOMINATOR = 1000000000000000;
// 费率: feePpq / FEE_DENOMINATOR(不是百分比)
// Normal: 0.000001% -> 10,000,000 PPQ,最小: 0.001 代币
uint256 public normalFeePpq = 10000000;
uint256 public normalMinFee = 1000000000000000;
// Whitelist: 0.0000001% -> 1,000,000 PPQ,最小: 0.0001 代币
uint256 public whitelistFeePpq = 1000000;
uint256 public whitelistMinFee = 100000000000000;
// SuperWhitelist: 0.00000001% -> 100,000 PPQ,最小: 0.00001 代币
uint256 public superWhitelistFeePpq = 100000;
uint256 public superWhitelistMinFee = 10000000000000;
// VIP: 0.000000001% -> 10,000 PPQ,最小: 0.000001 代币
uint256 public vipFeePpq = 10000;
uint256 public vipMinFee = 1000000000000;
// VVIP: 0.0000000001% -> 1,000 PPQ,最小: 0.0000001 代币
uint256 public vvipFeePpq = 1000;
uint256 public vvipMinFee = 100000000000;
// VVVIP: 0.000000000001% -> 10 PPQ,最小: 0.000000001 代币
uint256 public vvvipFeePpq = 10;
uint256 public vvvipMinFee = 1000000000;
mapping(address => bool) public whitelist;
mapping(address => bool) public superWhitelist;
mapping(address => bool) public vip;
mapping(address => bool) public vvip;
mapping(address => bool) public vvvip;
// 自动白名单阈值(基于持仓,用户可自助升级;仅上调,不会自动降级)
uint256 public autoWhitelistThreshold; // 例如 10 * 1e18
uint256 public autoSuperWhitelistThreshold; // 例如 100000 * 1e18
uint256 public autoVipThreshold; // 例如 1000000 * 1e18
// 手续费豁免
mapping(address => bool) public feeExemptSender; // 作为发送方豁免
mapping(address => bool) public feeExemptReceiver; // 作为接收方豁免
uint256 public maxLocksPerAddress = 16;
address public recoverWallet; // 误转代币接收地址(默认 Owner)
address public feeRecipient; // 手续费接收地址(为 0 时烧毁)
// 折扣配置:持有指定代币达到阈值享 50% 折扣(可叠加)
address public discountToken; // 可配置的ERC20代币地址
uint256 public senderDiscountThreshold; // 发送方阈值,例如 1000 * 10^18
uint256 public receiverDiscountThreshold; // 接收方阈值,例如 10 * 10^18
// 特定合约地址的额外手续费
mapping(address => uint256) public contractExtraFee; // 记录每个合约地址的额外手续费
// 付费VIP1结构(最优先,覆盖所有其他手续费功能)
struct PaidVip1Info {
uint256 feePpq; // 手续费率(PPQ:分母 1e15)
uint256 minFee; // 最小手续费(wei)
uint256 expireTime; // 过期时间戳
}
mapping(address => PaidVip1Info) public paidVip1Status; // 付费VIP1状态
// 锁仓结构
struct LockedBalance {
uint256 amount;
uint256 unlockTime;
}
// 增强的锁仓结构,支持按索引查询
struct LockInfo {
uint256 amount;
uint256 releaseTime;
}
mapping(address => LockedBalance) public lockedBalances;
// 按索引存储的锁仓记录
mapping(address => LockInfo[]) public locks;
mapping(address => uint256) public totalLocked;
uint256 public totalHold; // 全局锁仓总量
event Minted(address indexed to, uint256 amount);
event TransferDisabled(address indexed account);
event TransferEnabled(address indexed account);
event BurnMaxSupply(uint256 amount);
event TransferBlocked(address indexed account);
event TransferUnblocked(address indexed account);
event TokensLocked(address indexed account, uint256 amount, uint256 unlockTime);
event TokensUnlocked(address indexed account, uint256 amount);
event RecoverWalletUpdated(address indexed newWallet);
event ApprovalAndCall(address indexed owner, address indexed spender, uint256 amount);
event NativeTokenRecovered(address indexed to, uint256 amount);
event Burned(address indexed burner, uint256 amount);
event ApprovalIncreased(address indexed owner, address indexed spender, uint256 addedValue);
event ApprovalDecreased(address indexed owner, address indexed spender, uint256 subtractedValue);
event LockAdded(address indexed to, uint256 amount, uint256 releaseTime);
event LockRemoved(address indexed from, uint256 amount);
event TransferOnCallEnabled(address indexed account);
event TransferOnCallDisabled(address indexed account);
event TransferOnCallExecuted(address indexed from, address indexed to, uint256 amount, bool success);
event TransferWithCallExecuted(address indexed from, address indexed to, uint256 amount, bool success);
// 新增:手续费与白名单相关事件
event FeeConfigUpdated(
uint256 normalFeePpq,
uint256 normalMinFee,
uint256 whitelistFeePpq,
uint256 whitelistMinFee,
uint256 superWhitelistFeePpq,
uint256 superWhitelistMinFee
);
event WhitelistUpdated(address indexed account, bool enabled);
event SuperWhitelistUpdated(address indexed account, bool enabled);
event VipUpdated(address indexed account, bool enabled);
event VvipUpdated(address indexed account, bool enabled);
event VvvipUpdated(address indexed account, bool enabled);
event TransferFeeBurned(address indexed from, uint256 fee);
event ExpiredLocksPruned(address indexed account, uint256 processed, uint256 totalAmount);
event MaxLocksPerAddressUpdated(uint256 newMax);
event FeeExemptSenderUpdated(address indexed account, bool enabled);
event FeeExemptReceiverUpdated(address indexed account, bool enabled);
event FeeRecipientUpdated(address indexed newRecipient);
event DiscountConfigUpdated(address indexed token, uint256 senderThreshold, uint256 receiverThreshold);
event ContractExtraFeeUpdated(address indexed contractAddr, uint256 extraFee);
event PaidVip1Set(address indexed account, uint256 feePpq, uint256 minFee, uint256 expireTime);
event PaidVip1Removed(address indexed account);
event AutoWhitelistConfigUpdated(uint256 whitelistThreshold, uint256 superWhitelistThreshold);
event AutoWhitelistApplied(address indexed account, bool whitelistUpgraded, bool superWhitelistUpgraded);
event AutoVipConfigUpdated(uint256 vipThreshold);
event AutoVipApplied(address indexed account, bool vipUpgraded);
constructor() ERC20("PetroCash DAO", "PetroDAO") Ownable(msg.sender) {
// 设置最大供应量,但初始不铸造任何代币
maxSupply = MAX_TOTAL_SUPPLY;
recoverWallet = msg.sender;
// 默认合约 owner 作为发送方免手续费(批量发送/运营用途)
feeExemptSender[msg.sender] = true;
feeRecipient = address(0); // 默认烧毁
// 默认自动白名单阈值(可后续由 onlyOwner 修改)
autoWhitelistThreshold = 10 * (10 ** 18);
autoSuperWhitelistThreshold = 100000 * (10 ** 18);
autoVipThreshold = 1000000 * (10 ** 18);
}
// 内部函数:检查地址是否为合约
function _isContract(address addr) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(addr)
}
return size > 0;
}
// 设置手续费接收地址(设为 0 表示烧毁)
function setFeeRecipient(address newRecipient) external onlyOwner {
// 允许设为 0 以恢复烧毁
feeRecipient = newRecipient;
emit FeeRecipientUpdated(newRecipient);
}
// 设置折扣代币与阈值
function setDiscountConfig(address token, uint256 senderThreshold, uint256 receiverThreshold) external onlyOwner {
discountToken = token; // 允许为0表示不启用折扣
senderDiscountThreshold = senderThreshold;
receiverDiscountThreshold = receiverThreshold;
emit DiscountConfigUpdated(token, senderThreshold, receiverThreshold);
}
// 设置特定合约地址的额外手续费
function setContractExtraFee(address contractAddr, uint256 extraFee) external onlyOwner {
contractExtraFee[contractAddr] = extraFee;
emit ContractExtraFeeUpdated(contractAddr, extraFee);
}
// 移除特定合约地址的额外手续费
function removeContractExtraFee(address contractAddr) external onlyOwner {
contractExtraFee[contractAddr] = 0;
emit ContractExtraFeeUpdated(contractAddr, 0);
}
// 查询地址是否设置了额外手续费
function hasContractExtraFee(address contractAddr) external view returns (bool) {
return contractExtraFee[contractAddr] > 0;
}
// 设置付费VIP1(覆盖所有其他手续费功能,最优先)
// feePpq: 手续费率(PPQ,分母 1e15)
// minFee: 最小手续费(wei),例如 0.000000001 PETRO = 1000000000 wei
// expireTime: 过期时间戳(uint256),必须大于当前时间戳
function setPaidVip1(address account, uint256 feePpq, uint256 minFee, uint256 expireTime) external onlyOwner {
if (feePpq > FEE_DENOMINATOR) revert RateTooHigh();
if (expireTime <= block.timestamp) revert TimeNotInFuture();
if (account == address(0)) revert BadAddress();
paidVip1Status[account] = PaidVip1Info({
feePpq: feePpq,
minFee: minFee,
expireTime: expireTime
});
emit PaidVip1Set(account, feePpq, minFee, expireTime);
}
// 更新付费VIP1的最小手续费(不改变其他设置)
function setPaidVip1MinFee(address account, uint256 minFee) external onlyOwner {
PaidVip1Info storage vip1 = paidVip1Status[account];
if (vip1.expireTime == 0) revert NotExists();
if (block.timestamp >= vip1.expireTime) revert Expired();
vip1.minFee = minFee;
emit PaidVip1Set(account, vip1.feePpq, minFee, vip1.expireTime);
}
// 移除付费VIP1
function removePaidVip1(address account) external onlyOwner {
delete paidVip1Status[account];
emit PaidVip1Removed(account);
}
// 查询付费VIP1状态
function getPaidVip1Status(address account) external view returns (bool isActive, uint256 feePpq, uint256 minFee, uint256 expireTime, uint256 remainingTime) {
PaidVip1Info memory vip1 = paidVip1Status[account];
if (vip1.expireTime == 0) {
return (false, 0, 0, 0, 0);
}
bool active = block.timestamp < vip1.expireTime;
uint256 remaining = active ? (vip1.expireTime - block.timestamp) : 0;
return (active, vip1.feePpq, vip1.minFee, vip1.expireTime, remaining);
}
// **Mint(增发代币)**
function mint(address _to, uint256 _amount) external onlyOwner {
if (totalSupply() + _amount > maxSupply) revert MintExceedsMaxSupply();
_mint(_to, _amount);
emit Minted(_to, _amount);
}
// **增加 maxSupply(允许未来增发)**
function increaseMaxSupply(uint256 amount) external onlyOwner {
if (amount == 0) revert AmountZero();
maxSupply += amount;
}
// 关闭/开启全局转账
function setTransfersEnabled(bool _enabled) external onlyOwner {
transfersEnabled = _enabled;
}
// 禁止某个地址转账
function disableTransfer(address account) external onlyOwner {
transferDisabled[account] = true;
emit TransferDisabled(account);
}
// 允许某个地址恢复转账
function enableTransfer(address account) external onlyOwner {
transferDisabled[account] = false;
emit TransferEnabled(account);
}
// 冻结某个地址(无法发送 & 接收)
function blockTransfer(address account) external onlyOwner {
transferBlocked[account] = true;
emit TransferBlocked(account);
}
// 解除冻结
function unblockTransfer(address account) external onlyOwner {
transferBlocked[account] = false;
emit TransferUnblocked(account);
}
// 新增:手续费配置与白名单管理(PPQ:分母 1e15)
function setFeeConfig(
uint256 _normalFeePpq,
uint256 _normalMinFee,
uint256 _whitelistFeePpq,
uint256 _whitelistMinFee,
uint256 _superWhitelistFeePpq,
uint256 _superWhitelistMinFee,
uint256 _vipFeePpq,
uint256 _vipMinFee,
uint256 _vvipFeePpq,
uint256 _vvipMinFee,
uint256 _vvvipFeePpq,
uint256 _vvvipMinFee
) external onlyOwner {
if (!(_normalFeePpq <= FEE_DENOMINATOR && _whitelistFeePpq <= FEE_DENOMINATOR && _superWhitelistFeePpq <= FEE_DENOMINATOR)) revert RateTooHigh();
if (!(_vipFeePpq <= FEE_DENOMINATOR && _vvipFeePpq <= FEE_DENOMINATOR && _vvvipFeePpq <= FEE_DENOMINATOR)) revert RateTooHigh();
normalFeePpq = _normalFeePpq;
normalMinFee = _normalMinFee;
whitelistFeePpq = _whitelistFeePpq;
whitelistMinFee = _whitelistMinFee;
superWhitelistFeePpq = _superWhitelistFeePpq;
superWhitelistMinFee = _superWhitelistMinFee;
vipFeePpq = _vipFeePpq;
vipMinFee = _vipMinFee;
vvipFeePpq = _vvipFeePpq;
vvipMinFee = _vvipMinFee;
vvvipFeePpq = _vvvipFeePpq;
vvvipMinFee = _vvvipMinFee;
emit FeeConfigUpdated(normalFeePpq, normalMinFee, whitelistFeePpq, whitelistMinFee, superWhitelistFeePpq, superWhitelistMinFee);
}
function setWhitelist(address account, bool enabled) external onlyOwner {
whitelist[account] = enabled;
emit WhitelistUpdated(account, enabled);
}
function setSuperWhitelist(address account, bool enabled) external onlyOwner {
superWhitelist[account] = enabled;
emit SuperWhitelistUpdated(account, enabled);
}
function setVip(address account, bool enabled) external onlyOwner {
vip[account] = enabled;
emit VipUpdated(account, enabled);
}
function setVvip(address account, bool enabled) external onlyOwner {
vvip[account] = enabled;
emit VvipUpdated(account, enabled);
}
function setVvvip(address account, bool enabled) external onlyOwner {
vvvip[account] = enabled;
emit VvvipUpdated(account, enabled);
}
function setWhitelistBatch(address[] calldata accounts, bool enabled) external onlyOwner {
for (uint256 i = 0; i < accounts.length; i++) {
whitelist[accounts[i]] = enabled;
emit WhitelistUpdated(accounts[i], enabled);
}
}
function setSuperWhitelistBatch(address[] calldata accounts, bool enabled) external onlyOwner {
for (uint256 i = 0; i < accounts.length; i++) {
superWhitelist[accounts[i]] = enabled;
emit SuperWhitelistUpdated(accounts[i], enabled);
}
}
function setVipBatch(address[] calldata accounts, bool enabled) external onlyOwner {
for (uint256 i = 0; i < accounts.length; i++) {
vip[accounts[i]] = enabled;
emit VipUpdated(accounts[i], enabled);
}
}
function setVvipBatch(address[] calldata accounts, bool enabled) external onlyOwner {
for (uint256 i = 0; i < accounts.length; i++) {
vvip[accounts[i]] = enabled;
emit VvipUpdated(accounts[i], enabled);
}
}
function setVvvipBatch(address[] calldata accounts, bool enabled) external onlyOwner {
for (uint256 i = 0; i < accounts.length; i++) {
vvvip[accounts[i]] = enabled;
emit VvvipUpdated(accounts[i], enabled);
}
}
// 配置基于持仓的自动白名单阈值(仅 Owner)
function setAutoWhitelistThresholds(uint256 whitelistThreshold, uint256 superWhitelistThreshold) external onlyOwner {
autoWhitelistThreshold = whitelistThreshold;
autoSuperWhitelistThreshold = superWhitelistThreshold;
emit AutoWhitelistConfigUpdated(whitelistThreshold, superWhitelistThreshold);
}
// 配置基于持仓的自动 VIP 阈值(仅 Owner)
function setAutoVipThreshold(uint256 vipThreshold) external onlyOwner {
autoVipThreshold = vipThreshold;
emit AutoVipConfigUpdated(vipThreshold);
}
// 用户自助申请基于当前持仓的白名单升级(只会上调,不会下调)
// 返回值为是否被升级到 whitelist / superWhitelist
function applyWhitelistUpgrade() external returns (bool whitelistUpgraded, bool superWhitelistUpgraded) {
uint256 bal = balanceOf(msg.sender);
if (autoSuperWhitelistThreshold > 0 && bal >= autoSuperWhitelistThreshold && !superWhitelist[msg.sender]) {
superWhitelist[msg.sender] = true;
superWhitelistUpgraded = true;
emit SuperWhitelistUpdated(msg.sender, true);
}
if (autoWhitelistThreshold > 0 && bal >= autoWhitelistThreshold && !whitelist[msg.sender]) {
whitelist[msg.sender] = true;
whitelistUpgraded = true;
emit WhitelistUpdated(msg.sender, true);
}
if (whitelistUpgraded || superWhitelistUpgraded) {
emit AutoWhitelistApplied(msg.sender, whitelistUpgraded, superWhitelistUpgraded);
}
}
// 用户自助申请基于当前持仓的 VIP 升级(只会上调,不会下调)
function applyVipUpgrade() external returns (bool vipUpgraded) {
uint256 bal = balanceOf(msg.sender);
if (autoVipThreshold > 0 && bal >= autoVipThreshold && !vip[msg.sender]) {
vip[msg.sender] = true;
vipUpgraded = true;
emit VipUpdated(msg.sender, true);
emit AutoVipApplied(msg.sender, true);
}
}
function setMaxLocksPerAddress(uint256 newMax) external onlyOwner {
if (newMax < 1 || newMax > 64) revert BadMax();
maxLocksPerAddress = newMax;
emit MaxLocksPerAddressUpdated(newMax);
}
// 手续费豁免管理
function setFeeExemptSender(address account, bool enabled) external onlyOwner {
feeExemptSender[account] = enabled;
emit FeeExemptSenderUpdated(account, enabled);
}
function setFeeExemptSenderBatch(address[] calldata accounts, bool enabled) external onlyOwner {
for (uint256 i = 0; i < accounts.length; i++) {
feeExemptSender[accounts[i]] = enabled;
emit FeeExemptSenderUpdated(accounts[i], enabled);
}
}
function setFeeExemptReceiver(address account, bool enabled) external onlyOwner {
feeExemptReceiver[account] = enabled;
emit FeeExemptReceiverUpdated(account, enabled);
}
function setFeeExemptReceiverBatch(address[] calldata accounts, bool enabled) external onlyOwner {
for (uint256 i = 0; i < accounts.length; i++) {
feeExemptReceiver[accounts[i]] = enabled;
emit FeeExemptReceiverUpdated(accounts[i], enabled);
}
}
// 变更所有权时,切换豁免到新 owner
function transferOwnership(address newOwner) public override onlyOwner {
address oldOwner = owner();
super.transferOwnership(newOwner);
feeExemptSender[oldOwner] = false;
feeExemptSender[newOwner] = true;
}
// 检查地址是否可以转账
function canBeTransfered(address _addr, uint256 value) public view returns (bool) {
if (!transfersEnabled) return false;
if (transferDisabled[_addr]) return false;
if (transferBlocked[_addr]) return false;
if (_getUnlockedBalance(_addr) < value) return false;
return true;
}
// 启用 TransferOnCall 功能
function enableTransferOnCall() external {
transferOnCallEnabled[msg.sender] = true;
emit TransferOnCallEnabled(msg.sender);
}
// 禁用 TransferOnCall 功能
function disableTransferOnCall() external {
transferOnCallEnabled[msg.sender] = false;
emit TransferOnCallDisabled(msg.sender);
}
// 重写 _update 函数以支持 TransferOnCall 和收取手续费(加法模式:收款方收到全额,发送方额外支付手续费)
function _update(address from, address to, uint256 amount) internal override {
// 铸造或销毁不收取手续费
if (from == address(0) || to == address(0)) {
super._update(from, to, amount);
return;
}
// 统一的限制检查(涵盖 multiSend 等所有路径)
if (!transfersEnabled) revert TransfersDisabled();
if (transferDisabled[from]) revert SenderRestricted();
if (transferBlocked[from] || transferBlocked[to]) revert AddressBlocked();
if (amount == 0) revert AmountZero();
// 计算手续费(与金额独立转移)
uint256 feeAmount = _calculateFee(from, to, amount);
// 发送方需要有 amount + fee 的未锁定余额
uint256 required = amount + feeAmount;
if (_getUnlockedBalance(from) < required) revert InsufficientUnlocked();
// 先扣手续费
if (feeAmount > 0) {
address recipient = feeRecipient;
if (recipient == address(0)) {
super._update(from, address(0), feeAmount);
emit TransferFeeBurned(from, feeAmount);
} else {
super._update(from, recipient, feeAmount);
}
}
// 再转全额给接收方
super._update(from, to, amount);
// TransferOnCall(传递全额 amount)
if (_isContract(to) && transferOnCallEnabled[to]) {
bool success = _executeTransferOnCall(from, to, amount);
emit TransferOnCallExecuted(from, to, amount, success);
}
}
// 执行 TransferOnCall 回调 - 优化版本
function _executeTransferOnCall(address from, address to, uint256 amount) internal returns (bool) {
try ITokenReceiver(to).tokenReceived(from, amount) returns (bool success) {
return success;
} catch {
// 接收方回调失败不影响转账,只是返回失败状态
return false;
}
}
// 计算可用余额(避免下溢)
function _getUnlockedBalance(address account) internal view returns (uint256) {
uint256 bal = balanceOf(account);
uint256 locked = getLockedBalance(account);
return bal > locked ? bal - locked : 0;
}
// 获取手续费参数(付费VIP1最优先,覆盖所有其他手续费功能)
function _getFeeParams(address from) internal view returns (uint256 ppq, uint256 minFee) {
// 最优先检查付费VIP1,如果有效则覆盖所有其他手续费功能
PaidVip1Info memory vip1 = paidVip1Status[from];
if (vip1.expireTime > 0 && block.timestamp < vip1.expireTime) {
// 付费VIP1使用自定义的ppq和minFee
return (vip1.feePpq, vip1.minFee);
}
// 如果没有付费VIP1,则按原有逻辑
if (vvvip[from]) {
return (vvvipFeePpq, vvvipMinFee);
}
if (vvip[from]) {
return (vvipFeePpq, vvipMinFee);
}
if (vip[from]) {
return (vipFeePpq, vipMinFee);
}
if (superWhitelist[from]) {
return (superWhitelistFeePpq, superWhitelistMinFee);
}
if (whitelist[from]) {
return (whitelistFeePpq, whitelistMinFee);
}
return (normalFeePpq, normalMinFee);
}
// 查询某地址费率层级与参数(付费VIP1优先)
function getFeeTier(address account) external view returns (string memory tier, uint256 ppq, uint256 minFee) {
if (feeExemptSender[account] || feeExemptReceiver[account]) {
return ("exempt", 0, 0);
}
// 最优先检查付费VIP1,如果有效则覆盖所有其他手续费功能
PaidVip1Info memory vip1 = paidVip1Status[account];
if (vip1.expireTime > 0 && block.timestamp < vip1.expireTime) {
return ("paidvip1", vip1.feePpq, vip1.minFee);
}
if (vvvip[account]) {
return ("vvvip", vvvipFeePpq, vvvipMinFee);
}
if (vvip[account]) {
return ("vvip", vvipFeePpq, vvipMinFee);
}
if (vip[account]) {
return ("vip", vipFeePpq, vipMinFee);
}
if (superWhitelist[account]) {
return ("super", superWhitelistFeePpq, superWhitelistMinFee);
}
if (whitelist[account]) {
return ("whitelist", whitelistFeePpq, whitelistMinFee);
}
return ("normal", normalFeePpq, normalMinFee);
}
// 预估手续费(加法模式):若在豁免名单则为 0;否则按层级费率和最小费取较大值
function estimateFee(address from, address to, uint256 amount) external view returns (uint256) {
if (amount == 0) revert AmountZero();
return _calculateFee(from, to, amount);
}
function _findLockIndex(address _addr, uint256 releaseTime) internal view returns (bool found, uint256 index) {
for (uint256 i = 0; i < locks[_addr].length; i++) {
if (locks[_addr][i].releaseTime == releaseTime) {
return (true, i);
}
}
return (false, 0);
}
function _isFeeExempt(address from, address to) internal view returns (bool) {
if (feeExemptSender[from]) return true;
if (feeExemptReceiver[to]) return true;
return false;
}
// 内部函数:应用折扣到手续费
function _applyDiscount(address from, address to, uint256 amount, uint256 fee) internal view returns (uint256) {
if (discountToken == address(0) || fee == 0) return fee;
uint256 discountedFee = fee;
// 发送方折扣
if (senderDiscountThreshold > 0) {
if (IERC20(discountToken).balanceOf(from) >= senderDiscountThreshold &&
balanceOf(from) >= amount + senderDiscountThreshold) {
discountedFee = discountedFee / 2;
}
}
// 接收方折扣
if (receiverDiscountThreshold > 0) {
if (IERC20(discountToken).balanceOf(to) >= receiverDiscountThreshold) {
discountedFee = discountedFee / 2;
}
}
return discountedFee;
}
// 计算手续费:若豁免则 0;否则 max(mulDiv(amount, ppq, FEE_DENOMINATOR), minFee) + 合约额外手续费(也会受折扣影响)
function _calculateFee(address from, address to, uint256 amount) internal view returns (uint256) {
if (_isFeeExempt(from, to)) return 0;
(uint256 ppq, uint256 minFee) = _getFeeParams(from);
uint256 percentFee = Math.mulDiv(amount, ppq, FEE_DENOMINATOR);
uint256 fee = percentFee > minFee ? percentFee : minFee;
// 添加合约额外手续费
uint256 extraFee = contractExtraFee[to];
if (extraFee > 0) {
fee += extraFee;
}
// 应用折扣
return _applyDiscount(from, to, amount, fee);
}
// **自定义 Transfer**(收款方收全额,发送方额外支付手续费)
function transfer(address to, uint256 amount) public override nonReentrant returns (bool) {
if (!transfersEnabled) revert TransfersDisabled();
if (transferDisabled[msg.sender]) revert SenderRestricted();
if (transferBlocked[msg.sender] || transferBlocked[to]) revert AddressBlocked();
uint256 feeAmount = _calculateFee(msg.sender, to, amount);
if (amount == 0) revert AmountZero();
if (_getUnlockedBalance(msg.sender) < amount + feeAmount) revert InsufficientUnlocked();
_transfer(msg.sender, to, amount);
// 回调传递全额 amount
_callOnTokenTransfer(msg.sender, to, amount, "");
return true;
}
function transferFrom(address from, address to, uint256 amount) public override nonReentrant returns (bool) {
if (!transfersEnabled) revert TransfersDisabled();
if (transferDisabled[from]) revert SenderRestricted();
if (transferBlocked[from] || transferBlocked[to]) revert AddressBlocked();
uint256 feeAmount = _calculateFee(from, to, amount);
if (amount == 0) revert AmountZero();
if (_getUnlockedBalance(from) < amount + feeAmount) revert InsufficientUnlocked();
_spendAllowance(from, msg.sender, amount);
_transfer(from, to, amount);
// 回调传递全额 amount
_callOnTokenTransfer(from, to, amount, "");
return true;
}
// 支持 转账 + 回调 - 优化版本(收款方收全额,发送方额外支付手续费)
function transferWithCall(address to, uint256 amount, bytes calldata data) public nonReentrant returns (bool) {
if (!transfersEnabled) revert TransfersDisabled();
if (transferDisabled[msg.sender]) revert SenderRestricted();
if (transferBlocked[msg.sender] || transferBlocked[to]) revert AddressBlocked();
uint256 feeAmount = _calculateFee(msg.sender, to, amount);
if (amount == 0) revert AmountZero();
if (_getUnlockedBalance(msg.sender) < amount + feeAmount) revert InsufficientUnlocked();
_transfer(msg.sender, to, amount);
bool success = _callOnTokenTransfer(msg.sender, to, amount, data);
emit TransferWithCallExecuted(msg.sender, to, amount, success);
if (!success) revert TransferCallbackFailed();
return true;
}
// 支持 批准 + 回调
function approveAndCall(address spender, uint256 amount, bytes calldata data) public nonReentrant returns (bool) {
if (transferDisabled[msg.sender]) revert SenderRestricted();
if (transferBlocked[msg.sender] || transferBlocked[spender]) revert AddressBlocked();
_approve(msg.sender, spender, amount);
bool success = true; // 默认成功,如果spender不是合约则直接成功
if (_isContract(spender)) {
try IERC1363Spender(spender).onApprovalReceived(msg.sender, amount, data) returns (bool callSuccess) {
success = callSuccess;
} catch {
revert ApprovalCallbackFailed();
}
}
if (!success) revert ApprovalCallbackFailed();
emit ApprovalAndCall(msg.sender, spender, amount);
return true;
}
// 增加授权额度
function increaseApproval(address _spender, uint256 _addedValue) public returns (bool) {
uint256 currentAllowance = allowance(msg.sender, _spender);
_approve(msg.sender, _spender, currentAllowance + _addedValue);
emit ApprovalIncreased(msg.sender, _spender, _addedValue);
return true;
}
// 减少授权额度
function decreaseApproval(address _spender, uint256 _subtractedValue) public returns (bool) {
uint256 currentAllowance = allowance(msg.sender, _spender);
uint256 newAllowance = currentAllowance > _subtractedValue ? currentAllowance - _subtractedValue : 0;
_approve(msg.sender, _spender, newAllowance);
emit ApprovalDecreased(msg.sender, _spender, _subtractedValue);
return true;
}
// 改进回调函数,确保调用失败时回滚
function _callOnTokenTransfer(address from, address to, uint256 amount, bytes memory data) internal returns (bool) {
if (_isContract(to)) {
try IERC1363Receiver(to).onTokenTransfer(from, amount, data) returns (bool success) {
return success;
} catch {
return false;
}
}
return true;
}
// **锁仓**
function lockTokens(address account, uint256 amount, uint256 unlockTime) external onlyOwner {
if (balanceOf(account) < amount) revert InsufficientBalance();
if (unlockTime <= block.timestamp) revert TimeNotInFuture();
lockedBalances[account].amount += amount;
lockedBalances[account].unlockTime = unlockTime;
emit TokensLocked(account, amount, unlockTime);
}
// 新增锁仓函数,支持按索引存储
function lock(address _to, uint256 releaseTime, uint256 lockamount) external onlyOwner {
if (balanceOf(_to) < lockamount) revert InsufficientBalance();
if (releaseTime <= block.timestamp) revert TimeNotInFuture();
if (lockamount == 0) revert AmountZero();
// 添加溢出检查
if (totalLocked[_to] + lockamount < totalLocked[_to]) revert Overflow();
(bool found, uint256 idx) = _findLockIndex(_to, releaseTime);
if (found) {
locks[_to][idx].amount += lockamount;
} else {
if (locks[_to].length >= maxLocksPerAddress) revert LocksMax();
locks[_to].push(LockInfo({
amount: lockamount,
releaseTime: releaseTime
}));
}
totalLocked[_to] += lockamount;
totalHold += lockamount;
emit LockAdded(_to, lockamount, releaseTime);
}
// 移除指定地址的所有锁仓
function removeHoldByAddress(address _address) external onlyOwner {
uint256 totalAmount = totalLocked[_address];
if (totalAmount == 0) revert NoLocks();
delete locks[_address];
totalHold -= totalAmount; // 使用保存的totalAmount而不是totalLocked[_address]
totalLocked[_address] = 0;
emit LockRemoved(_address, totalAmount);
}
// 移除指定地址的指定索引锁仓
function removeHoldByAddressIndex(address _address, uint256 _index) external onlyOwner {
if (_index >= locks[_address].length) revert BadIndex();
uint256 amount = locks[_address][_index].amount;
if (amount == 0) revert LockAlreadyRemoved();
totalHold -= amount;
totalLocked[_address] -= amount;
// 移除指定索引的锁仓记录
if (_index < locks[_address].length - 1) {
locks[_address][_index] = locks[_address][locks[_address].length - 1];
}
locks[_address].pop();
emit LockRemoved(_address, amount);
}
// 清理已到期的锁仓,避免累积 O(n) 遍历
function pruneExpiredLocks(address _address, uint256 maxToProcess) external returns (uint256 processed, uint256 totalReleased) {
uint256 i = 0;
while (i < locks[_address].length && processed < maxToProcess) {
if (locks[_address][i].releaseTime <= block.timestamp) {
uint256 amount = locks[_address][i].amount;
totalHold -= amount;
totalLocked[_address] -= amount;
if (i < locks[_address].length - 1) {
locks[_address][i] = locks[_address][locks[_address].length - 1];
}
locks[_address].pop();
processed += 1;
totalReleased += amount;
} else {
i += 1;
}
}
if (processed > 0) {
emit ExpiredLocksPruned(_address, processed, totalReleased);
}
}
// 获取指定地址的锁仓记录数量
function getlockslen(address _address) public view returns (uint256) {
return locks[_address].length;
}
// 获取指定地址的指定索引锁仓记录
function getlocksbyindex(address _address, uint256 _index) public view returns (uint256 amount, uint256 releaseTime) {
if (_index >= locks[_address].length) revert BadIndex();
LockInfo memory lockData = locks[_address][_index];
return (lockData.amount, lockData.releaseTime);
}
// 获取全局锁仓总量
function gettotalHold() public view returns (uint256) {
return totalHold;
}
// **解锁**
function unlockTokens(address account) external onlyOwner {
uint256 amount = lockedBalances[account].amount;
if (amount == 0) revert NoLocks();
lockedBalances[account].amount = 0;
lockedBalances[account].unlockTime = 0;
emit TokensUnlocked(account, amount);
}
function getLockedBalance(address account) public view returns (uint256) {
uint256 lockedAmount = 0;
// 检查旧的锁仓机制
if (block.timestamp < lockedBalances[account].unlockTime) {
lockedAmount += lockedBalances[account].amount;
}
// 检查新的锁仓机制
for (uint256 i = 0; i < locks[account].length; i++) {
if (block.timestamp < locks[account][i].releaseTime) {
lockedAmount += locks[account][i].amount;
}
}
return lockedAmount;
}
function getAccountBalance(address account) public view returns (uint256 available, uint256 locked) {
uint256 lockedAmount = getLockedBalance(account);
uint256 bal = balanceOf(account);
uint256 avail = bal > lockedAmount ? bal - lockedAmount : 0;
return (avail, lockedAmount);
}
// **销毁代币,并减少 maxSupply**
function burnMaxSupply(uint256 amount) external onlyOwner {
if (amount == 0) revert AmountZero();
if (amount > totalSupply()) revert BurnExceedsSupply();
_burn(msg.sender, amount);
maxSupply -= amount;
emit BurnMaxSupply(amount);
}
// 普通销毁
function burn(uint256 amount) public {
if (amount == 0) revert AmountZero();
if (_getUnlockedBalance(msg.sender) < amount) revert InsufficientUnlocked();
_burn(msg.sender, amount);
emit Burned(msg.sender, amount);
}
// **允许 onlyOwner 销毁**
function burnFrom(address account, uint256 amount) public onlyOwner {
_burn(account, amount);
emit Burned(account, amount);
}
// **误转代币找回 - ERC20代币**
function recoverTokens(address token, uint256 amount) external onlyOwner {
if (token == address(this)) revert CannotRecoverSelf();
IERC20(token).transfer(recoverWallet, amount);
}
// **误转代币找回 - 批量ERC20代币**
function recoverAllTokens(address[] calldata tokens) external onlyOwner {
for (uint256 i = 0; i < tokens.length; i++) {
if (tokens[i] != address(this)) {
uint256 balance = IERC20(tokens[i]).balanceOf(address(this));
if (balance > 0) {
IERC20(tokens[i]).transfer(recoverWallet, balance);
}
}
}
}
// **误转原生代币找回**
function recoverNativeToken() external onlyOwner {
uint256 balance = address(this).balance;
if (balance == 0) revert NoNative();
(bool success, ) = recoverWallet.call{value: balance}("");
if (!success) revert NativeTokenTransferFailed();
emit NativeTokenRecovered(recoverWallet, balance);
}
// **设置误转代币接收地址**
function setNewRecoverWallet(address newWallet) external onlyOwner {
if (newWallet == address(0)) revert BadAddress();
recoverWallet = newWallet;
emit RecoverWalletUpdated(newWallet);
}
// **批量发送代币** - 优化版本(收款方收全额,发送方额外支付手续费)
function multiSend(address[] calldata _recipients, uint256[] calldata _amounts) external onlyOwner nonReentrant returns (bool) {
if (_recipients.length != _amounts.length) revert LengthMismatch();
if (_recipients.length == 0) revert EmptyArray();
uint256 totalAmount = 0;
uint256 totalFee = 0;
for (uint256 i = 0; i < _recipients.length; i++) {
if (_recipients[i] == address(0)) revert BadAddress();
totalAmount += _amounts[i];
if (totalAmount < _amounts[i]) revert Overflow();
uint256 fee = _calculateFee(msg.sender, _recipients[i], _amounts[i]);
totalFee += fee;
if (totalFee < fee) revert Overflow();
}
if (!transfersEnabled) revert TransfersDisabled();
if (transferDisabled[msg.sender]) revert SenderRestricted();
if (transferBlocked[msg.sender]) revert AddressBlocked();
if (_getUnlockedBalance(msg.sender) < totalAmount + totalFee) revert InsufficientUnlocked();
for (uint256 i = 0; i < _recipients.length; i++) {
if (transferBlocked[_recipients[i]]) revert AddressBlocked();
_transfer(msg.sender, _recipients[i], _amounts[i]);
}
return true;
}
// 批量增发代币(按地址-金额)
function multiMint(address[] calldata _recipients, uint256[] calldata _amounts) external onlyOwner returns (bool) {
if (_recipients.length != _amounts.length) revert LengthMismatch();
if (_recipients.length == 0) revert EmptyArray();
uint256 totalMint = 0;
for (uint256 i = 0; i < _recipients.length; i++) {
if (_recipients[i] == address(0)) revert BadAddress();
if (transferBlocked[_recipients[i]]) revert AddressBlocked();
uint256 amount = _amounts[i];
if (amount == 0) revert AmountZero();
totalMint += amount;
if (totalMint < amount) revert Overflow();
}
if (totalSupply() + totalMint > maxSupply) revert MintExceedsMaxSupply();
for (uint256 i = 0; i < _recipients.length; i++) {
_mint(_recipients[i], _amounts[i]);
emit Minted(_recipients[i], _amounts[i]);
}
return true;
}
// 接收原生代币
receive() external payable {}
// ========== 诊断和检查函数 ==========
// 获取账户完整状态信息(用于诊断)
function getAccountStatus(address account) external view returns (
uint256 balance,
uint256 unlockedBalance,
uint256 lockedBalance,
bool isTransferDisabled,
bool isTransferBlocked,
bool isWhitelist,
bool isSuperWhitelist,
bool isVip,
bool isVvip,
bool isVvvip,
bool isFeeExemptSender,
bool isFeeExemptReceiver,
bool hasPaidVip1,
bool paidVip1Active,
uint256 lockCount
) {
balance = balanceOf(account);
unlockedBalance = _getUnlockedBalance(account);
lockedBalance = getLockedBalance(account);
isTransferDisabled = transferDisabled[account];
isTransferBlocked = transferBlocked[account];
isWhitelist = whitelist[account];
isSuperWhitelist = superWhitelist[account];
isVip = vip[account];
isVvip = vvip[account];
isVvvip = vvvip[account];
isFeeExemptSender = feeExemptSender[account];
isFeeExemptReceiver = feeExemptReceiver[account];
PaidVip1Info memory vip1 = paidVip1Status[account];
hasPaidVip1 = vip1.expireTime > 0;
paidVip1Active = hasPaidVip1 && block.timestamp < vip1.expireTime;
lockCount = locks[account].length;
}
// 获取手续费计算明细(用于调试)
function getFeeBreakdown(address from, address to, uint256 amount) external view returns (
bool isExempt,
string memory tier,
uint256 feePpq,
uint256 minFee,
uint256 percentFee,
uint256 baseFee,
uint256 extraFeeAmount,
uint256 feeBeforeDiscount,
bool hasSenderDiscount,
bool hasReceiverDiscount,
uint256 finalFee
) {
// 检查豁免
if (_isFeeExempt(from, to)) {
return (true, "exempt", 0, 0, 0, 0, 0, 0, false, false, 0);
}
// 获取费率层级
(tier, feePpq, minFee) = this.getFeeTier(from);
// 计算基础手续费
percentFee = Math.mulDiv(amount, feePpq, FEE_DENOMINATOR);
baseFee = percentFee > minFee ? percentFee : minFee;
// 添加合约额外手续费
extraFeeAmount = contractExtraFee[to];
feeBeforeDiscount = baseFee + extraFeeAmount;
// 检查折扣条件
if (discountToken != address(0) && feeBeforeDiscount > 0) {
if (senderDiscountThreshold > 0) {
hasSenderDiscount = IERC20(discountToken).balanceOf(from) >= senderDiscountThreshold &&
balanceOf(from) >= amount + senderDiscountThreshold;
}
if (receiverDiscountThreshold > 0) {
hasReceiverDiscount = IERC20(discountToken).balanceOf(to) >= receiverDiscountThreshold;
}
}
// 应用折扣计算最终手续费
finalFee = feeBeforeDiscount;
if (hasSenderDiscount) {
finalFee = finalFee / 2;
}
if (hasReceiverDiscount) {
finalFee = finalFee / 2;
}
return (false, tier, feePpq, minFee, percentFee, baseFee, extraFeeAmount, feeBeforeDiscount, hasSenderDiscount, hasReceiverDiscount, finalFee);
}
// 检查转账可行性(完整检查)
function checkTransferFeasibility(address from, address to, uint256 amount) external view returns (
bool feasible,
string memory reason,
uint256 requiredBalance,
uint256 availableBalance,
uint256 feeAmount,
bool transfersEnabledStatus,
bool senderNotDisabled,
bool senderNotBlocked,
bool receiverNotBlocked,
bool hasEnoughBalance
) {
transfersEnabledStatus = transfersEnabled;
senderNotDisabled = !transferDisabled[from];
senderNotBlocked = !transferBlocked[from];
receiverNotBlocked = !transferBlocked[to];
if (!transfersEnabledStatus) {
return (false, "Transfers disabled", 0, 0, 0, false, senderNotDisabled, senderNotBlocked, receiverNotBlocked, false);
}
if (!senderNotDisabled) {
return (false, "Sender restricted", 0, 0, 0, true, false, senderNotBlocked, receiverNotBlocked, false);
}
if (!senderNotBlocked || !receiverNotBlocked) {
return (false, "Address blocked", 0, 0, 0, true, true, senderNotBlocked, receiverNotBlocked, false);
}
if (amount == 0) {
return (false, "Amount zero", 0, 0, 0, true, true, true, true, false);
}
feeAmount = _calculateFee(from, to, amount);
requiredBalance = amount + feeAmount;
availableBalance = _getUnlockedBalance(from);
hasEnoughBalance = availableBalance >= requiredBalance;
if (!hasEnoughBalance) {
return (false, "Insufficient balance", requiredBalance, availableBalance, feeAmount, true, true, true, true, false);
}
return (true, "Feasible", requiredBalance, availableBalance, feeAmount, true, true, true, true, true);
}
// 获取所有手续费配置(用于检查)
function getAllFeeConfigs() external view returns (
uint256 normalPpq,
uint256 normalMin,
uint256 whitelistPpq,
uint256 whitelistMin,
uint256 superWhitelistPpq,
uint256 superWhitelistMin,
uint256 vipPpq,
uint256 vipMin,
uint256 vvipPpq,
uint256 vvipMin,
uint256 vvvipPpq,
uint256 vvvipMin
) {
return (
normalFeePpq, normalMinFee,
whitelistFeePpq, whitelistMinFee,
superWhitelistFeePpq, superWhitelistMinFee,
vipFeePpq, vipMinFee,
vvipFeePpq, vvipMinFee,
vvvipFeePpq, vvvipMinFee
);
}
// 获取折扣配置(用于检查)
function getDiscountConfig() external view returns (
address token,
uint256 senderThreshold,
uint256 receiverThreshold,
bool isEnabled
) {
return (discountToken, senderDiscountThreshold, receiverDiscountThreshold, discountToken != address(0));
}
// 获取折扣状态(用于检查)
function getDiscountStatus(address account, uint256 amount) external view returns (
bool senderEligible,
bool receiverEligible,
uint256 senderBalance,
uint256 receiverBalance,
uint256 petroBalance
) {
if (discountToken == address(0)) {
return (false, false, 0, 0, 0);
}
senderBalance = IERC20(discountToken).balanceOf(account);
receiverBalance = senderBalance; // 接收方和发送方是同一个地址
petroBalance = balanceOf(account);
senderEligible = senderDiscountThreshold > 0 &&
senderBalance >= senderDiscountThreshold &&
petroBalance >= amount + senderDiscountThreshold;
receiverEligible = receiverDiscountThreshold > 0 && receiverBalance >= receiverDiscountThreshold;
return (senderEligible, receiverEligible, senderBalance, receiverBalance, petroBalance);
}
// 获取锁仓详情(用于检查)
function getLockDetails(address account) external view returns (
uint256 totalLockedAmount,
uint256 activeLockCount,
uint256[] memory lockAmounts,
uint256[] memory releaseTimes,
bool[] memory isExpired
) {
totalLockedAmount = totalLocked[account];
uint256 lockCount = locks[account].length;
activeLockCount = 0;
lockAmounts = new uint256[](lockCount);
releaseTimes = new uint256[](lockCount);
isExpired = new bool[](lockCount);
for (uint256 i = 0; i < lockCount; i++) {
LockInfo memory lockInfo = locks[account][i];
lockAmounts[i] = lockInfo.amount;
releaseTimes[i] = lockInfo.releaseTime;
bool expired = block.timestamp >= lockInfo.releaseTime;
isExpired[i] = expired;
if (!expired) {
activeLockCount++;
}
}
}
// 获取合约状态(用于检查)
function getContractStatus() external view returns (
uint256 totalSupplyValue,
uint256 maxSupplyValue,
uint256 totalHoldValue,
bool transfersEnabledStatus,
address feeRecipientAddress,
address recoverWalletAddress,
uint256 maxLocksPerAddressValue
) {
return (
totalSupply(),
maxSupply,
totalHold,
transfersEnabled,
feeRecipient,
recoverWallet,
maxLocksPerAddress
);
}
// 检查地址的所有白名单状态
function getAllWhitelistStatus(address account) external view returns (
bool whitelistStatus,
bool superWhitelistStatus,
bool vipStatus,
bool vvipStatus,
bool vvvipStatus,
bool paidVip1StatusActive,
bool feeExemptSenderStatus,
bool feeExemptReceiverStatus
) {
whitelistStatus = whitelist[account];
superWhitelistStatus = superWhitelist[account];
vipStatus = vip[account];
vvipStatus = vvip[account];
vvvipStatus = vvvip[account];
PaidVip1Info memory vip1 = paidVip1Status[account];
paidVip1StatusActive = vip1.expireTime > 0 && block.timestamp < vip1.expireTime;
feeExemptSenderStatus = feeExemptSender[account];
feeExemptReceiverStatus = feeExemptReceiver[account];
}
// 模拟转账(用于测试,不实际执行)
function simulateTransfer(address from, address to, uint256 amount) external view returns (
bool success,
string memory message,
uint256 feeAmount,
uint256 fromBalanceBefore,
uint256 fromBalanceAfter,
uint256 toBalanceBefore,
uint256 toBalanceAfter,
uint256 fromUnlockedBefore,
uint256 fromUnlockedAfter
) {
// 获取余额
fromBalanceBefore = balanceOf(from);
toBalanceBefore = balanceOf(to);
fromUnlockedBefore = _getUnlockedBalance(from);
// 快速检查基本条件并提前返回
if (!transfersEnabled) {
return (false, "Transfers disabled", 0, fromBalanceBefore, fromBalanceBefore, toBalanceBefore, toBalanceBefore, fromUnlockedBefore, fromUnlockedBefore);
}
if (transferDisabled[from]) {
return (false, "Sender restricted", 0, fromBalanceBefore, fromBalanceBefore, toBalanceBefore, toBalanceBefore, fromUnlockedBefore, fromUnlockedBefore);
}
if (transferBlocked[from] || transferBlocked[to]) {
return (false, "Address blocked", 0, fromBalanceBefore, fromBalanceBefore, toBalanceBefore, toBalanceBefore, fromUnlockedBefore, fromUnlockedBefore);
}
if (amount == 0) {
return (false, "Amount zero", 0, fromBalanceBefore, fromBalanceBefore, toBalanceBefore, toBalanceBefore, fromUnlockedBefore, fromUnlockedBefore);
}
// 计算手续费
feeAmount = _calculateFee(from, to, amount);
// 检查余额
if (fromUnlockedBefore < amount + feeAmount) {
return (false, "Insufficient balance", feeAmount, fromBalanceBefore, fromBalanceBefore, toBalanceBefore, toBalanceBefore, fromUnlockedBefore, fromUnlockedBefore);
}
// 计算转账后的余额
fromBalanceAfter = fromBalanceBefore - amount - feeAmount;
toBalanceAfter = toBalanceBefore + amount;
fromUnlockedAfter = fromUnlockedBefore - amount - feeAmount;
return (true, "Success", feeAmount, fromBalanceBefore, fromBalanceAfter, toBalanceBefore, toBalanceAfter, fromUnlockedBefore, fromUnlockedAfter);
}
}