{
  "language": "Solidity",
  "sources": {
    "contracts/T1YFeeSwapper.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// File: @openzeppelin/contracts/utils/Context.sol\n\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n\n// File: @openzeppelin/contracts/access/Ownable.sol\n\n\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    /**\n     * @dev The caller account is not authorized to perform an operation.\n     */\n    error OwnableUnauthorizedAccount(address account);\n\n    /**\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\n     */\n    error OwnableInvalidOwner(address owner);\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n     */\n    constructor(address initialOwner) {\n        if (initialOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(initialOwner);\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        if (owner() != _msgSender()) {\n            revert OwnableUnauthorizedAccount(_msgSender());\n        }\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        if (newOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n\n// File: FeeSwapper.sol\n\n// FeeSwapper.sol\n\npragma solidity ^0.8.20;\n\n\ninterface IERC20 {\n    function transfer(address to, uint256 amount) external returns (bool);\n    function approve(address spender, uint256 amount) external returns (bool);\n    function balanceOf(address account) external view returns (uint256);\n}\n\n\n/**\n * @title T1YFeeSwapper\n * @notice 专门用于处理 T1Y 手续费兑换的中间合约\n * @dev 将 T1Y 手续费兑换为 USDT 并自动分配到节点奖池\n */\ncontract T1YFeeSwapper is Ownable {\n    address public T1Y_TOKEN;\n    address public immutable WBNB;\n    address public immutable USDT;\n    address public immutable ROUTER;\n    \n    // 自动兑换开关\n    bool public autoSwapEnabled = true;\n    \n    // 最小兑换数量（极低阈值，确保每笔都兑换）\n    uint256 public minSwapAmount = 0.001 ether;  // 0.001 T1Y\n\n    uint256 public slippageBps = 1000;\n\n    mapping(address=>bool) public earleirUser;\n    \n    event FeeSwapped(uint256 t1yAmount, uint256 usdtAmount);\n    event AutoSwapToggled(bool enabled);\n    event MinSwapAmountUpdated(uint256 newAmount);\n    event AddEarleirUser(address user);\n    \n    /**\n     * @notice 构造函数\n     * @param _t1yToken T1Y代币地址（即主合约地址）\n     */\n    constructor(\n        address _t1yToken\n    ) Ownable(msg.sender) {\n        require(_t1yToken != address(0), \"Invalid T1Y token\");\n        require(_t1yToken.code.length > 0, \"Nc\");\n        T1Y_TOKEN = _t1yToken;\n        WBNB = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;  // BSC WBNB\n        ROUTER = 0x10ED43C718714eb63d5aA57B78B54704E256024E;      // PancakeSwap Router V2\n        USDT=0x55d398326f99059fF775485246999027B3197955;\n    }\n    \n    /**\n     * @notice 兑换指定数量的 T1Y 为 WBNB 并自动分配\n     * @dev 由主合约在卖出时自动调用\n     * @param t1yAmount 要兑换的 T1Y 数量\n     * @return wbnbAmount 获得的 WBNB 数量\n     */\n    function swapT1YForWBNB(uint256 t1yAmount) external returns (uint256) {\n        require(msg.sender == T1Y_TOKEN, \"Only main contract\");\n        \n        if (!autoSwapEnabled || t1yAmount < minSwapAmount) {\n            return 0;  // 不兑换，累积到下次\n        }\n        \n        uint256 t1yBalance = IERC20(T1Y_TOKEN).balanceOf(address(this));\n        require(t1yBalance >= t1yAmount, \"Insufficient T1Y balance\");\n        \n        // 授权 Router\n        IERC20(T1Y_TOKEN).approve(ROUTER, t1yAmount);\n        \n        // 设置交易路径：T1Y → WBNB\n        address[] memory path = new address[](2);\n        path[0] = T1Y_TOKEN;\n        path[1] = WBNB;\n\n        uint256[] memory quoted = IPancakeRouter(ROUTER).getAmountsOut(t1yAmount, path);\n        \n        // 执行 swap\n        uint256[] memory amounts = IPancakeRouter(ROUTER).swapExactTokensForTokens(\n            t1yAmount,\n            _minAfterSlippage(quoted[1], slippageBps),\n            path,\n            address(this),  // 先接收到本合约\n            block.timestamp + 300\n        );\n        \n        uint256 wbnbAmount = amounts[1];\n        \n        // 将 WBNB 转回主合约并触发分配\n        require(IERC20(WBNB).transfer(T1Y_TOKEN, wbnbAmount), \"WBNB transfer failed\");\n        \n        emit FeeSwapped(t1yAmount, wbnbAmount);\n        \n        return wbnbAmount;\n    }\n    \n    /**\n     * @notice 切换自动兑换开关\n     */\n    function toggleAutoSwap(bool _enabled) external onlyOwner {\n        autoSwapEnabled = _enabled;\n        emit AutoSwapToggled(_enabled);\n    }\n    \n    /**\n     * @notice 设置最小兑换数量\n     */\n    function setMinSwapAmount(uint256 _amount) external onlyOwner {\n        minSwapAmount = _amount;\n        emit MinSwapAmountUpdated(_amount);\n    }\n\n    function setSlippageBps(uint256 _bps) external onlyOwner {\n        require(_bps <= 5000, \"max 50%\");\n        slippageBps = _bps;\n    }\n\n    /**\n     * @notice 添加优先用户\n     */\n    function addEarleirUser(address[] memory users) external onlyOwner {\n        for(uint i = 0;i<users.length;i++){\n            earleirUser[users[i]]=true;\n            emit AddEarleirUser(users[i]);\n        }\n    }\n    \n    /**\n     * @notice 查看当前累积的 T1Y 余额\n     */\n    function getT1YBalance() external view returns (uint256) {\n        return IERC20(T1Y_TOKEN).balanceOf(address(this));\n    }\n    \n    /**\n     * @notice 转移代币到指定地址\n     * @dev 只允许 T1Y 主合约调用，用于赎回等操作\n     * @param token 代币地址\n     * @param to 接收地址\n     * @param amount 转移数量\n     */\n    function transferToken(address token, address to, uint256 amount) external returns (bool) {\n        require(msg.sender == T1Y_TOKEN, \"Only main contract\");\n        require(to != address(0), \"Invalid recipient\");\n        \n        return IERC20(token).transfer(to, amount);\n    }\n    \n    /**\n     * @notice 紧急提取函数\n     */\n    function emergencyWithdraw(address token, uint256 amount) external onlyOwner {\n        require(IERC20(token).transfer(msg.sender, amount), \"Token transfer failed\");\n    }\n    /**\n     * @notice 将查询WBNB对U的价格\n     */\n    function _getWBNBAmountOut(uint256 amountIn) external view returns(uint256){\n        return _getAmountOut(WBNB,USDT,amountIn);\n    }\n    /**\n     * @notice 将查询T1Y对WBNB的价格\n     */\n    function _getT1YAmountOut(uint256 amountIn) external view returns(uint256){\n        return _getAmountOut(T1Y_TOKEN,WBNB,amountIn);\n    }\n    /**\n     * @notice 将查询T1Y对WBNB的价格\n     */\n    function _getT1YAmountOutOfUSDT(uint256 amountIn) external view returns(uint256){\n        uint wbnbAmount = _getAmountOut(T1Y_TOKEN,WBNB,amountIn);\n        return _getAmountOut(WBNB,USDT,wbnbAmount);\n    }\n    function _getAmountOut(address token0,address token1,uint256 amountIn) internal view returns(uint256){\n        address[] memory path = new address[](2);\n        path[0] = token0;\n        path[1] = token1;\n        uint256[] memory amounts = IPancakeRouter(ROUTER).getAmountsOut(amountIn, path);\n        return amounts[1];\n    }\n\n    function _minAfterSlippage(uint256 amount, uint256 bps) internal pure returns (uint256) {\n        if (bps >= 10000) return 0;\n        return (amount * (10000 - bps)) / 10000;\n    }\n}\n\ninterface IPancakeRouter {\n    function factory() external pure returns (address);\n    function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts);\n    function addLiquidity(\n        address tokenA,\n        address tokenB,\n        uint256 amountADesired,\n        uint256 amountBDesired,\n        uint256 amountAMin,\n        uint256 amountBMin,\n        address to,\n        uint256 deadline\n    ) external returns (uint256 amountA, uint256 amountB, uint256 liquidity);\n    function removeLiquidity(\n        address tokenA,\n        address tokenB,\n        uint256 liquidity,\n        uint256 amountAMin,\n        uint256 amountBMin,\n        address to,\n        uint256 deadline\n    ) external returns (uint256 amountA, uint256 amountB);\n    function swapExactTokensForTokens(\n        uint256 amountIn,\n        uint256 amountOutMin,\n        address[] calldata path,\n        address to,\n        uint256 deadline\n    ) external returns (uint256[] memory amounts);\n    function swapExactETHForTokens(\n        uint256 amountOutMin,\n        address[] calldata path,\n        address to,\n        uint256 deadline\n    ) external payable returns (uint256[] memory amounts);\n}\n"
    },
    "contracts/T1YToken.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// File: @openzeppelin/contracts/token/ERC20/IERC20.sol\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n\n// File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\n\n\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity >=0.6.2;\n\n\n/**\n * @dev Interface for the optional metadata functions from the ERC-20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n\n// File: @openzeppelin/contracts/utils/Context.sol\n\n\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n\n// File: @openzeppelin/contracts/interfaces/draft-IERC6093.sol\n\n\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/draft-IERC6093.sol)\npragma solidity >=0.8.4;\n\n/**\n * @dev Standard ERC-20 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.\n */\ninterface IERC20Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC20InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC20InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     * @param allowance Amount of tokens a `spender` is allowed to operate with.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC20InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC20InvalidSpender(address spender);\n}\n\n/**\n * @dev Standard ERC-721 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.\n */\ninterface IERC721Errors {\n    /**\n     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.\n     * Used in balance queries.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721InvalidOwner(address owner);\n\n    /**\n     * @dev Indicates a `tokenId` whose `owner` is the zero address.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721NonexistentToken(uint256 tokenId);\n\n    /**\n     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param tokenId Identifier number of a token.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC721InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC721InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721InsufficientApproval(address operator, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC721InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC721InvalidOperator(address operator);\n}\n\n/**\n * @dev Standard ERC-1155 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.\n */\ninterface IERC1155Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC1155InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC1155InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC1155MissingApprovalForAll(address operator, address owner);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC1155InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC1155InvalidOperator(address operator);\n\n    /**\n     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\n     * Used in batch transfers.\n     * @param idsLength Length of the array of token identifiers\n     * @param valuesLength Length of the array of token amounts\n     */\n    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\n}\n\n// File: @openzeppelin/contracts/token/ERC20/ERC20.sol\n\n\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.20;\n\n\n\n\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC-20\n * applications.\n */\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\n    mapping(address account => uint256) private _balances;\n    mapping(address account => mapping(address spender => uint256)) private _allowances;\n    uint256 private _totalSupply;\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * Both values are immutable: they can only be set once during construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual returns (uint8) {\n        return 18;\n    }\n\n    /// @inheritdoc IERC20\n    function totalSupply() public view virtual returns (uint256) {\n        return _totalSupply;\n    }\n\n    /// @inheritdoc IERC20\n    function balanceOf(address account) public view virtual returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `value`.\n     */\n    function transfer(address to, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, value);\n        return true;\n    }\n\n    /// @inheritdoc IERC20\n    function allowance(address owner, address spender) public view virtual returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, value);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Skips emitting an {Approval} event indicating an allowance update. This is not\n     * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `value`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `value`.\n     */\n    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, value);\n        _transfer(from, to, value);\n        return true;\n    }\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead.\n     */\n    function _transfer(address from, address to, uint256 value) internal {\n        if (from == address(0)) {\n            revert ERC20InvalidSender(address(0));\n        }\n        if (to == address(0)) {\n            revert ERC20InvalidReceiver(address(0));\n        }\n        _update(from, to, value);\n    }\n\n    /**\n     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\n     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\n     * this function.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _update(address from, address to, uint256 value) internal virtual {\n        if (from == address(0)) {\n            // Overflow check required: The rest of the code assumes that totalSupply never overflows\n            _totalSupply += value;\n        } else {\n            uint256 fromBalance = _balances[from];\n            if (fromBalance < value) {\n                revert ERC20InsufficientBalance(from, fromBalance, value);\n            }\n            unchecked {\n                // Overflow not possible: value <= fromBalance <= totalSupply.\n                _balances[from] = fromBalance - value;\n            }\n        }\n\n        if (to == address(0)) {\n            unchecked {\n                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\n                _totalSupply -= value;\n            }\n        } else {\n            unchecked {\n                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\n                _balances[to] += value;\n            }\n        }\n\n        emit Transfer(from, to, value);\n    }\n\n    /**\n     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\n     * Relies on the `_update` mechanism\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead.\n     */\n    function _mint(address account, uint256 value) internal {\n        if (account == address(0)) {\n            revert ERC20InvalidReceiver(address(0));\n        }\n        _update(address(0), account, value);\n    }\n\n    /**\n     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\n     * Relies on the `_update` mechanism.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead\n     */\n    function _burn(address account, uint256 value) internal {\n        if (account == address(0)) {\n            revert ERC20InvalidSender(address(0));\n        }\n        _update(account, address(0), value);\n    }\n\n    /**\n     * @dev Sets `value` as the allowance of `spender` over the `owner`'s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     *\n     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\n     */\n    function _approve(address owner, address spender, uint256 value) internal {\n        _approve(owner, spender, value, true);\n    }\n\n    /**\n     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\n     *\n     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\n     * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\n     * `Approval` event during `transferFrom` operations.\n     *\n     * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\n     * true using the following override:\n     *\n     * ```solidity\n     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\n     *     super._approve(owner, spender, value, true);\n     * }\n     * ```\n     *\n     * Requirements are the same as {_approve}.\n     */\n    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\n        if (owner == address(0)) {\n            revert ERC20InvalidApprover(address(0));\n        }\n        if (spender == address(0)) {\n            revert ERC20InvalidSpender(address(0));\n        }\n        _allowances[owner][spender] = value;\n        if (emitEvent) {\n            emit Approval(owner, spender, value);\n        }\n    }\n\n    /**\n     * @dev Updates `owner`'s allowance for `spender` based on spent `value`.\n     *\n     * Does not update the allowance value in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Does not emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance < type(uint256).max) {\n            if (currentAllowance < value) {\n                revert ERC20InsufficientAllowance(spender, currentAllowance, value);\n            }\n            unchecked {\n                _approve(owner, spender, currentAllowance - value, false);\n            }\n        }\n    }\n}\n\n// File: @openzeppelin/contracts/access/Ownable.sol\n\n\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    /**\n     * @dev The caller account is not authorized to perform an operation.\n     */\n    error OwnableUnauthorizedAccount(address account);\n\n    /**\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\n     */\n    error OwnableInvalidOwner(address owner);\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n     */\n    constructor(address initialOwner) {\n        if (initialOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(initialOwner);\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        if (owner() != _msgSender()) {\n            revert OwnableUnauthorizedAccount(_msgSender());\n        }\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        if (newOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n\n\n\n// File: T1Y.sol\n\n\npragma solidity ^0.8.24;\n\n/**\n * @title T1Y Token Contract\n * @notice T1Y 是一个创新的 BEP-20 代币，具有算力挖矿、节点奖励、邀请系统等功能\n * @dev 实现了完整的 LP 管理、自动底池燃烧、自动奖励分配等机制\n * @dev 生产环境：静态+燃烧使用小时周期；动态+节点使用一天周期\n */\n\ncontract T1YToken is ERC20,Ownable {\n    \n    // ============ 常量定义 ============\n    address public tokenExt; //代币逻辑扩展合约\n    address public feeSwapper;  // 手续费兑换合约地址\n    \n    /// @notice 黑洞地址，用于接收销毁的代币\n    address public constant DEAD = 0x000000000000000000000000000000000000dEaD;\n    \n    /// @notice 基础比例分母\n    uint256 private constant BASE = 100000;\n    \n    // ============ DEX 相关 ============\n    /// @notice PancakeSwap Router V2 (BSC Mainnet)\n    address public constant ROUTER = 0x10ED43C718714eb63d5aA57B78B54704E256024E;\n    \n    /// @notice USDT 代币地址 (BSC)\n    address public constant USDT = 0x55d398326f99059fF775485246999027B3197955;\n    \n    /// @notice WBNB 代币地址 (BSC)\n    address public constant WBNB = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;\n        \n    /// @notice T1Y-WBNB LP 池地址\n    address public pancakePair;\n\n    /// @notice 初始上级地址（创世推荐人）\n    address public constant INITIAL_SUPERIOR = 0x86C4ba8B7634A13a2E8252fE51F065De0A6f96a0;\n    \n    // ============ 地址配置 ============\n    \n    /// @notice 生态地址\n    address public constant operationsAddress = 0x9F1201ba19a9bdE5FeAF6F7707D0B4079956927c;\n    \n    address public constant evnAddress = 0x745394748Fbbc7Dd311f451D7C906dD0ef59D93D;\n\n    address public constant techAddress = 0x6B7b9f6FAC994FC96bC5AB81211114595f2C03C9;\n\n    address private constant operationReserveAddress1 = 0x556Cbee427cec8aB039C3E16dE7d2D046764077d;\n    address private constant operationReserveAddress2 = 0x4429150Df6eF58e478108Fa6552B8C60Cb155a4D;\n    address private constant operationReserveAddress3 = 0x725068641a1265B10C8c9297b0CDA848cdBa4263;\n    \n    /// @notice 创世节点地址\n    address public constant genesisNodeAddress = 0xeb66E4C8513a91D41d30667685FC62B87762F9B4;\n\n    /// @notice 白名单地址\n    address public constant baiAddress = 0x13ff54aD16ddE8a20B0f4c4537397169b72b71F1;\n\n    /// @notice 归集地址\n    address public constant guijiAddress = 0xF869E633aC86E85F645684bc0F06ce0F7401ef3A;\n\n    /// @notice 流动性操作滑点（默认 5%，单位：bps，即 500 = 5%）\n    uint256 public liquiditySlippageBps = 500;\n\n    /// @notice swap 操作滑点（默认 10%，单位：bps，即 1000 = 10%）\n    uint256 public swapSlippageBps = 1000;\n    \n    // ============ 用户信息结构 ============\n    \n    /// @notice 用户信息\n    struct User {\n        address superior;           // 上级地址\n        uint8   nodeLevel;          // 节点等级 0=无，1=L1，2=L2，3=L3, 4=L4, 5=L5\n        uint256 lpAmount;           // LP 代币数量\n        uint256 usdtValue;          // USDT 面值\n        uint256 depositCycle;       // 入场周期\n        uint256 hashrateStatic;     // 静态算力\n        uint256 hashrateDynamic;    // 动态算力\n        uint256 staticReceived;     // 静态已领取（累计）\n        uint256 dynamicReceived;    // 动态已领取（累计）\n        uint256 nodeWBNBReceived;   // 节点WBNB已领取\n        uint256 nodeT1YReceived;    // 节点T1Y已领取\n        uint256 validReferralCount; // 有效下级数量（直推且已入金的用户）\n        uint256 hashrateReward;\n    }\n    \n    /// @notice 用户领奖周期记录\n    struct UserLast {\n        uint256 lastStaticCycle;    // 上次静态领奖周期\n        uint256 lastDynamicCycle;   // 上次动态领奖周期\n        uint256 lastNodeWBNBCycle;  // 上次节点WBNB领奖周期\n        uint256 lastNodeT1YCycle;   // 上次节点T1Y领奖周期\n    }\n    \n    /// @notice 用户信息映射\n    mapping(address => User) public users;\n    mapping(address => uint256) public wbnbReward;\n    mapping(address => uint256) public userReward;\n    \n    /// @notice 用户领奖周期映射\n    mapping(address => UserLast) public userLasts;\n\n    /// @notice 用户周期静态算力映射\n    mapping(address => mapping(uint256 => uint256)) public usersCycleStaticHashrate;\n\n    /// @notice 用户周期动态算力映射\n    mapping(address => mapping(uint256 => uint256)) public usersCyclelDynamicHashrate;\n\n    /// @notice 用户周期节点等级映射\n    mapping(address => mapping(uint256 => uint256)) public usersCyclelNodeLevel;\n    \n    /// @notice 算力贡献记录：上级地址 => 下级地址 => 下级实际贡献的动态算力\n    /// @dev 用于赎回时精确扣除，避免多扣或少扣\n    mapping(address => mapping(address => uint256)) public hashrateContribution;\n    \n    // ============ 全网数据 ============\n    \n    /// @notice 全网总静态算力\n    uint256 public totalStaticHashrate;\n    \n    /// @notice 全网总动态算力\n    uint256 public totalDynamicHashrate;\n    \n    /// @notice 各节点等级总人数 [L1, L2, L3, L4, L5]\n    uint256[5] public nodeTotalCount;\n    \n    // ============ 周期数据（静态奖励 + 底池燃烧）============\n    \n    /// @notice 周期静态算力快照\n    mapping(uint256 => uint256) public hourlyCycleStaticHashrate;\n    \n    /// @notice 周期静态奖励\n    mapping(uint256 => uint256) public hourlyCycleStaticReward;\n    \n    // ============ 周期数据（动态 + 节点）============\n    \n    /// @notice 周期动态算力快照\n    mapping(uint256 => uint256) public dailyCycleDynamicHashrate;\n    \n    /// @notice 周期节点人数快照 [L1, L2, L3, L4, L5]\n    mapping(uint256 => uint256[5]) public dailyCycleNodeCount;\n    \n    /// @notice 周期动态奖励\n    mapping(uint256 => uint256) public dailyCycleDynamicReward;\n    \n    /// @notice 周期节点奖励 \n    mapping(uint256 => uint256[10]) public dailyCycleNodeRewards;\n    \n    // ============ 时间与周期 ============\n    \n    /// @notice 合约创建时间（取整时）\n    uint256 public  launchTime;\n    \n    // ============ 入金 ============\n    \n    /// @notice 用户是否已经入金过\n    mapping(address => bool) public hasDeposited;\n    \n    // ============ 白名单 ============\n    \n    /// @notice 转账白名单（免手续费和销毁）\n    mapping(address => bool) public transferWhitelist;\n\n    /// @notice 每小时的单价\n    mapping(uint256 => uint256) public pricePerHour;\n\n    /// @notice 每日进场用户数量\n    mapping(uint256 => uint256) public numberPerDay;\n    \n    /// @notice 原版进场队列字段，当前同步入金路径不再写入\n    UserQueue[] public usersQueue;\n    \n    /// @notice 原版队列处理序列号，当前同步入金路径不再推进\n    uint256 public processIndex;\n\n    /// @notice 原版用户排队序号，当前同步入金路径不再写入\n    mapping(address=>uint256) public queueIndexOfUser;\n\n    /// @notice 原版用户排队日期，当前同步入金路径不再写入\n    mapping(address=>uint256) public currentDayOfUser;\n\n    /// @notice 原版用户排队记录\n    struct UserQueue{\n        address user;\n        uint8 status;\n        uint256 value;\n    }\n    // ============ 事件定义 ============\n    \n    event Deposit(address indexed user, uint256 bnbAmount, uint256 usdtAmount,uint256 lpAmount);\n    event EnterQueue(address indexed user,uint256 bnbAmount,uint256 Day); // 原版队列事件，当前同步入金路径不再触发\n    event Redeem(address indexed user, uint256 lpAmount, uint256 wbnbAmount, uint256 t1yAmount,uint256 cycle);\n    event ReferrerBound(address indexed user, address indexed referrer);\n    event NodeLevelChanged(address indexed user, uint8 oldLevel, uint8 newLevel);\n    event HourlyCycleUpdated(uint256 cycle, uint256 staticHashrate, uint256 staticReward, uint256 burnAmount);\n    event DailyCycleUpdated(uint256 cycle, uint256 dynamicHashrate, uint256 dynamicReward, uint256[5] nodeHashrate);\n    event RewardClaimed(address indexed user, uint8 rewardType, uint256 amount);\n    event RedeemCompleted(address indexed user);\n    event HashrateMismatch(address indexed user, uint256 requested, uint256 actual, string hashrateType);\n    event SellAmountAdjusted(address indexed user, uint256 requestedAmount, uint256 actualAmount);\n    event RewardCompleted(address indexed user, uint level, uint256 staticHashrate, uint256 dynamicHashrate, uint256 reward);\n    \n    \n    // ============ 构造函数 ============\n    \n    \n    constructor() ERC20(\"T1Y\", \"T1Y\") Ownable(baiAddress) {\n        // 设置启动时间\n        launchTime = block.timestamp / 1 hours * 1 hours;\n        // 铸造总供应量\n        _mint(baiAddress, 130_000_000 ether);\n        _mint(operationReserveAddress1, 1_000_000 ether);\n        _mint(operationReserveAddress2, 1_000_000 ether);\n        _mint(operationReserveAddress3, 1_000_000 ether);\n        _mint(INITIAL_SUPERIOR,100 ether);\n        // 将关键地址加入白名单\n        transferWhitelist[address(this)] = true;\n        transferWhitelist[DEAD] = true;\n        transferWhitelist[genesisNodeAddress] = true;\n        transferWhitelist[INITIAL_SUPERIOR] = true;\n        transferWhitelist[baiAddress] = true;\n        // 初始化创世上级（指向自己，避免绑定检查失败）\n        users[INITIAL_SUPERIOR].superior = INITIAL_SUPERIOR;\n        initializeLiquidity();\n    }\n\n    // ============ 周期函数 ============\n    \n    /**\n     * @notice 获取当前周期（用于静态奖励和底池燃烧）\n     */\n    function getHourlyCycle() public view returns (uint256) {\n        return (block.timestamp - launchTime) / 1 hours;\n    }\n    \n    /**\n     * @notice 获取当前周期（用于动态奖励和节点奖励\n     */\n    function getDailyCycle() public view returns (uint256) {\n        return (block.timestamp - launchTime) / 1 days;\n    }\n\n    function setFeeSwapper(address _feeSwapper) public  onlyOwner(){\n        require(_feeSwapper != address(0), \"Ia\");//Invalid address\n        feeSwapper = _feeSwapper;\n        // 将 feeSwapper 加入白名单\n        transferWhitelist[_feeSwapper] = true;\n    }\n    function settokenExt(address ext) public  onlyOwner(){\n        require(ext != address(0), \"Ia\");//Invalid address\n        tokenExt = ext;\n        transferWhitelist[ext] = true;\n    }\n\n    function setLiquiditySlippageBps(uint256 _bps) external onlyOwner {\n        require(_bps <= 5000);\n        liquiditySlippageBps = _bps;\n    }\n\n    function setSwapSlippageBps(uint256 _bps) external onlyOwner {\n        require(_bps <= 5000);\n        swapSlippageBps = _bps;\n    }\n\n    function _minAfterSlippage(uint256 amount, uint256 bps) internal pure returns (uint256) {\n        if (bps >= 10000) return 0;\n        return (amount * (10000 - bps)) / 10000;\n    }\n\n    /**\n     * @notice 尝试兑换累积的手续费（内部调用）\n     * @dev 在普通转账时触发，失败不影响主流程\n     */\n    function _trySwapFees() internal {\n        if (feeSwapper == address(0)) return;\n        // 检查累积的手续费数量\n        uint256 feeBalance = IFeeSwapper(feeSwapper).getT1YBalance();\n        \n        // 如果累积超过 1 T1Y，则触发兑换\n        if (feeBalance >= 1 ether) {\n            try IFeeSwapper(feeSwapper).swapT1YForWBNB(feeBalance) returns (uint256 nodeWBNB) {\n                if (nodeWBNB > 0) {\n                    _distributeNodePool(nodeWBNB);\n                }\n            } catch {\n                // 兑换失败，不影响主流程\n            }\n        }\n    }\n    \n    // ============ 核心功能：入金 ============\n    \n    /**\n     * @notice 接收 BNB 入金\n     */\n    receive() external payable {\n        require(msg.value >= 15e16, \"Bm\");//Below minimum\n        require(users[msg.sender].superior != address(0), \"Mb\");//Must bind referrer\n        require(pancakePair != address(0), \"Ni\");//Not initialized\n        //更新周期数据（必须在 swap 之前，避免在 swap 过程中重复调用）\n        (,uint256 currentDay)=_updateCycle();\n        \n        // 检查报单人数\n        _queuetoDeposit(msg.sender,currentDay,msg.value);\n    }\n    \n    /**\n    * @notice 同步入金\n     */\n    function _queuetoDeposit(address user, uint256 currentDay, uint256 bnbAmount)internal{\n        // 1. 检查入金限制\n        require(bnbAmount <= 15e16*(1+(currentDay/3)),\"01\");//Exceeds early deposit limit \n        require(bnbAmount <= 5 ether, \"l5\");//Less than 1 BNB\n        require(!hasDeposited[user], \"oo\");//Address can only deposit once\n\n        uint256 allow =100;\n        for (uint256 d = 0; d < currentDay; d++) {\n            allow = (allow * 110) / 100;\n            if (allow >= 200) {\n                allow = 200;\n                break;\n            }\n        }\n        require(numberPerDay[currentDay]<allow, \"02\");\n\n        numberPerDay[currentDay] += 1;\n        _deposit(user,bnbAmount);\n        hasDeposited[user] = true;\n    }\n    /**\n     * @notice 原版队列执行函数，当前同步入金路径不再调用\n     */\n    function _executeDeposit(uint256 currentDay,uint256 index) internal returns(bool){\n        // 1. 计算入金数量 以100为基数，每日增加10%，最大1000.\n        uint256 allow =100;\n        for (uint256 d = 0; d < currentDay; d++) {\n            allow = (allow * 110) / 100;\n            if (allow >= 200) {\n                allow = 200;\n                break;\n            }\n        }\n        // 2. 未超过当日限制\n        if(numberPerDay[currentDay]>=allow) return false;\n        if(usersQueue.length==0) return false;\n        uint256 currentlength = usersQueue.length;\n        uint256 baseIndex = processIndex;\n        uint256 i = baseIndex;\n\n        for (; i < (baseIndex + 6) && i < currentlength; i++) {\n            UserQueue storage queue = usersQueue[i];\n            if (queue.status > 0) {\n                continue; \n            }\n            _deposit(queue.user, queue.value);\n\n            numberPerDay[currentDay] += 1;\n            queue.status = 1;\n            if (numberPerDay[currentDay] >= allow) {\n                processIndex = i + 1;\n                return false;\n            }\n        }\n        \n        processIndex = i;\n\n        // 3. 处理自己\n        if(index > 0 ){ \n            UserQueue storage queue = usersQueue[index];\n            // 用户处于排队中，并且是当日用户\n            if(queue.status==0 && currentDayOfUser[queue.user]<=currentDay){\n                // 处理入金\n                _deposit(queue.user, queue.value);\n                // 更新排队状态\n                numberPerDay[currentDay]+=1;\n                queue.status=1;\n                return true;\n            }\n        }\n        return false;\n    }\n    /**\n     * @notice 内部入金处理函数\n     */\n    function _deposit(address user, uint256 bnbAmount) internal {\n        \n        // 1、将BNB兑换为WBNB\n        IWETH(WBNB).deposit{value:bnbAmount}();\n        \n        // 2. 处理WBNB分配和LP构建\n        uint256 actualLP = _processBuildLP(bnbAmount, user);\n        \n        // 3. 更新直推上级的有效下级数量\n        address superior = users[user].superior;\n        if (superior != address(0) && users[user].lpAmount == 0) {\n            users[superior].validReferralCount += 1;\n        }\n        \n        // 4. 更新算力和信息\n        uint256 usdtAmount = IFeeSwapper(feeSwapper)._getWBNBAmountOut(bnbAmount);\n        uint256 staticHashrate = _updateUserHashrateAndInfo(user, usdtAmount, actualLP);\n        \n        // 5. 分配奖励和算力\n        _processRewardsAndHashrate(user, bnbAmount, staticHashrate);\n        \n        emit Deposit(user, bnbAmount, usdtAmount, actualLP);\n    }\n    \n    /**\n     * @notice 处理bnb分配和构建LP\n     * @dev 入金bnb的60%用于构建LP池，其中一半购买T1Y，一半保留bnb\n     * @dev 剩余的代币会转入LP池并同步，确保不浪费\n     * @param bnbAmount 总bnb金额\n     * @param user 入金用户地址\n     * @return liquidity 返回获得的LP代币数量\n     */\n    function _processBuildLP(uint256 bnbAmount, address user) internal returns (uint256) {\n        // 60% 的 wbnb 用于构建 LP 池\n        uint256 lpbnb = (bnbAmount * 60) / 100;\n        \n        // 将 LP 用的 wbnb 分成两半：一半买 T1Y，一半保留 wbnb\n        uint256 buyT1YAmount = lpbnb / 2;  // 30% 的总金额\n        \n        // 用 wbnb 在 PancakeSwap 上购买 T1Y 代币\n        require(IERC20(WBNB).transfer(tokenExt, buyT1YAmount), \"WBNB transfer failed\");\n        uint256 t1yAmount = ITokenExt(tokenExt)._buyT1Y(buyT1YAmount);\n        // 转回合约\n        _transfer(tokenExt, address(this), t1yAmount);\n        \n        // 添加流动性：将 T1Y 和 WBNB 配对添加到 LP 池\n        // 返回实际使用的 T1Y、WBNB 数量和获得的 LP 代币数量\n        (uint256 usedT1Y, uint256 usedWBNB, uint256 liquidity) = _addLiquidity(t1yAmount, buyT1YAmount, user);\n        \n        // 计算剩余的代币（由于价格波动，可能不会全部使用）\n        uint256 remainingT1Y = t1yAmount >= usedT1Y ? t1yAmount - usedT1Y : 0;\n        uint256 remainingWBNB = buyT1YAmount >= usedWBNB ? buyT1YAmount - usedWBNB : 0;\n        \n        // 将剩余代币转入交易对并同步，避免资金浪费\n        // 这些剩余代币会增加 LP 池的深度，但不会产生新的 LP 代币\n        bool needSync = false;\n        if (remainingT1Y > 0) {\n            _transfer(address(this), pancakePair, remainingT1Y);\n            needSync = true;\n        }\n        if (remainingWBNB > 0) {\n            _transferWBNB(pancakePair, remainingWBNB);\n            needSync = true;\n        }\n        // 如果有剩余代币转入，需要同步 LP 池的储备量\n        if (needSync) {\n            IPancakePair(pancakePair).sync();\n        }\n        \n        return liquidity;\n    }\n    \n    /**\n     * @notice 更新用户算力和信息\n     * @dev 静态算力会随着时间递增，越晚入金算力越高（激励早期参与）\n     * @param user 用户地址\n     * @param usdtAmount 入金的WBNB数量\n     * @param actualLP 获得的LP代币数量\n     * @return staticHashrate 返回本次获得的静态算力\n     */\n    function _updateUserHashrateAndInfo(\n        address user,\n        uint256 usdtAmount,\n        uint256 actualLP\n    ) internal returns (uint256) {\n        // 计算静态算力：基础算力 + 时间加成\n        // 每天增加 4%\n        uint256 elapsed = getDailyCycle();\n        uint256 staticHashrate = usdtAmount + (usdtAmount * elapsed * 4000) / BASE;\n        \n        // 更新用户数据\n        User storage u = users[user];\n        u.lpAmount += actualLP;              // 累加LP代币数量\n        u.usdtValue += usdtAmount;           // 累加USDT面值（用于节点等级判断）\n        \n        // 首次入金记录时间和领奖周期\n        if (u.depositCycle == 0) {\n            // 记录上次领奖周期（避免领取历史奖励）\n            userLasts[user].lastStaticCycle = getHourlyCycle();\n            userLasts[user].lastDynamicCycle = getDailyCycle();\n            userLasts[user].lastNodeWBNBCycle = getDailyCycle();\n            userLasts[user].lastNodeT1YCycle = getDailyCycle();\n        }\n        u.depositCycle = elapsed;\n        \n        u.hashrateStatic += staticHashrate;  // 累加静态算力\n\n        uint256 currentHourlyCycle = getHourlyCycle();\n        uint256 currentDailyCycle = getDailyCycle();\n        \n        // 🔥 更新用户周期快照（用于奖励计算）\n        usersCycleStaticHashrate[user][currentHourlyCycle] = u.hashrateStatic;\n        // 🔥 关键修复：初始化动态算力周期快照，即使当前为0也要记录\n        usersCyclelDynamicHashrate[user][currentDailyCycle] = u.hashrateDynamic;\n        \n        // 更新全网总静态算力（用于静态奖励分配计算）\n        totalStaticHashrate += staticHashrate;\n\n        // 更新周期总静态算力（用于静态奖励分配计算）\n        hourlyCycleStaticHashrate[currentHourlyCycle] = totalStaticHashrate;\n        \n        return staticHashrate;\n    }\n    \n    /**\n     * @notice 处理奖励分配和算力分配\n     * @dev 入金金额的分配：60% LP + 30% 直推 + 5% 节点 + 2.5% 运维 + 2.5% 技术 = 100%\n     * @param user 用户地址\n     * @param wbnbAmount 总WBNB金额\n     * @param staticHashrate 用户本次获得的静态算力\n     */\n    function _processRewardsAndHashrate(\n        address user,\n        uint256 wbnbAmount,\n        uint256 staticHashrate\n    ) internal {\n        // ===== 计算各部分金额分配 =====\n        uint256 nodeWBNB = (wbnbAmount * 5) / 100;          // 5% 进入节点BNB奖池\n        uint256 referralWBNB = (wbnbAmount * 30) / 100;     // 30% 给上级直推奖励（见点奖）\n        uint256 operationsWBNB = (wbnbAmount * 25) / 1000;   // 2.5% 给运维地址\n        uint256 techWBNB = (wbnbAmount * 25) / 1000;         // 2.5% 给技术地址\n        // 注：剩余60%已在 _processBuildLP 中用于构建LP\n        \n        // ===== 分配节点WBNB奖池（按周期分配给所有节点） =====\n        _distributeNodePool(nodeWBNB);\n        \n        // ===== 分配直推见点奖（直推8%，2-20代各1%） =====\n        _distributeReferralRewards(user, referralWBNB);\n        \n        // ===== 分配动态算力给上级（直推16%，2-3代8%，4-20代4%） =====\n        _distributeDynamicHashrate(user, staticHashrate);\n        \n        // 🔥 关键修复：检查用户自己是否达到节点等级\n        // 这确保用户入金后立即检查节点等级，并初始化节点等级周期快照\n        _updateNodeLevel(user);\n        \n        // ===== 转账到功能地址 =====\n        _transferWBNB(operationsAddress, operationsWBNB);\n        _transferWBNB(techAddress, techWBNB);\n    }\n    \n    // ============ 核心功能：赎回 ============\n    \n    /**\n     * @notice 赎回流动性\n     * @dev 用户需要先授权LP代币给合约，然后转0 T1Y给自己触发赎回\n     * @dev 赎回流程：用户授权LP -> 转0 T1Y给自己 -> 合约自动转移LP并移除流动性\n     */\n    function _redeem(address user) internal {\n        User storage u = users[user];\n        \n        // 1. 必须是有入金记录的用户\n        require(u.lpAmount > 0, \"Nr\");//No deposit record\n        \n        // 2. 记录要赎回的LP数量\n        uint256 lpToRedeem = u.lpAmount;\n        \n        // 3. 检查用户的LP余额是否足够\n        uint256 userLPBalance = IERC20(pancakePair).balanceOf(user);\n        require(userLPBalance >= lpToRedeem, \"Ib\");//Insufficient LP balance\n        \n        // 4. 检查用户是否已授权足够的LP给合约\n        uint256 allowance = IERC20(pancakePair).allowance(user, address(this));\n        require(allowance >= lpToRedeem, \"Iar\");//Insufficient LP allowance\n        \n        // 5. 从用户地址转移LP到合约\n        require(IERC20(pancakePair).transferFrom(user, address(this), lpToRedeem), \"tf\");//LP transfer failed\n        \n        // 6. 确保feeSwapper已设置\n        require(feeSwapper != address(0), \"ns\");//FeeSwapper not set\n        \n        // 7. 授权Router使用LP代币\n        IERC20(pancakePair).approve(ROUTER, lpToRedeem);\n\n        uint256 totalLiquidity = IPancakePair(pancakePair).totalSupply();\n        require(totalLiquidity > 0, \"Nl\");\n        uint256 expectedToken = (super.balanceOf(pancakePair) * lpToRedeem) / totalLiquidity;\n        uint256 expectedWBNB = (IERC20(WBNB).balanceOf(pancakePair) * lpToRedeem) / totalLiquidity;\n        \n        // 8. 调用PancakeRouter移除流动性（代币先到feeSwapper中间合约，添加滑点保护）\n        (uint256 t1yAmount, uint256 wbnbAmount) = IPancakeRouter(ROUTER).removeLiquidity(\n            address(this),          // tokenA: T1Y\n            WBNB,                   // tokenB: WBNB\n            lpToRedeem,             // 移除的LP数量\n            _minAfterSlippage(expectedToken, liquiditySlippageBps), // 最小T1Y数量\n            _minAfterSlippage(expectedWBNB, liquiditySlippageBps),   // 最小WBNB数量\n            feeSwapper,             // 代币先到feeSwapper中间合约\n            block.timestamp + 300   // 5分钟有效期\n        );\n        \n        // 9. 从feeSwapper将T1Y转移到合约（使用_transfer内部函数）\n        _transfer(feeSwapper, address(this), t1yAmount);\n        \n        // 10. 从feeSwapper将WBNB转移到合约（通过FeeSwapper的transferToken方法）\n        require(IFeeSwapper(feeSwapper).transferToken(WBNB, address(this), wbnbAmount), \"wtf\");//WBNB transfer failed\n        \n        // 11. 计算持有天数\n        uint256 daysHeld = getDailyCycle();\n        if (daysHeld >= u.depositCycle) {\n            daysHeld -= u.depositCycle;\n        } else {\n            daysHeld = 0;\n        }\n        \n        // 12. 根据持有天数计算销毁比例和用户应得\n        uint256 burnAmount;\n        uint256 userAmount;\n        \n        if (daysHeld < 30) {\n            // 30天内：100%销毁\n            burnAmount = t1yAmount;\n            userAmount = 0;\n        } else if (daysHeld < 60) {\n            // 31-60天：90%销毁\n            burnAmount = t1yAmount * 9 / 10;\n            userAmount = t1yAmount - burnAmount;\n        } else if (daysHeld < 120) {\n            // 61-120天：80%销毁\n            burnAmount = t1yAmount * 8 / 10;\n            userAmount = t1yAmount - burnAmount;\n        } else if (daysHeld < 180) {\n            // 121-180天：70 %销毁\n            burnAmount = t1yAmount * 7 / 10;\n            userAmount = t1yAmount - burnAmount;\n        }else if (daysHeld < 360) {\n            // 180-360天：50 %销毁\n            burnAmount = t1yAmount / 2;\n            userAmount = t1yAmount - burnAmount;\n        } else {\n            burnAmount = 0;\n            userAmount = t1yAmount;\n        }\n        \n        // 13. 执行T1Y销毁和转账\n        if (burnAmount > 0) {\n            _transfer(address(this), DEAD, burnAmount);\n        }\n        if (userAmount > 0) {\n            _transfer(address(this), user, userAmount);\n        }\n        \n        // 14. WBNB全额返还给用户\n        if (wbnbAmount > 0) {\n            _transferWBNB(user, wbnbAmount);\n        }\n        \n        // 15. 清理用户数据（扣除算力、更新节点等）\n        _cleanupRedeemData(user,true);\n        \n        // 16. 触发赎回事件\n        emit Redeem(user, lpToRedeem, wbnbAmount, userAmount,daysHeld);\n    }\n    \n    // ============ 辅助函数：安全算力扣除 ============\n    \n    /**\n     * @notice 安全扣除全网静态算力（防下溢）\n     * @dev 如果扣除量大于当前值，记录异常并归零，避免revert导致用户资金锁死\n     * @param amount 要扣除的算力数量\n     */\n    function _safeDeductStaticHashrate(uint256 amount) internal {\n        if (amount == 0) return;\n        \n        if (totalStaticHashrate >= amount) {\n            totalStaticHashrate -= amount;\n        } else {\n            // 防御性处理：记录异常但允许继续\n            // 这表示算力记录可能存在不一致，需要监控\n            emit HashrateMismatch(msg.sender, amount, totalStaticHashrate, \"static\");\n            totalStaticHashrate = 0;\n        }\n    }\n    \n    /**\n     * @notice 安全扣除全网动态算力（防下溢）\n     * @dev 如果扣除量大于当前值，记录异常并归零，避免revert导致用户资金锁死\n     * @param amount 要扣除的算力数量\n     */\n    function _safeDeductDynamicHashrate(uint256 amount) internal {\n        if (amount == 0) return;\n        \n        if (totalDynamicHashrate >= amount) {\n            totalDynamicHashrate -= amount;\n        } else {\n            // 防御性处理：记录异常但允许继续\n            emit HashrateMismatch(msg.sender, amount, totalDynamicHashrate, \"dynamic\");\n            totalDynamicHashrate = 0;\n        }\n    }\n    \n    /**\n     * @notice 清理赎回用户数据\n     * @dev 当用户从LP池赎回时，清理所有相关数据和算力\n     */\n    function _cleanupRedeemData(address user,bool isRemove) internal {\n        User storage u = users[user];\n        \n        // 获取当前周期\n        uint256 currentHourlyCycle = getHourlyCycle();\n        uint256 currentDailyCycle = getDailyCycle();\n        \n        // 扣除算力\n        uint256 userStatic = u.hashrateStatic;\n        uint256 userDynamic = u.hashrateDynamic;\n        \n        // 🔥 修复：使用安全扣除函数，防止下溢导致用户资金锁死\n        if (userStatic > 0) {\n            _safeDeductStaticHashrate(userStatic);\n        }\n        \n        if(isRemove) {\n            if (userDynamic > 0) {\n                _safeDeductDynamicHashrate(userDynamic);\n            }\n            // 扣除上级动态算力\n            _deductUplineDynamicHashrate(user);\n        \n            // 🔥 新增：减少直推上级的有效下级数量\n            address superior = u.superior;\n            if (superior != address(0) && users[superior].validReferralCount > 0) {\n                users[superior].validReferralCount -= 1;\n            }\n        }\n        \n        // 🔥 关键修复：更新当前周期的全网算力快照\n        // 赎回会减少全网算力，必须同步更新周期快照，确保数据一致性\n        hourlyCycleStaticHashrate[currentHourlyCycle] = totalStaticHashrate;\n        dailyCycleDynamicHashrate[currentDailyCycle] = totalDynamicHashrate;\n        dailyCycleNodeCount[currentDailyCycle] = nodeTotalCount;\n        \n        // 清空用户数据\n        if(isRemove) {\n            uint8 oldLevel = u.nodeLevel;    \n            // 更新节点人数\n            if (oldLevel > 0 && nodeTotalCount[oldLevel - 1] > 0) {\n                nodeTotalCount[oldLevel - 1] -= 1;\n            }\n\n            u.lpAmount = 0;\n            u.nodeLevel = 0;\n            u.hashrateDynamic = 0;\n            u.hashrateReward = 0;\n            u.usdtValue = 0;\n            if (oldLevel > 0) {\n                usersCyclelNodeLevel[user][currentDailyCycle] = 0;\n                emit NodeLevelChanged(user, oldLevel, 0);\n            }\n        }else{\n            userReward[user] += 3 * u.hashrateStatic;\n        }\n        u.hashrateStatic = 0;\n        \n\n        // 清空用户周期快照\n        usersCycleStaticHashrate[user][currentHourlyCycle] = 0;\n        usersCyclelDynamicHashrate[user][currentDailyCycle] = 0;\n        \n        // 更新周期数据\n        _updateCycle();\n    }\n    // ============ 核心功能：转账逻辑 ============\n    \n    /**\n     * @notice 重写余额查询方法（显示虚拟余额：实际余额 + 待领取奖励）\n     */\n    function balanceOf(address account) public view override returns (uint256) {\n        uint256 actualBalance = super.balanceOf(account);\n        (uint256 staticReward,) = ITokenExt(tokenExt)._calculateStaticReward(account);\n        uint256 dynamicReward = ITokenExt(tokenExt)._calculateDynamicReward(account);\n        return actualBalance + staticReward + dynamicReward;\n    }\n    \n    /**\n     * @notice 重写转账函数\n     */\n    function transfer(address to, uint256 amount) public override returns (bool) {\n        return _transferWithLogic(msg.sender, to, amount);\n    }\n    \n    /**\n     * @notice 重写授权转账函数\n     */\n    function transferFrom(address from, address to, uint256 amount) public override returns (bool) {\n        address spender = msg.sender;\n        _spendAllowance(from, spender, amount);\n        \n        return _transferWithLogic(from, to, amount);\n    }\n    \n    /**\n     * @notice 带逻辑的转账函数\n     */\n    function _transferWithLogic(address from, address to, uint256 amount) internal returns (bool) {\n        // 更新周期数据\n        (uint256 hourlyCycle,uint256 daliyCycle)=_updateCycle();\n        \n        // 处理 0 T1Y 转账（领取奖励）\n        if (amount == 0) {\n            _handleZeroTransfer(from, to);\n            return true;\n        }\n        \n        // 自动领取奖励（在非零转账时）\n        if (from != address(this)) {\n            _autoClaimRewards(from);\n            if (amount == 1e16){\n                // 绑定上级\n                require(to != from, \"Cr\");//Cannot refer self\n                require(to != address(0), \"Ir\");//Invalid referrer\n                require(users[to].superior == address(0) && users[from].superior != address(0), \"Ab\");//Already bound\n                users[to].superior = from;\n                emit ReferrerBound(to, from);\n            }\n        }\n\n        // 白名单地址直接转账\n        if (transferWhitelist[from] || transferWhitelist[to]) {\n            _transfer(from, to, amount);\n            return true;\n        }\n        \n        // 合约自身转账（添加流动性、内部结算等）直接放行\n        if (from == address(this)) {\n            _transfer(from, to, amount);\n            return true;\n        }\n        \n        // 检查是否从LP池转出（赎回操作）\n        if (from == pancakePair) {\n            // 禁止直接从LP池赎回，必须通过转0 T1Y给自己的方式触发redeem函数\n            revert(\"T0\");//Use redeem: transfer 0 T1Y to yourself\n        }\n        \n        // 检查是否为卖出操作（排除合约自身内部操作） 白名单是否考虑\n        if (to == pancakePair && from != address(this) ) {\n            \n            // 🔥 关键修复：如果发生了销毁，需要检查剩余余额是否足够卖出\n            // 如果销毁后余额不足，自动调整为卖出全部剩余余额\n            uint256 userBalance = super.balanceOf(from);\n            \n            uint256 actualSellAmount = amount;\n            \n            if (userBalance < amount) {\n                // 余额不足，自动调整为卖出全部余额\n                actualSellAmount = userBalance;\n                \n                // 触发调整事件，方便前端监控\n                emit SellAmountAdjusted(from, amount, actualSellAmount);\n            }\n            \n            // 如果余额为0或不足以支付手续费，交易失败\n            require(actualSellAmount > 0, \"Ib\");//Insufficient balance after burn\n            \n            _handleSell(from, actualSellAmount,hourlyCycle,daliyCycle);\n            return true;\n        }\n\n        uint balance = super.balanceOf(from);\n        if (amount>balance) amount = balance;\n        _transfer(from, to, amount);\n\n        // 尝试兑换累积的手续费（普通转账时触发，不影响转账流程）\n        _trySwapFees();\n        \n        return true;\n    }\n    \n    /**\n     * @notice 处理 0 T1Y 转账\n     * @dev 静态和动态奖励已自动领取，仅保留节点奖励领取和绑定上级功能\n     */\n    function _handleZeroTransfer(address from, address to) internal {\n        if (to == DEAD) {\n            // 领取节点 WBNB 奖励\n            _claimNodeWBNBReward(from);\n        } else if (to == address(this)) {\n            // 领取节点 T1Y 奖励\n            _claimNodeT1YReward(from);\n        } else if (to == from) {\n            // 转给自己：触发赎回流动性\n            _redeem(from);\n        }\n    }\n    \n    // ============ 核心功能：双周期更新 ============\n    \n    /**\n     * @notice 更新周期（静态奖励 + 底池燃烧 + 动态奖励 + 节点T1Y奖励）\n     * @dev 回溯补齐所有缺失的周期，使用历史算力，避免复利燃烧\n     */\n    function _updateCycle() internal returns(uint256 currentHour,uint256 currentDay){\n        currentHour = getHourlyCycle();\n        currentDay = getDailyCycle();\n        //记录T1Y本周期的最高单价\n        if (super.balanceOf(pancakePair)>0){\n            uint256 price = IFeeSwapper(feeSwapper)._getT1YAmountOut(1e18);\n            if(pricePerHour[currentHour] < price) pricePerHour[currentHour] = price; \n        }\n        \n        \n        // 记录当前周期的算力快照\n        if (hourlyCycleStaticHashrate[currentHour] == 0) {\n            hourlyCycleStaticHashrate[currentHour] = totalStaticHashrate;\n        }\n        if (dailyCycleDynamicHashrate[currentDay] == 0) {\n            dailyCycleDynamicHashrate[currentDay] = totalDynamicHashrate;\n            dailyCycleNodeCount[currentDay] = nodeTotalCount;\n        }\n\n        // ===== 处理小时周期（静态奖励+燃烧）=====\n        // 找到上一个已执行的小时周期\n        uint256 lastExecutedHour = currentHour;\n        // 🔥 修复：允许回溯到周期 0，避免周期 0 被跳过\n        while (hourlyCycleStaticReward[lastExecutedHour] == 0) {\n            if (lastExecutedHour == 0) break;  // 到达周期 0 时停止\n            lastExecutedHour--;\n        }\n        \n        // 🔥 安全修复：限制最大回溯数量，防止DoS攻击\n        // 🔥 修复：如果回溯到周期 0 且周期 0 没有数据，从周期 0 开始执行\n        uint256 catchupStartHour = (lastExecutedHour == 0 && hourlyCycleStaticReward[0] == 0) \n            ? 0 \n            : lastExecutedHour + 1;\n        uint256 catchupEndHour = currentHour;\n        if (catchupEndHour > catchupStartHour + 100) { //最多补齐100小时\n            // 如果缺失周期过多，只补最近的N个\n            catchupStartHour = catchupEndHour - 100;\n        }\n        \n        // 获取历史静态算力\n        uint256 historicalStatic = hourlyCycleStaticHashrate[lastExecutedHour];\n        \n        // 补齐缺失的小时周期（只补齐到 currentHour - 1，且受限于MAX_HOURLY_CATCHUP）\n        for (uint256 hour = catchupStartHour; hour < catchupEndHour; hour++) {\n            // 先补齐算力快照\n            if (hourlyCycleStaticHashrate[hour] == 0) {\n                hourlyCycleStaticHashrate[hour] = historicalStatic;\n            }else{\n                historicalStatic = hourlyCycleStaticHashrate[hour];\n            }\n            \n            // 再执行燃烧（如果还没执行）\n            if (hourlyCycleStaticReward[hour] == 0) {\n                uint256 hourDailyCycle = hour / 24;  // 将小时转换为天数（24小时=1天）\n                _executePoolBurn(hour, hourDailyCycle);\n            }\n        }\n        \n        // ===== 处理日周期（动态奖励+节点奖励）=====\n        // 找到上一个已执行的日周期\n        uint256 lastExecutedDay = currentDay;\n        while (lastExecutedDay > 0 && dailyCycleDynamicHashrate[lastExecutedDay] == 0) {\n            lastExecutedDay--;\n        }\n        \n        // 🔥 安全修复：限制最大回溯数量，防止DoS攻击\n        uint256 catchupStartDay = lastExecutedDay + 1;\n        uint256 catchupEndDay = currentDay;\n        if (catchupEndDay > catchupStartDay + 30) {// 最多补齐30天\n            // 如果缺失周期过多，只补最近的N个\n            catchupStartDay = catchupEndDay - 30;\n        }\n        \n        uint256 historicalDynamic = dailyCycleDynamicHashrate[lastExecutedDay];\n        uint256[5] memory historicalNodeCount = dailyCycleNodeCount[lastExecutedDay];\n        \n        // 补齐缺失的日周期（受限于30 天）\n        for (uint256 day = catchupStartDay; day < catchupEndDay; day++) {\n            if (dailyCycleDynamicHashrate[day] == 0) {\n                dailyCycleDynamicHashrate[day] = historicalDynamic;\n                dailyCycleNodeCount[day] = historicalNodeCount;\n            }else{\n                historicalDynamic = dailyCycleDynamicHashrate[day];\n                historicalNodeCount = dailyCycleNodeCount[day];\n            }\n        }\n    }\n    \n    /**\n     * @notice 执行底池燃烧（小时周期）\n     * @dev 每小时从LP池中燃烧一定比例的T1Y代币，并分配奖励\n     * @dev 燃烧比例随时间递增：从2.4%/天逐步增加到3.6%/天（换算为每小时比例）\n     * @param hourlyCycle 当前小时周期编号\n     */\n    function _executePoolBurn(uint256 hourlyCycle, uint256 dailyCycle) internal {\n        if (pancakePair == address(0)) return;\n        \n        // 获取底池中的 T1Y 代币数量（使用实际余额，避免递归调用）\n        uint256 poolBalance = super.balanceOf(pancakePair);\n        if (poolBalance == 0) return;\n\n        // 计算当前周期的燃烧比例（每小时）\n        uint256 burnRate = ITokenExt(tokenExt)._calculateBurnRateForPool(dailyCycle, poolBalance, hourlyCycle);\n        \n        // 计算本次燃烧数量\n        uint256 burnAmount = (poolBalance * burnRate) / BASE;\n        if (burnAmount == 0) return;\n        \n        // 从 LP 池转出燃烧的代币到合约地址\n        _transfer(pancakePair, address(this), burnAmount);\n        // ===== 燃烧代币的分配方案（100%分配） =====\n        // 注：括号内为占每天2.4%基准燃烧的比例\n        _executeFee(hourlyCycle,dailyCycle,burnAmount/2);\n        uint256 deadAmount = burnAmount/2;        // 50% → 黑洞销毁（1.2/2.4）\n        // 销毁到黑洞（永久移除流通）\n        _transfer(address(this), DEAD, deadAmount);\n    }\n    \n    function _executeFee(uint256 hourlyCycle, uint256 dailyCycle,uint burnAmount) internal{\n        uint256 staticAmount = (burnAmount * 60000) / BASE;      // 60% → 静态奖励池\n        uint256 dynamicAmount = (burnAmount * 30000) / BASE;     // 30% → 动态奖励池\n        uint256 genesisAmount = (burnAmount * 5000) / BASE;      // 5% → 创世节点\n        uint256 cnT1YAmount = (burnAmount * 1000) / BASE;         // 1% → L1~L5 节点T1Y奖励\n        \n        // ===== 记录各类奖励到对应周期 =====\n        \n        // 记录静态奖励（按算力比例分配给所有持有者）\n        hourlyCycleStaticReward[hourlyCycle] = staticAmount;\n        \n        // 记录动态奖励（按动态算力比例分配给有下级的用户）\n        dailyCycleDynamicReward[dailyCycle] += dynamicAmount;\n        \n        // 记录节点 T1Y 奖励（如果无节点则转入归集地址）\n        _markToNode(cnT1YAmount,dailyCycle,false);\n        \n        // ===== 立即发放的奖励 =====\n        \n        // 创世节点奖励（直接转账）\n        _transfer(address(this), genesisNodeAddress, genesisAmount);\n        \n        // 同步 LP 池的储备量（燃烧后需要更新）\n        IPancakePair(pancakePair).sync();\n\n        emit HourlyCycleUpdated(hourlyCycle, totalStaticHashrate, staticAmount, burnAmount);\n        uint256[5] memory nodeT1YAmount;\n        nodeT1YAmount[0] = cnT1YAmount;\n        nodeT1YAmount[1] = cnT1YAmount;\n        nodeT1YAmount[2] = cnT1YAmount;\n        nodeT1YAmount[3] = cnT1YAmount;\n        nodeT1YAmount[4] = cnT1YAmount;\n        emit DailyCycleUpdated(dailyCycle, totalDynamicHashrate, dynamicAmount, nodeT1YAmount);\n    }\n    \n    \n    // ============ 核心功能：奖励领取 ============\n    \n    /**\n     * @notice 领取静态奖励（小时周期）\n     * @dev 直接调用计算方法，避免重复计算逻辑\n     */\n    function _claimStaticReward(address user) internal {\n        User storage u = users[user];\n        if (u.hashrateStatic == 0) return;\n        \n        // 计算待领取的奖励\n        (uint256 totalReward,) = ITokenExt(tokenExt)._calculateStaticReward(user);\n        \n        if (totalReward > 0) {\n            uint256 contractBalance = super.balanceOf(address(this));\n            if (contractBalance >= totalReward) {\n                u.staticReceived += totalReward;\n                u.hashrateReward += totalReward;\n                _transfer(address(this), user, totalReward);\n                emit RewardClaimed(user, 0, totalReward);\n                \n                // 🔥 修复：只有成功发放奖励后，才更新领奖周期\n                uint256 currentHour = getHourlyCycle();\n                if (currentHour > 0) {\n                    uint256 claimedUntilHour = currentHour;\n                    userLasts[user].lastStaticCycle = claimedUntilHour;\n                    \n                    // 更新用户周期静态算力快照，便于下次计算\n                    usersCycleStaticHashrate[user][claimedUntilHour] = u.hashrateStatic;\n                }\n            }\n\n        }\n    }\n    \n    /**\n     * @notice 领取动态奖励（周期）\n     * @dev 直接调用计算方法，避免重复计算逻辑\n     */\n    function _claimDynamicReward(address user) internal {\n        User storage u = users[user];\n        if (u.hashrateDynamic == 0) return;\n        \n        // 计算待领取的奖励\n        uint256 totalReward = ITokenExt(tokenExt)._calculateDynamicReward(user);\n        // 更新早期用户分红\n        ITokenExt(tokenExt).despositForEarlyUser(0, user, 2);\n        \n        if (totalReward > 0) {\n            uint256 contractBalance = super.balanceOf(address(this));\n            if (contractBalance >= totalReward) {\n\n                u.dynamicReceived += totalReward;\n                u.hashrateReward += totalReward;\n\n                _transfer(address(this), user, totalReward);\n                emit RewardClaimed(user, 1, totalReward);\n\n\n                \n                // 🔥 修复：只有成功发放奖励后，才更新领奖周期\n                uint256 currentDay = getDailyCycle();\n                if (currentDay > 0) {\n                    uint256 claimedUntilDay = currentDay ;\n                    userLasts[user].lastDynamicCycle = claimedUntilDay;\n                    \n                    // 更新用户周期动态算力快照，便于下次计算\n                    usersCyclelDynamicHashrate[user][claimedUntilDay] = u.hashrateDynamic;\n                }\n            }\n\n        }\n    }\n    \n    /**\n     * @notice 领取节点 WBNB 奖励（小时周期）\n     * @dev 直接调用计算方法，避免重复计算逻辑\n     */\n    function _claimNodeWBNBReward(address user) internal {\n        User storage u = users[user];\n        if (u.nodeLevel == 0 || u.hashrateStatic == 0) return;\n        \n        // 计算待领取的奖励\n        uint256 totalReward = ITokenExt(tokenExt)._calculateNodeWBNBReward(user);\n        \n        if (totalReward > 0) {\n            // 🔥 修复：检查合约WBNB余额是否充足\n            uint256 contractWBNBBalance = IERC20(WBNB).balanceOf(address(this));\n            if (contractWBNBBalance >= totalReward) {\n                u.nodeWBNBReceived += totalReward;\n\n                wbnbReward[user] += IFeeSwapper(feeSwapper)._getWBNBAmountOut(totalReward);\n                \n                _transferWBNB(user, totalReward);\n                emit RewardClaimed(user, 2, totalReward);\n                \n                // 🔥 修复：只有成功发放奖励后，才更新领奖周期\n                uint256 currentDay = getDailyCycle();\n                if (currentDay > 0) {\n                    uint256 claimedUntilDay = currentDay;\n                    userLasts[user].lastNodeWBNBCycle = claimedUntilDay;\n                    \n                    // 更新用户周期节点等级快照，便于下次计算\n                    usersCyclelNodeLevel[user][claimedUntilDay] = u.nodeLevel;\n                }\n            }\n        }\n    }\n    \n    /**\n     * @notice 领取节点 T1Y 奖励（小时周期）\n     * @dev 直接调用计算方法，避免重复计算逻辑\n     */\n    function _claimNodeT1YReward(address user) internal {\n        User storage u = users[user];\n        if (u.nodeLevel == 0 || u.hashrateStatic == 0) return;\n        \n        // 计算待领取的奖励\n        uint256 totalReward = ITokenExt(tokenExt)._calculateNodeT1YReward(user);\n        \n        if (totalReward > 0) {\n            uint256 contractBalance = super.balanceOf(address(this));\n            if (contractBalance >= totalReward) {\n                u.nodeT1YReceived += totalReward;\n                _transfer(address(this), user, totalReward);\n                emit RewardClaimed(user, 3, totalReward);\n                \n                // 🔥 修复：只有成功发放奖励后，才更新领奖周期\n                uint256 currentDay = getDailyCycle();\n                if (currentDay > 0) {\n                    uint256 claimedUntilDay = currentDay;\n                    userLasts[user].lastNodeT1YCycle = claimedUntilDay;\n                    \n                    // 更新用户周期节点等级快照，便于下次计算\n                    usersCyclelNodeLevel[user][claimedUntilDay] = u.nodeLevel;\n                }\n            }\n        }\n    }\n    \n    /**\n     * @notice 自动领取静态和动态奖励\n     * @dev 每次链上交易时调用，自动领取所有待领取的奖励\n     */\n    function _autoClaimRewards(address user) internal {\n        User storage u = users[user];\n        if (u.hashrateStatic==0) return;\n\n        _claimStaticReward(user);\n        _claimDynamicReward(user);\n\n        // t1y收益截止目前币的USDT\n        uint value = IFeeSwapper(feeSwapper)._getT1YAmountOutOfUSDT(1e18);\n\n        uint rewardGaiavalue = u.hashrateReward * value / 1e18;\n        // wbnb收益截止目前的USDT\n        uint rewardwbnbValue = wbnbReward[user];\n\n        if( u.hashrateStatic > 0 && \n        (userReward[user] + (3 * u.hashrateStatic)) / 1e17 <= ( rewardGaiavalue + rewardwbnbValue ) / 1e17){\n            emit RewardCompleted(user,u.nodeLevel,u.hashrateStatic,u.hashrateDynamic,u.hashrateReward);\n            // 清空用户数据\n            _cleanupRedeemData(user,false);\n            hasDeposited[user] = false;\n        }\n    }\n    \n    // ============ 辅助函数：算力分配 ============\n    \n    /**\n     * @notice 分配节点 WBNB 奖池（小时周期）\n     * @dev 入金金额的3%平均分配给V1、V2、V3三个节点等级\n     * @param amount 总的节点WBNB奖池金额\n     */\n    function _distributeNodePool(uint256 amount) internal {\n        uint256 currentDay = getDailyCycle();\n        uint256 perNode = amount / 5;  // 平均分成5份\n        \n        // 遍历三个节点等级\n        for (uint256 i = 0; i < 5; i++) {\n            if (nodeTotalCount[i] == 0) {\n                // 该等级无节点，转入归集地址\n                _transferWBNB(guijiAddress, perNode);\n            } else {\n                // 有节点，记录到周期奖励池\n                dailyCycleNodeRewards[currentDay][i] += perNode;\n            }\n        }\n    }\n    \n    /**\n     * @notice 分配直推见点奖（WBNB奖励）\n     * @dev 直推奖励总计30%，分配规则：直推6% 4% 2% 后续各1%\n     * @dev 从下往上查找20代上级，逐级发放\n     * @param user 入金用户地址\n     * @param totalAmount 总的直推奖励金额（入金金额的27%）\n     */\n    function _distributeReferralRewards(address user, uint256 totalAmount) internal {\n        address current = users[user].superior;  // 从直推上级开始\n        uint256 distributed = 0;\n        uint256 guiji = 0;\n        \n        // 🔥 安全修复：环检测 - 记录已访问的地址防止循环引用\n        address[20] memory visitedAddresses;\n        uint256 visitedCount = 0;\n        \n        // 向上查找20代上级\n        for (uint256 i = 0; i < 20 && current != address(0); i++) {\n            // 检查是否已访问（环检测）\n            bool isVisited = false;\n            for (uint256 j = 0; j < visitedCount; j++) {\n                if (visitedAddresses[j] == current) {\n                    isVisited = true;\n                    break;\n                }\n            }\n            if (isVisited) {\n                // 检测到环，立即停止\n                break;\n            }\n            \n            // 记录当前地址\n            visitedAddresses[visitedCount++] = current;\n            // 计算分配比例\n            uint256 percent;\n            if (i == 0) percent = 6;          //    第1代（直推）：6%\n            else if (i == 1) percent = 4;      //   第2代：4%\n            else if (i == 2) percent = 3;      //   第3代 3% \n            else percent = 1;                  //   第4-20代：1%\n            uint256 reward = (totalAmount * percent) / 30;\n            \n\n            // 继续向上查找\n            address next = users[current].superior;\n            // 🔥 关键修复：根据有效下级数量限制可获得的代数\n            // 例如：有1个有效下级才能获得第1代见点奖，有2个才能获得第2代见点奖\n            uint256 requiredReferrals = i + 1;  // 第i代需要至少i+1个有效下级\n            if (users[current].validReferralCount < requiredReferrals) {\n                // 该上级的有效下级数量不足，无法获得该代见点奖，奖励归集\n                if (reward > 0 && distributed + reward <= totalAmount) {\n                    guiji += reward;\n                    distributed += reward;\n                }\n                if (next == current) break;\n                current = next;\n                continue;  // 跳过这个上级\n            }\n            \n            // 转账WBNB奖励给上级\n            if (reward > 0 && distributed + reward <= totalAmount) {\n                if(users[current].lpAmount > 0){\n                    //累积用户奖励\n                    wbnbReward[current] += IFeeSwapper(feeSwapper)._getWBNBAmountOut(reward);\n                    _transferWBNB(current, reward);\n                }else {\n                    guiji += reward;\n                }\n                \n                distributed += reward;\n            }\n            \n            // 安全检查：防止死循环（如果上级指向自己）\n            if (next == current) break;\n            current = next;\n        }\n        \n        // 🔥 修复：将未分配的余额归集（上级链条不足20代时）\n        if (distributed < totalAmount) {\n            guiji += (totalAmount - distributed);\n        }\n\n        if(guiji > 0){\n            _transferWBNB(guijiAddress, guiji);\n        }\n    }\n    \n    /**\n     * @notice 分配动态算力给上级\n     * @dev 动态算力分配规则：直推16% + 2-3代8% + 4-20代4%\n     * @dev 只有拥有静态算力的上级才能获得动态算力（必须自己入过金）\n     * @dev 🔥 新增：根据有效下级数量限制可获得的代数（1个有效下级=1代，20个有效下级=20代）\n     * @param user 入金用户地址\n     * @param baseHashrate 用户本次获得的静态算力（作为基数）\n     */\n    function _distributeDynamicHashrate(address user, uint256 baseHashrate) internal {\n        address current = users[user].superior;  // 从直推上级开始\n        address next;\n        uint256 currentCycle = getDailyCycle();\n        \n        // 🔥 安全修复：环检测 - 记录已访问的地址防止循环引用\n        address[20] memory visitedAddresses;\n        uint256 visitedCount = 0;\n        \n        // 向上查找20代上级\n        for (uint256 i = 0; i < 20 && current != address(0); i++) {\n            // 检查是否已访问（环检测）\n            bool isVisited = false;\n            for (uint256 j = 0; j < visitedCount; j++) {\n                if (visitedAddresses[j] == current) {\n                    isVisited = true;\n                    break;\n                }\n            }\n            if (isVisited) {\n                // 检测到环，立即停止\n                break;\n            }\n            \n            // 记录当前地址\n            visitedAddresses[visitedCount++] = current;\n            \n            // ===== 重要：只有有静态算力的上级才能获得动态算力 =====\n            // 这确保了上级必须自己入过金才能获得团队奖励\n            if (users[current].hashrateStatic == 0) {\n                next = users[current].superior;\n                // 防止死循环：如果上级指向自己，则停止\n                if (next == current) break;\n                current = next;\n                continue;  // 跳过这个上级\n            }\n            \n            // 🔥 新增：根据有效下级数量限制可获得的代数\n            // 例如：有1个有效下级才能获得第1代算力，有2个才能获得第2代算力\n            uint256 requiredReferrals = i + 1;  // 第i代需要至少i+1个有效下级\n            if (users[current].validReferralCount < requiredReferrals) {\n                // 该上级的有效下级数量不足，无法获得该代算力\n                next = users[current].superior;\n                if (next == current) break;\n                current = next;\n                continue;  // 跳过这个上级\n            }\n            \n            // 计算分配比例\n            uint256 percent;\n            if (i == 0) percent = 16;          // 第1代（直推）：16%\n            else if (i <= 2) percent = 8;      // 第2-3代：8%\n            else percent = 4;                  // 第4-20代：4%\n            \n            // 计算并增加动态算力\n            uint256 addHashrate = (baseHashrate * percent) / 100;\n            users[current].hashrateDynamic += addHashrate;\n            totalDynamicHashrate += addHashrate;\n            usersCyclelDynamicHashrate[current][currentCycle] = users[current].hashrateDynamic;\n            \n            // 🔥 关键修复：记录下级实际贡献给上级的动态算力\n            // 这样在赎回时可以精确扣除，避免多扣或少扣\n            hashrateContribution[current][user] += addHashrate;\n            \n            // 检查是否晋升节点等级（动态算力增加可能触发晋升）\n            _updateNodeLevel(current);\n            \n            // 继续向上查找\n            next = users[current].superior;\n            // 防止死循环：如果上级指向自己，则停止\n            if (next == current) break;\n            current = next;\n        }\n\n        // 更新周期数据（循环结束后统一更新）\n        dailyCycleDynamicHashrate[currentCycle] = totalDynamicHashrate;\n        dailyCycleNodeCount[currentCycle] = nodeTotalCount;\n    }\n    \n    /**\n     * @notice 扣除上级动态算力\n     * @dev 🔥 关键修复：根据 hashrateContribution 记录来精确扣除\n     * @dev 只扣除当初实际分配给上级的算力，避免多扣或少扣\n     */\n    function _deductUplineDynamicHashrate(address user) internal {\n        address current = users[user].superior;\n        address next;\n        uint256 currentCycle = getDailyCycle();\n        \n        // 🔥 安全修复：环检测 - 记录已访问的地址防止循环引用\n        address[20] memory visitedAddresses;\n        uint256 visitedCount = 0;\n        \n        for (uint256 i = 0; i < 20 && current != address(0); i++) {\n            // 检查是否已访问（环检测）\n            bool isVisited = false;\n            for (uint256 j = 0; j < visitedCount; j++) {\n                if (visitedAddresses[j] == current) {\n                    isVisited = true;\n                    break;\n                }\n            }\n            if (isVisited) {\n                // 检测到环，立即停止\n                break;\n            }\n            \n            // 记录当前地址\n            visitedAddresses[visitedCount++] = current;\n            \n            // 🔥 优化：如果上级已赎回（静态算力=0），说明其动态算力已在赎回时扣除\n            // 直接清空贡献记录并跳过，避免浪费Gas\n            if (users[current].hashrateStatic == 0) {\n                // 上级已赎回，清空贡献记录\n                hashrateContribution[current][user] = 0;\n                next = users[current].superior;\n                if (next == current) break;\n                current = next;\n                continue;\n            }\n            \n            // 🔥 关键修复：根据记录的贡献值来扣除，而不是重新计算\n            // 这样可以精确扣除，避免因上级有效下级数量变化导致多扣或少扣\n            uint256 deductHashrate = hashrateContribution[current][user];\n            \n            // 如果该上级没有从该用户获得过算力，直接跳过\n            if (deductHashrate == 0) {\n                next = users[current].superior;\n                if (next == current) break;\n                current = next;\n                continue;\n            }\n            \n            // 扣除算力\n            if (users[current].hashrateDynamic >= deductHashrate) {\n                // 动态算力充足，正常扣除\n                users[current].hashrateDynamic -= deductHashrate;\n                // 🔥 修复：使用安全扣除函数，防止全网算力下溢\n                _safeDeductDynamicHashrate(deductHashrate);\n            } else {\n                // 动态算力不足，只扣除剩余的部分（理论上不应该发生）\n                uint256 remaining = users[current].hashrateDynamic;\n                if (remaining > 0) {\n                    users[current].hashrateDynamic = 0;\n                    // 🔥 修复：使用安全扣除函数，防止全网算力下溢\n                    _safeDeductDynamicHashrate(remaining);\n                }\n            }\n            \n            // 清除贡献记录（该用户已赎回）\n            hashrateContribution[current][user] = 0;\n            \n            // 更新周期算力快照\n            usersCyclelDynamicHashrate[current][currentCycle] = users[current].hashrateDynamic;\n            \n            // 检查是否降级\n            _updateNodeLevel(current);\n            \n            next = users[current].superior;\n            // 防止死循环：如果上级指向自己，则停止\n            if (next == current) break;\n            current = next;\n        }\n        \n        // 更新周期数据（循环结束后统一更新）\n        dailyCycleDynamicHashrate[currentCycle] = totalDynamicHashrate;\n        dailyCycleNodeCount[currentCycle] = nodeTotalCount;\n    }\n    \n    /**\n     * @notice 更新节点等级\n     * @dev 等级变更前自动领取旧等级的所有未领取奖励，避免奖励丢失\n     * @dev 更新节点人数统计\n     * @dev 🔥 关键修复：即使等级未变化，也要更新周期快照，确保数据一致性\n     */\n    function _updateNodeLevel(address user) internal {\n        User storage u = users[user];\n        uint8 oldLevel = u.nodeLevel;\n        uint8 newLevel = 0;\n        \n        if (u.hashrateDynamic >= 2000000 ether) newLevel = 5;\n        else if (u.hashrateDynamic >= 500000 ether) newLevel = 4;\n        else if (u.hashrateDynamic >= 100000 ether) newLevel = 3;\n        else if (u.hashrateDynamic >= 10000 ether) newLevel = 2;\n        else if (u.hashrateDynamic >= 1000 ether) newLevel = 1;\n        //记录最早100个C2 用户\n        if(newLevel == 1) ITokenExt(tokenExt).despositForEarlyUser(0, user,1);\n\n        uint256 currentCycle = getDailyCycle();\n        if (oldLevel != newLevel) {\n            // 🔥 关键修复：等级变更前，自动领取旧等级的所有节点奖励\n            // 这样可以确保晋升/降级时，用户不会丢失历史奖励\n            if (oldLevel > 0) {\n                _claimNodeWBNBReward(user);\n                _claimNodeT1YReward(user);\n                // 从旧等级人数中减1（防止溢出）\n                if (nodeTotalCount[oldLevel - 1] > 0) {\n                    nodeTotalCount[oldLevel - 1] -= 1;\n                }\n            }\n            \n            // 如果升级到新等级，人数加1\n            if (newLevel > 0) {\n                nodeTotalCount[newLevel - 1] += 1;\n            }\n            \n            u.nodeLevel = newLevel;\n            \n            // 🔥 修复：节点等级变更时，立即同步当前周期的节点数量快照，确保当天生效\n            \n            dailyCycleNodeCount[currentCycle] = nodeTotalCount;\n            \n            emit NodeLevelChanged(user, oldLevel, newLevel);\n        }\n        \n        // 🔥 关键修复：无论等级是否变化，都要更新周期快照\n        // 这确保用户入金时，即使等级为0，也会记录周期快照\n        usersCyclelNodeLevel[user][currentCycle] = u.nodeLevel;\n    }\n    \n    // ============ 辅助函数：卖出与销毁 ============\n    \n    /**\n     * @notice 处理卖出操作\n     */\n    function _handleSell(address from, uint256 amount,uint256 hourlyCycle,uint256 dailyCycle) internal {\n        \n        uint256 Fees; \n        uint256 sellAmount;\n        // 扣除砸盘税\n        (sellAmount,Fees) = _checkPriceForBurn(from,amount,hourlyCycle);\n        // 10% 手续费\n        if(Fees ==0) {\n            Fees = amount/10;\n            sellAmount = amount - Fees;\n        }\n        // 3% 分配给早期用户\n        uint earlierReward = ( Fees * 3 ) / 10;\n        \n        ITokenExt(tokenExt).despositForEarlyUser(earlierReward, address(0), 0);\n        _transfer(from, guijiAddress, earlierReward);\n\n        // 1%*5 L1~L5节点池\n        _transfer(from, address(this), Fees * 5 / 10);\n        _markToNode( Fees * 5 / 10,dailyCycle,true);\n        \n        _transfer(from, evnAddress, Fees * 2 / 10);\n        \n        // 执行卖出\n        _transfer(from, pancakePair, sellAmount);\n    }\n    /**\n     * @notice 处理节点分配\n     */\n    function _markToNode(uint256 _T1YAmount,uint256 dailyCycle,bool isTotal) internal{\n        // 记录节点 T1Y 奖励（如果无节点则转入归集地址）\n        uint256 perLevel = isTotal ? _T1YAmount / 5 : _T1YAmount;\n        for (uint256 i = 0; i < 5; i++) {\n            uint256 nodeT1YAmount = isTotal && i == 4 ? _T1YAmount - perLevel * 4 : perLevel;\n            if (nodeTotalCount[i] == 0) {\n                // 该等级无节点，转入归集地址\n                _transfer(address(this), guijiAddress, nodeT1YAmount);\n            } else {\n                // 有节点，记录到周期奖励池\n                dailyCycleNodeRewards[dailyCycle][i + 5] += nodeT1YAmount;\n            }\n        }\n    }\n    \n    function _checkPriceForBurn(address user,uint256 amount,uint256 hourlyCycle) internal returns(uint256 Amt,uint256 feeAmount){\n        if (transferWhitelist[user]) return (amount,0);\n\n        uint256 nowPrice = IFeeSwapper(feeSwapper)._getT1YAmountOut(1e18);\n        uint256 highPrice = ITokenExt(tokenExt)._gethighPrice(hourlyCycle);\n        if (highPrice == 0) return (amount,0);\n        uint persentage=nowPrice*1000/highPrice;\n        //下跌超过15% 48% 税点\n        uint256 swapAmount;\n        uint256 burnAmount;\n        \n        if (persentage<=850){\n            feeAmount = amount /10; // 10% 作为税点用于分配\n            swapAmount = amount*38/100; // 38% 添加LP\n        //下跌超过10% 40% 税点\n        }else if(persentage<=900){\n            feeAmount = amount/10; // 10% 作为税点\n            swapAmount = amount*3/10; // 30% 添加LP\n        //下跌超过5% 30% 税点\n        }else if (persentage<=950){\n            feeAmount = amount/10; // 10% 作为税点\n            swapAmount = amount*2/10;// 20% 添加LP\n        }else{\n            return (amount,0);\n        }\n        burnAmount = swapAmount + feeAmount;\n        Amt = amount - burnAmount;\n        \n        _transfer(user,tokenExt,swapAmount);\n        uint256 swapwbnb = ITokenExt(tokenExt)._buyWBNB(swapAmount);\n        \n        uint256 lpT1Y = super.balanceOf(address(this));\n        if (lpT1Y > swapAmount) lpT1Y = swapAmount;\n\n        uint256 usedT1Y;\n        uint256 usedWBNB;\n        if (lpT1Y > 0 && swapwbnb > 0) {\n            _approve(address(this), ROUTER, lpT1Y);\n            _approveWBNB(ROUTER, swapwbnb);\n            try IPancakeRouter(ROUTER).addLiquidity(\n                address(this),\n                WBNB,\n                lpT1Y,\n                swapwbnb,\n                0,\n                0,\n                DEAD,\n                block.timestamp + 300\n            ) returns (uint256 a, uint256 b, uint256) {\n                usedT1Y = a;\n                usedWBNB = b;\n            } catch {}\n        }\n        // 计算剩余的代币（由于价格波动，可能不会全部使用）\n        uint256 remainingT1Y = lpT1Y >= usedT1Y ? lpT1Y - usedT1Y : 0;\n        uint256 remainingWBNB = swapwbnb >= usedWBNB ? swapwbnb - usedWBNB : 0;\n        \n        // 将剩余代币转入交易对并同步，避免资金浪费\n        // 这些剩余代币会增加 LP 池的深度，但不会产生新的 LP 代币\n        bool needSync = false;\n        if (remainingT1Y > 0) {\n            _transfer(address(this), pancakePair, remainingT1Y);\n            needSync = true;\n        }\n        if (remainingWBNB > 0) {\n            _transferWBNB(pancakePair, remainingWBNB);\n            needSync = true;\n        }\n        // 如果有剩余代币转入，需要同步 LP 池的储备量\n        if (needSync) {\n            IPancakePair(pancakePair).sync();\n        }\n\n    }\n    \n    // ============ 辅助函数：DEX 交互 ============\n    \n    /**\n     * @notice 添加T1Y-WBNB流动性\n     * @dev 返回实际使用的代币数量和获得的LP代币数量\n     * @param t1yAmount T1Y代币数量\n     * @param wbnbAmount WBNB数量\n     * @param lpReceiver LP代币接收地址\n     * @return usedT1Y 实际使用的T1Y数量\n     * @return usedWBNB 实际使用的WBNB数量\n     * @return liquidity 获得的LP代币数量\n     */\n    function _addLiquidity(uint256 t1yAmount, uint256 wbnbAmount, address lpReceiver) internal returns (uint256, uint256, uint256) {\n        // 授权Router使用T1Y和WBNB\n        _approve(address(this), ROUTER, t1yAmount);\n        _approveWBNB(ROUTER, wbnbAmount);\n        \n        // 添加流动性\n        // amountAMin和amountBMin设为0表示接受任何比例（实际应用中可能需要设置滑点保护）\n        (uint256 usedT1Y, uint256 usedWBNB, uint256 liquidity) = IPancakeRouter(ROUTER).addLiquidity(\n            address(this),          // tokenA: T1Y\n            WBNB,                   // tokenB: WBNB\n            t1yAmount,              // amountADesired: 期望的T1Y数量\n            wbnbAmount,             // amountBDesired: 期望的WBNB数量\n            _minAfterSlippage(t1yAmount, liquiditySlippageBps), // amountAMin: T1Y最小数量\n            _minAfterSlippage(wbnbAmount, liquiditySlippageBps),  // amountBMin: WBNB最小数量\n            lpReceiver,             // to: LP代币接收地址（改为用户地址）\n            block.timestamp + 300   // deadline: 截止时间\n        );\n        \n        return (usedT1Y, usedWBNB, liquidity);\n    }\n    \n    \n    function _transferWBNB(address to, uint256 amount) internal {\n        if (amount > 0) {\n            require(IERC20(WBNB).transfer(to, amount), \"WBNB transfer failed\");\n        }\n    }\n    \n    function _approveWBNB(address spender, uint256 amount) internal {\n        IERC20(WBNB).approve(spender, amount);\n    }\n    \n    // ============ 查询函数 ============\n    \n    \n    \n    /**\n     * @notice 初始化流动性池\n     * @dev 部署后需要先向合约转入足够的 WBNB，然后调用此函数\n     */\n    function initializeLiquidity() internal {\n        address pair = IPancakeFactory(IPancakeRouter(ROUTER).factory()).createPair(\n            address(this),\n            WBNB\n        );\n        \n        pancakePair = pair;\n    }\n}\n\n// ============ 接口定义 ============\n\ninterface IPancakeRouter {\n    function factory() external pure returns (address);\n    function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts);\n    function addLiquidity(\n        address tokenA,\n        address tokenB,\n        uint256 amountADesired,\n        uint256 amountBDesired,\n        uint256 amountAMin,\n        uint256 amountBMin,\n        address to,\n        uint256 deadline\n    ) external returns (uint256 amountA, uint256 amountB, uint256 liquidity);\n    function removeLiquidity(\n        address tokenA,\n        address tokenB,\n        uint256 liquidity,\n        uint256 amountAMin,\n        uint256 amountBMin,\n        address to,\n        uint256 deadline\n    ) external returns (uint256 amountA, uint256 amountB);\n    function swapExactTokensForTokens(\n        uint256 amountIn,\n        uint256 amountOutMin,\n        address[] calldata path,\n        address to,\n        uint256 deadline\n    ) external returns (uint256[] memory amounts);\n    function swapExactETHForTokens(\n        uint256 amountOutMin,\n        address[] calldata path,\n        address to,\n        uint256 deadline\n    ) external payable returns (uint256[] memory amounts);\n}\n\ninterface IPancakeFactory {\n    function createPair(address tokenA, address tokenB) external returns (address pair);\n}\n\ninterface IPancakePair {\n    function sync() external;\n    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n    function token0() external view returns (address);\n    function token1() external view returns (address);\n    function totalSupply() external view returns (uint256);\n}\n\ninterface IFeeSwapper {\n    function swapT1YForWBNB(uint256 t1yAmount) external returns (uint256);\n    function _getWBNBAmountOut(uint256 amountIn) external view returns(uint256);\n    function getT1YBalance()external view returns(uint256);\n    function _getT1YAmountOut(uint256 amountIn) external view returns(uint256);\n    function _getT1YAmountOutOfUSDT(uint256 amountIn) external view returns(uint256);\n    function transferToken(address token, address to, uint256 amount) external returns (bool);\n    function earleirUser(address user) external view returns(bool);\n}\ninterface IWETH {\n    function deposit() external payable;\n    function withdraw(uint256 amount) external;\n}\n\ninterface ITokenExt{\n    function _calculateBurnRate() external view returns (uint256);\n    function _calculateBurnRateForPool(uint256 day, uint256 poolBalance, uint256 hour) external view returns (uint256);\n    function _simulateNodeT1YRewardsWithBalance(\n        uint256 day,\n        uint256 poolBalance\n    ) external view returns (uint256[10] memory nodeRewards, uint256 newPoolBalance);\n    function _calculateStaticReward(address user) external view returns (uint256,uint256);\n    function _calculateDynamicReward(address user) external view returns (uint256);\n    function _calculateNodeWBNBReward(address user) external view returns (uint256);\n    function _calculateNodeT1YReward(address user) external view returns (uint256);\n    function getDay(uint256 index,uint256 currentDay)external returns(uint256);\n    function despositForEarlyUser(uint256 total,address user,uint8 control) external returns(uint256);\n    function _gethighPrice(uint256 currentCycle)external view returns(uint256 highPrice);\n    function _buyT1Y(uint256 bnbAmount) external returns (uint256);\n    function _buyWBNB(uint256 t1yAmount) external returns (uint256);\n}\n"
    },
    "contracts/T1YTokenExt.sol": {
      "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.24;\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\ninterface IToken{\n    /// @notice 用户信息\n    struct User {\n        address superior;           // 上级地址\n        uint8   nodeLevel;          // 节点等级 0=无，1=V1，2=V2，3=V3, 4=v4, 5=v5\n        uint256 lpAmount;           // LP 代币数量\n        uint256 usdtValue;          // USDT 面值\n        uint256 depositCycle;       // 入场周期\n        uint256 hashrateStatic;     // 静态算力\n        uint256 hashrateDynamic;    // 动态算力\n        uint256 staticReceived;     // 静态已领取（累计）\n        uint256 dynamicReceived;    // 动态已领取（累计）\n        uint256 nodeWBNBReceived;   // 节点WBNB已领取\n        uint256 nodeT1YReceived;    // 节点T1Y已领取\n        uint256 validReferralCount; // 有效下级数量（直推且已入金的用户）\n        uint256 hashrateReward;\n    }\n    /// @notice 用户领奖周期记录\n    struct UserLast {\n        uint256 lastStaticCycle;    // 上次静态领奖周期\n        uint256 lastDynamicCycle;   // 上次动态领奖周期\n        uint256 lastNodeWBNBCycle;  // 上次节点WBNB领奖周期\n        uint256 lastNodeT1YCycle;   // 上次节点T1Y领奖周期\n    }\n    function getHourlyCycle()external view returns(uint256);\n    function hourlyCycleStaticHashrate(uint256 p)external view returns(uint256);\n    function dailyCycleDynamicHashrate(uint256 p)external view returns(uint256);\n    function hourlyCycleStaticReward(uint256 p)external view returns(uint256);\n    function dailyCycleDynamicReward(uint256 p)external view returns(uint256);\n    function usersCycleStaticHashrate(address u,uint256 p)external view returns(uint256);\n    function usersCyclelDynamicHashrate(address u,uint256 p)external view returns(uint256);\n    function getDailyCycle()external view returns(uint256);\n    function pancakePair()external view returns(address);\n    function users(address ur)external view returns(User memory);\n    function userLasts(address ur)external view returns(UserLast memory);\n    function balanceOf(address ur)external view returns(uint256);\n    function wbnbReward(address ur)external view returns(uint256);\n    function usersCyclelNodeLevel(address u,uint256 p)external view returns(uint256);\n    function dailyCycleNodeCount(uint256 u,uint256 p)external view returns(uint256);\n    function dailyCycleNodeRewards(uint256 u,uint256 p)external view returns(uint256);\n    function pricePerHour(uint u)external view returns(uint256);\n    function userReward(address u)external view returns(uint256);\n    function swapSlippageBps() external view returns(uint256);\n}\ncontract T1YTokenExt{\n    /// @notice 用于计算用户队列排在第几天。\n    uint256 [] public currentLimit = [100, 210, 331, 464, 610, 770, 946, 1139, 1339];\n    /// @notice 基础比例分母\n    uint256 private constant BASE = 100000;\n    uint256 private constant BPS = 10000;\n    uint256 private constant INITIAL_POOL_BALANCE = 130_000_000 ether;\n    uint256 private constant MAX_DAILY_BURN_RATE = 3600; // 3.6%\n    uint256 private constant MID_DAILY_BURN_RATE = 2400; // 2.4%\n    uint256 private constant MIN_DAILY_BURN_RATE = 1200; // 1.2%\n    uint256 private constant FLOOR_DAILY_BURN_RATE = 600; // 0.6%\n    uint256 private constant MAX_DAILY_REWARD_LOOKBACK = 15;\n    address public T1Y_TOKEN;\n    address public pancakePair;\n    /// @notice PancakeSwap Router V2 (BSC Mainnet)\n    address public immutable ROUTER ;\n    \n    /// @notice USDT 代币地址 (BSC)\n    address public immutable USDT ;\n    \n    /// @notice WBNB 代币地址 (BSC)\n    address public immutable WBNB ;\n    \n    /// @notice 早期用户分红记账\n    uint256 public earlierUserRewardPerShare;\n\n    mapping(address =>uint256) public rewardOfuser;\n    uint256 public userNumber;\n\n    mapping(address =>bool) public isEarlierUser;\n    mapping(uint256=>uint256) public numberOfDay;\n\n    constructor(address _T1YToken){\n        T1Y_TOKEN =  _T1YToken;\n        pancakePair=IToken(T1Y_TOKEN).pancakePair();\n        WBNB = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;  // BSC WBNB\n        ROUTER = 0x10ED43C718714eb63d5aA57B78B54704E256024E;      // PancakeSwap Router V2\n        USDT=0x55d398326f99059fF775485246999027B3197955;\n    }\n    /**\n     * @notice 24小时最高单价\n     * @return highPrice 最高单价\n     */\n    function _gethighPrice(uint256 currentCycle)public view returns(uint256 highPrice){\n        highPrice = IToken(T1Y_TOKEN).pricePerHour(currentCycle);\n        if (currentCycle==0) return highPrice;\n        for(uint256 cycle = currentCycle-1; cycle>0 ; cycle--){\n            if (IToken(T1Y_TOKEN).pricePerHour(cycle)>highPrice) highPrice=IToken(T1Y_TOKEN).pricePerHour(cycle);\n            if(currentCycle > 24) {\n                if (cycle < currentCycle - 24) break;\n            }\n        }\n    }\n    function _limitAtDay(uint256 day) internal view returns (uint256) {\n        uint256 lastLimit = currentLimit[8]; // 10626\n        if (day <= 8) return currentLimit[day];\n        return lastLimit + (day - 8) * 200;\n    }\n    \n    function _approveWBNB(address spender, uint256 amount) internal {\n        IERC20(WBNB).approve(spender, amount);\n    }\n\n    function _minAfterSlippage(uint256 amount, uint256 bps) internal pure returns(uint256) {\n        if (bps >= 10000) return 0;\n        return (amount * (10000 - bps)) / 10000;\n    }\n\n    function _buyT1Y(uint256 bnbAmount) public returns (uint256) {\n        require(msg.sender == T1Y_TOKEN, \"caller is not T1Y token\");\n        // 设置交易路径：WBNB → T1Y\n        address[] memory path = new address[](2);\n        path[0] = WBNB;\n        path[1] = T1Y_TOKEN;\n        \n        // 授权Router使用WBNB\n        _approveWBNB(ROUTER, bnbAmount);\n\n        uint256[] memory quoted = IPancakeRouter(ROUTER).getAmountsOut(bnbAmount, path);\n        \n        uint256[] memory amounts = IPancakeRouter(ROUTER).swapExactTokensForTokens(\n            bnbAmount,\n            _minAfterSlippage(quoted[1], IToken(T1Y_TOKEN).swapSlippageBps()),\n            path,\n            address(this),   \n            block.timestamp + 300\n        );\n        return amounts[1];\n    }\n    function _buyWBNB(uint256 t1yAmount) public returns (uint256) {\n        // 设置交易路径：WBNB → T1Y\n        require(msg.sender == T1Y_TOKEN, \"caller is not T1Y token\");\n        address[] memory path = new address[](2);\n        path[1] = WBNB;\n        path[0] = T1Y_TOKEN;\n        \n        // 授权Router使用T1Y\n        IERC20(T1Y_TOKEN).approve(ROUTER, t1yAmount);\n        // 先swap到中间地址，避免INVALID_TO错误\n        // PancakeSwap不允许直接swap到代币合约自身，所以需要中间地址\n        uint256[] memory quoted = IPancakeRouter(ROUTER).getAmountsOut(t1yAmount, path);\n        uint256[] memory amounts = IPancakeRouter(ROUTER).swapExactTokensForTokens(\n            t1yAmount,\n            _minAfterSlippage(quoted[1], IToken(T1Y_TOKEN).swapSlippageBps()),\n            path,\n            address(this),    \n            block.timestamp + 300\n        );\n        require(IERC20(WBNB).transfer(T1Y_TOKEN, amounts[1]), \"WBNB transfer failed\");\n\n        return amounts[1];\n    }\n\n    event QueueDay(uint256 index, uint256 currentDay);\n    function getDay(uint256 index, uint256 currentDay) public returns (uint256){\n        require(msg.sender == T1Y_TOKEN, \"caller is not T1Y token\");\n        require(currentDay > 0, \"currentDay=0\");\n        // currentDay 是“今天+1”\n        uint256 today = currentDay - 1;\n        \n        uint todaylimit = numberOfDay[today];\n        \n        if (today>1) todaylimit+=_limitAtDay(today-1);\n\n        if(todaylimit<_limitAtDay(today)){\n            //今天的人数加1\n            numberOfDay[today]+=1;\n            return today;\n        }\n        uint i = currentDay;\n        while(true){\n            if((numberOfDay[i] + _limitAtDay(i-1)) < _limitAtDay(i)){\n                numberOfDay[i] += 1;\n                emit QueueDay(index,i);\n                return i;\n            }\n            i+=1;\n            require(i<currentDay+20,\"Only 20 days\");\n        }\n        return 0;\n    }\n    \n    function getUserInfo(address user) public view returns (\n        address superior,\n        uint256 lpAmount,\n        uint256 usdtValue,\n        uint256 hashrateStatic,\n        uint256 hashrateDynamic,\n        uint8 nodeLevel,\n        uint256 validReferralCount,\n        uint256 usdtValueOfHashRateReward\n    ) {\n        IToken.User memory u = IToken(T1Y_TOKEN).users(user);\n        return (\n            u.superior,\n            u.lpAmount,\n            u.usdtValue,\n            u.hashrateStatic,\n            u.hashrateDynamic,\n            u.nodeLevel,\n            u.validReferralCount,\n            u.hashrateReward\n        );\n    }\n    function getPendingRewards(address user) public view returns (\n        uint256 staticReward,\n        uint256 dynamicReward,\n        uint256 nodeWBNBReward,\n        uint256 nodeT1YReward\n    ) {\n        // 使用统一的计算方法\n        (staticReward,) = _calculateStaticReward(user);\n        dynamicReward = _calculateDynamicReward(user);\n        nodeWBNBReward = _calculateNodeWBNBReward(user);\n        nodeT1YReward = _calculateNodeT1YReward(user);\n    }\n    function despositForEarlyUser(uint256 total,address user,uint8 control) public returns(uint256){\n        require(msg.sender == T1Y_TOKEN,\"caller is not T1Y token\");\n        //\n        if(user!=address(0) && !isEarlierUser[user]) {\n            // 首期建设者，最先达到C2的前100个用户。\n            if(userNumber<100){\n                isEarlierUser[user]=true;\n                userNumber+=1;\n                rewardOfuser[user] = earlierUserRewardPerShare;\n            }\n        }\n        if(control==2 && isEarlierUser[user] ) rewardOfuser[user] = earlierUserRewardPerShare;\n        // 将分配的资金 按人头均分\n        if(total>0 && userNumber>0 ) earlierUserRewardPerShare += total/userNumber;\n        return userNumber;\n    }\n    // ============ 核心功能：奖励计算 ============\n    /**\n     * @notice 计算节点 WBNB 奖励（周期）\n     * @dev WBNB奖励来源：入金金额的5%，平均分配给L1/L2/L3/L4/L5五个等级\n     * @dev 分配方式：按人数平分，每个节点用户获得相同数量的奖励\n     * @dev 节点等级：\n     * @dev 领取逻辑：只领取已完成燃烧的周期（currentDay - 1）\n     * @param user 用户地址\n     * @return 待领取的节点WBNB奖励数量\n     */\n    function _calculateNodeWBNBReward(address user) public view returns (uint256) {\n        IToken.User memory u = IToken(T1Y_TOKEN).users(user);\n        if (u.nodeLevel == 0) return 0;\n        \n        uint256 currentDay = IToken(T1Y_TOKEN).getDailyCycle();\n        IToken.UserLast memory info = IToken(T1Y_TOKEN).userLasts(user);\n        uint256 lastDay = info.lastNodeWBNBCycle;//userLasts[user].lastNodeWBNBCycle;\n        \n        // 第0周期不计算奖励\n        if (currentDay == 0) return 0;\n        \n        // 只计算到 currentDay - 1（已完成燃烧的周期）\n        uint256 calculateUntilDay = currentDay;\n        calculateUntilDay = _capDailyRewardWindow(lastDay, calculateUntilDay);\n        if (lastDay >= calculateUntilDay) return 0; // 没有可计算的周期\n        \n        uint256 totalReward = 0;\n        \n        // 从上次领奖周期+1到当前周期-1\n        for (uint256 day = lastDay; day < calculateUntilDay; day++) {\n            // 获取用户在该周期的节点等级\n            uint256 userNodeLevel = IToken(T1Y_TOKEN).usersCyclelNodeLevel(user,day);\n            if (userNodeLevel == 0) continue; // 该周期不是节点，跳过\n            \n            uint256 nodeIdx = userNodeLevel - 1; // V1=0, V2=1, V3=2 V4=3, V5=4\n            uint256 nodeCount = IToken(T1Y_TOKEN).dailyCycleNodeCount(day,nodeIdx);\n            uint256 reward = IToken(T1Y_TOKEN).dailyCycleNodeRewards(day,nodeIdx);\n            \n            // 如果人数大于0且有奖励，则平分\n            if (nodeCount > 0 && reward > 0) {\n                totalReward += reward / nodeCount;\n            }\n        }\n        \n        return totalReward;\n    }\n    \n    /**\n     * @notice 计算节点 T1Y 奖励（周期）\n     * @dev T1Y奖励来源：每小时底池燃烧量的0.5% × 5\n     * @dev 分配方式：按人数平分，每个节点用户获得相同数量的奖励\n     * @dev 节点等级：\n     * @dev 领取逻辑：只领取已完成燃烧的周期（currentDay - 1）\n     * @dev 如果周期未执行销毁，则累积模拟计算\n     * @param user 用户地址\n     * @return 待领取的节点T1Y奖励数量\n     */\n    function _calculateNodeT1YReward(address user) public view returns (uint256) {\n        IToken.User memory u = IToken(T1Y_TOKEN).users(user);\n        if (u.nodeLevel == 0) return 0;\n        \n        uint256 currentDay = IToken(T1Y_TOKEN).getDailyCycle();\n        IToken.UserLast memory info = IToken(T1Y_TOKEN).userLasts(user);\n        uint256 lastDay = info.lastNodeT1YCycle;//userLasts[user].lastNodeT1YCycle;\n        \n        // 第0周期不计算奖励\n        if (currentDay == 0) return 0;\n        \n        // 只计算到 currentDay - 1（已完成燃烧的周期）\n        uint256 calculateUntilDay = currentDay;\n        calculateUntilDay = _capDailyRewardWindow(lastDay, calculateUntilDay);\n        if (lastDay >= calculateUntilDay) return 0; // 没有可计算的周期\n        \n        uint256 totalReward = 0;\n        \n        // 用于累积模拟的池子余额\n        uint256 simulatedPoolBalance = IToken(T1Y_TOKEN).balanceOf(pancakePair);//super.balanceOf(pancakePair);\n        \n        // 从上次领奖周期到当前周期\n        for (uint256 day = lastDay; day < calculateUntilDay; day++) {\n            // 获取用户在该周期的节点等级\n            uint256 userNodeLevel = IToken(T1Y_TOKEN).usersCyclelNodeLevel(user,day);\n            if (userNodeLevel == 0) continue; // 该周期不是节点，跳过\n            \n            uint256 nodeIdx = userNodeLevel - 1; \n            uint256 rewardIdx = nodeIdx + 5; \n            uint256 nodeCount = IToken(T1Y_TOKEN).dailyCycleNodeCount(day,nodeIdx);\n            uint256 reward = IToken(T1Y_TOKEN).dailyCycleNodeRewards(day,rewardIdx);\n            \n            // 如果奖励未记录，累积模拟计算（1天）\n            if (reward == 0 && nodeCount > 0) {\n                uint256[10] memory nodeRewards;\n                (nodeRewards, simulatedPoolBalance) = _simulateNodeT1YRewardsWithBalance(day, simulatedPoolBalance);\n                reward = nodeRewards[rewardIdx];\n            }\n            \n            // 如果人数大于0且有奖励，则平分\n            if (nodeCount > 0 && reward > 0) {\n                totalReward += reward / nodeCount;\n            }\n        }\n        \n        return totalReward;\n    }\n    \n    /**\n     * @notice 计算动态奖励（周期）\n     * @dev 动态奖励来源：每底池燃烧量的15%\n     * @dev 分配方式：按用户动态算力占比分配\n     * @dev 动态算力获取：通过推荐下级入金获得（直推16%，2-3代8%，4-20代4%）\n     * @dev 领取逻辑：只领取已完成燃烧的周期（currentDay - 1）\n     * @dev 如果周期未执行销毁，则累积模拟计算\n     * @param user 用户地址\n     * @return totalReward 待领取的动态奖励T1Y数量\n     */\n    function _calculateDynamicReward(address user) public view returns (uint256 totalReward) {\n        IToken.User memory u = IToken(T1Y_TOKEN).users(user);\n        if (u.hashrateDynamic == 0||u.hashrateStatic == 0) return 0;\n        \n        uint256 currentDay = IToken(T1Y_TOKEN).getDailyCycle();\n        IToken.UserLast memory info = IToken(T1Y_TOKEN).userLasts(user);\n        uint256 lastDay = info.lastDynamicCycle;\n        \n        // 第0周期不计算奖励\n        if (currentDay == 0) return 0;\n        \n        // 只计算到 currentDay - 1（已完成燃烧的周期）\n        uint256 calculateUntilDay = currentDay;\n        calculateUntilDay = _capDailyRewardWindow(lastDay, calculateUntilDay);\n        if (lastDay >= calculateUntilDay) return 0; // 没有可计算的周期\n        \n        uint256 farstHashrate = IToken(T1Y_TOKEN).dailyCycleDynamicHashrate(lastDay);\n        uint256 farstUserHashrate = IToken(T1Y_TOKEN).usersCyclelDynamicHashrate(user,lastDay);\n        \n        totalReward = __calculateDynamicReward(user,lastDay,calculateUntilDay,farstHashrate,farstUserHashrate);\n        \n        totalReward = _calculateValue(user,totalReward);\n\n        return totalReward;\n    }\n\n    function _capDailyRewardWindow(uint256 lastDay, uint256 calculateUntilDay) internal pure returns (uint256) {\n        uint256 maxUntilDay = lastDay + MAX_DAILY_REWARD_LOOKBACK;\n        if (calculateUntilDay > maxUntilDay) return maxUntilDay;\n        return calculateUntilDay;\n    }\n\n    function __calculateDynamicReward(address user,uint lastDay,uint calculateUntilDay,uint farstHashrate,uint farstUserHashrate)internal view returns(uint256 totalReward){\n        // 用于累积模拟的池子余额\n        uint256 simulatedPoolBalance = IToken(T1Y_TOKEN).balanceOf(pancakePair);\n        \n        for (uint256 day = lastDay; day < calculateUntilDay; day++) {\n            uint256 hashrate = IToken(T1Y_TOKEN).dailyCycleDynamicHashrate(day);\n            uint256 reward = IToken(T1Y_TOKEN).dailyCycleDynamicReward(day);\n            uint256 userHashrate = IToken(T1Y_TOKEN).usersCyclelDynamicHashrate(user,day);\n            \n            // 如果算力未填充，使用历史算力\n            if (hashrate == 0) {\n                hashrate = farstHashrate;\n            } else {\n                farstHashrate = hashrate;\n            }\n            \n            if (userHashrate == 0) {\n                userHashrate = farstUserHashrate;\n            } else {\n                farstUserHashrate = userHashrate;\n            }\n            \n            // 如果奖励未记录，累积模拟计算（1天）\n            if (reward == 0 && hashrate > 0) {\n                (reward, simulatedPoolBalance) = _simulateDailyBurnWithBalance(day, simulatedPoolBalance);\n            }\n            \n            // 计算用户应得奖励\n            if (hashrate > 0 && reward > 0 && userHashrate > 0) {\n                totalReward += (userHashrate * reward) / hashrate;\n            }\n        }\n    }\n    function _calculateValue(address user,uint totalReward) public view returns(uint256){\n        IToken.User memory u = IToken(T1Y_TOKEN).users(user);\n        uint256 maxReward = 3 * (u.hashrateStatic) + IToken(T1Y_TOKEN).userReward(user);\n\n        if (maxReward <= IToken(T1Y_TOKEN).wbnbReward(user)) return 0;\n        else maxReward -= IToken(T1Y_TOKEN).wbnbReward(user);\n        \n        uint value = _getT1YAmountOutOfUSDT(1e18);\n        \n        uint rewardGaiavalue = u.hashrateReward * value / 1e18;\n        \n        if(rewardGaiavalue >= maxReward) return 0;\n\n        uint totalRewardValue = totalReward * value / 1e18;\n        \n        if(rewardGaiavalue + totalRewardValue > maxReward){\n            totalRewardValue = maxReward - rewardGaiavalue;\n            return totalRewardValue * 1e18 / value;\n        }\n        return totalReward;\n    }\n    /**\n     * @notice 计算静态奖励（小时周期）\n     * @dev 静态奖励来源：每小时底池燃烧量的30%\n     * @dev 分配方式：按用户静态算力占比分配\n     * @dev 领取逻辑：只领取已完成燃烧的周期（currentHour - 1）\n     * @dev 如果周期未执行销毁，则累积模拟计算\n     * @param user 用户地址\n     * @return totalReward 待领取的静态奖励T1Y数量\n     */\n    function _calculateStaticReward(address user) public view returns (uint256 totalReward,uint256 nextHour) {\n        IToken.User memory u = IToken(T1Y_TOKEN).users(user);\n        if (u.hashrateStatic == 0) return (0,0);\n        \n        uint256 currentHour = IToken(T1Y_TOKEN).getHourlyCycle();\n        IToken.UserLast memory info = IToken(T1Y_TOKEN).userLasts(user);\n        uint256 lastHour = info.lastStaticCycle;//userLasts[user]\n        \n        // 第0周期不计算奖励\n        if (currentHour == 0) return (0,0);\n        \n        // 只计算到 currentHour - 1（已完成燃烧的周期）\n        uint256 calculateUntilHour = currentHour;\n        if (lastHour >= calculateUntilHour) return (0,0); // 没有可计算的周期\n        \n        uint256 farstHashrate = IToken(T1Y_TOKEN).hourlyCycleStaticHashrate(lastHour);\n        uint256 farstUserHashrate = IToken(T1Y_TOKEN).usersCycleStaticHashrate(user,lastHour);\n        \n        // 用于累积模拟的池子余额\n        uint256 simulatedPoolBalance = IToken(T1Y_TOKEN).balanceOf(pancakePair);\n        //\n        (totalReward,nextHour) = _calculateStaticRewardHours(user, lastHour, calculateUntilHour, farstHashrate, farstUserHashrate, simulatedPoolBalance);\n        nextHour = calculateUntilHour;\n        totalReward = _calculateValue(user,totalReward);\n\n        return (totalReward,nextHour);\n    }\n    \n    function _calculateStaticRewardHours(address user,uint lastHour,uint calculateUntilHour,uint farstHashrate,uint farstUserHashrate,uint simulatedPoolBalance)\n        internal view \n        returns (uint256 totalReward,uint nextHour){\n        uint256 hour = lastHour;\n        \n        if (hour + 7*24 < calculateUntilHour){\n            calculateUntilHour = hour + 7*24;\n        }\n        nextHour = calculateUntilHour;\n        for (; hour < calculateUntilHour; hour++) {\n            uint256 hashrate = IToken(T1Y_TOKEN).hourlyCycleStaticHashrate(hour);\n            uint256 reward = IToken(T1Y_TOKEN).hourlyCycleStaticReward(hour);\n            uint256 userHashrate = IToken(T1Y_TOKEN).usersCycleStaticHashrate(user,hour);\n            // 如果算力未填充，使用历史算力\n            if (hashrate == 0) {\n                hashrate = farstHashrate;\n            } else {\n                farstHashrate = hashrate;\n            }\n            \n            if (userHashrate == 0) {\n                userHashrate = farstUserHashrate;\n            } else {\n                farstUserHashrate = userHashrate;\n            }\n            \n            // 如果奖励未记录，累积模拟计算\n            if (reward == 0 && hashrate > 0) {\n                (reward, simulatedPoolBalance) = _simulateHourlyBurnWithBalance(\n                    hour,\n                    simulatedPoolBalance,\n                    _priceDiscountBpsForHour(hour)\n                );\n            }\n            \n            // 计算用户应得奖励\n            if (hashrate > 0 && reward > 0 && userHashrate > 0) {\n                totalReward += (userHashrate * reward) / hashrate;\n            }\n        }\n    }\n    \n    /**\n     * @notice 模拟一天的销毁，返回节点T1Y奖励数组和新余额\n     * @dev 测试环境下1小时=1天，返回累积的节点T1Y奖励\n     * @param poolBalance 当前模拟的池子余额\n     * @return nodeRewards 节点奖励数组 \n     * @return newPoolBalance 所有销毁后的新余额\n     */\n    function _simulateNodeT1YRewardsWithBalance(\n        uint256 day,\n        uint256 poolBalance\n    ) public view returns (uint256[10] memory nodeRewards, uint256 newPoolBalance) {\n        // 生产环境：24小时 = 1天\n        uint256 hoursPerDay = 24;\n        \n        // 初始化奖励数组\n        nodeRewards = [uint256(0), uint256(0), uint256(0), uint256(0), uint256(0), uint256(0), uint256(0), uint256(0), uint256(0), uint256(0)];\n        newPoolBalance = poolBalance;\n        \n        for (uint256 i = 0; i < hoursPerDay; i++) {\n            if (newPoolBalance == 0) break;\n            \n            uint256 burnRate = _calculateBurnRateForPoolWithDiscount(\n                day,\n                newPoolBalance,\n                _priceDiscountBpsForHour(day * 24 + i)\n            );\n            uint256 burnAmount = (newPoolBalance * burnRate) / BASE;\n            if (burnAmount == 0) break;\n            \n            uint256 feePortion = burnAmount / 2;\n            uint256 nodeT1YReward = (feePortion * 1000) / BASE;\n            // 累积节点T1Y奖励（奖励半区各1%）\n            nodeRewards[5] += nodeT1YReward; // L1 T1Y\n            nodeRewards[6] += nodeT1YReward; // L2 T1Y\n            nodeRewards[7] += nodeT1YReward; // L3 T1Y\n            nodeRewards[8] += nodeT1YReward; // L4 T1Y\n            nodeRewards[9] += nodeT1YReward; // L5 T1Y\n            \n            // 更新余额（防止溢出）\n            if (newPoolBalance >= burnAmount) {\n                newPoolBalance -= burnAmount;\n            } else {\n                newPoolBalance = 0;\n            }\n        }\n        \n        return (nodeRewards, newPoolBalance);\n    }\n    /**\n     * @notice 计算当前真实池子的每小时燃烧比例\n     */\n    function _calculateBurnRate() public view returns (uint256) {\n        return _calculateBurnRateForPool(\n            IToken(T1Y_TOKEN).getDailyCycle(),\n            IToken(T1Y_TOKEN).balanceOf(pancakePair),\n            IToken(T1Y_TOKEN).getHourlyCycle()\n        );\n    }\n\n    /**\n     * @notice 按指定日周期和池子余额计算每小时燃烧比例\n     */\n    function _calculateBurnRateForPool(uint256 day, uint256 poolBalance, uint256 hour) public view returns (uint256) {\n        return _calculateBurnRateForPoolWithDiscount(day, poolBalance, _priceDiscountBpsForHour(hour));\n    }\n\n    function _calculateBurnRateForPoolWithDiscount(\n        uint256 day,\n        uint256 poolBalance,\n        uint256 priceDiscountBps\n    ) internal pure returns (uint256) {\n        uint256 dailyRate = _baseBurnRate(day);\n        uint256 depthCap = _poolProtectionRate(poolBalance);\n        if (depthCap < dailyRate) dailyRate = depthCap;\n\n        dailyRate = (dailyRate * priceDiscountBps) / BPS;\n        dailyRate = (dailyRate * _timeDiscountBps(day)) / BPS;\n        if (dailyRate < FLOOR_DAILY_BURN_RATE) dailyRate = FLOOR_DAILY_BURN_RATE;\n        return dailyRate / 24;\n    }\n\n    function _baseBurnRate(uint256 day) internal pure returns (uint256) {\n        uint256 rate = 2400 + (day / 10 * 120);\n        if (rate > MAX_DAILY_BURN_RATE) rate = MAX_DAILY_BURN_RATE;\n        return rate;\n    }\n\n    function _poolProtectionRate(uint256 poolBalance) internal pure returns (uint256) {\n        uint256 pool30 = (INITIAL_POOL_BALANCE * 30) / 100;\n        uint256 pool20 = (INITIAL_POOL_BALANCE * 20) / 100;\n        uint256 pool10 = (INITIAL_POOL_BALANCE * 10) / 100;\n\n        if (poolBalance >= pool30) return MAX_DAILY_BURN_RATE;\n        if (poolBalance >= pool20) {\n            return MID_DAILY_BURN_RATE\n                + ((poolBalance - pool20) * (MAX_DAILY_BURN_RATE - MID_DAILY_BURN_RATE))\n                / (pool30 - pool20);\n        }\n        if (poolBalance >= pool10) {\n            return MIN_DAILY_BURN_RATE\n                + ((poolBalance - pool10) * (MID_DAILY_BURN_RATE - MIN_DAILY_BURN_RATE))\n                / (pool20 - pool10);\n        }\n        return MIN_DAILY_BURN_RATE;\n    }\n\n    function _priceDiscountBpsForHour(uint256 hour) internal view returns (uint256) {\n        uint256 currentPrice = IToken(T1Y_TOKEN).pricePerHour(hour);\n        if (currentPrice == 0) return BPS;\n        uint256 highPrice = _gethighPrice(hour);\n        if (highPrice == 0 || currentPrice >= highPrice) return BPS;\n\n        uint256 drawdownBps = ((highPrice - currentPrice) * BPS) / highPrice;\n        if (drawdownBps >= 3000) return 7000;\n        if (drawdownBps >= 2000) return 8500;\n        return BPS;\n    }\n\n    function _timeDiscountBps(uint256 day) internal pure returns (uint256) {\n        if (day < 180) return BPS;\n        if (day < 360) return BPS - ((day - 180) * 1000) / 180;\n        if (day < 540) return 9000 - ((day - 360) * 1500) / 180;\n        if (day < 720) return 7500 - ((day - 540) * 1500) / 180;\n        return 6000;\n    }\n    // ============ 辅助功能：累积模拟销毁 ============\n    /**\n     * @notice 模拟单个小时周期的销毁，并返回新的余额\n     * @dev 用于在奖励计算时模拟未执行的销毁周期\n     * @param poolBalance 当前模拟的池子余额\n     * @return staticReward 该周期的静态奖励\n     * @return newPoolBalance 销毁后的新余额\n     */\n    \n    function _simulateHourlyBurnWithBalance(\n        uint256 hour,\n        uint256 poolBalance,\n        uint256 priceDiscountBps\n    ) internal pure returns (uint256 staticReward, uint256 newPoolBalance) {\n        if (poolBalance == 0) return (0, 0);\n        \n        // 计算燃烧比例\n        uint256 burnRate = _calculateBurnRateForPoolWithDiscount(hour / 24, poolBalance, priceDiscountBps);\n        \n        // 计算燃烧数量\n        uint256 burnAmount = (poolBalance * burnRate) / BASE;\n        if (burnAmount == 0) return (0, poolBalance);\n        \n        // 计算静态奖励（30%）\n        staticReward = (burnAmount * 30000) / BASE;\n        \n        // 返回销毁后的新余额\n        newPoolBalance = poolBalance - burnAmount;\n        \n        return (staticReward, newPoolBalance);\n    }\n    /**\n     * @notice 模拟一天的销毁（累积所有小时），并返回新的余额\n     * @dev 测试环境下1小时=1天，生产环境需要累积24小时\n     * @param poolBalance 当前模拟的池子余额\n     * @return dailyDynamicReward 该天的累积动态奖励\n     * @return newPoolBalance 所有销毁后的新余额\n     */\n    function _simulateDailyBurnWithBalance(\n        uint256 day,\n        uint256 poolBalance\n    ) public view returns (uint256 dailyDynamicReward, uint256 newPoolBalance) {\n        // 测试环境：1小时 = 1天\n        // 生产环境：需要累积24小时的销毁\n        uint256 hoursPerDay = 24; // 生产环境：一天周期\n        \n        dailyDynamicReward = 0;\n        newPoolBalance = poolBalance;\n        \n        for (uint256 i = 0; i < hoursPerDay; i++) {\n            if (newPoolBalance == 0) break;\n            \n            uint256 burnRate = _calculateBurnRateForPoolWithDiscount(\n                day,\n                newPoolBalance,\n                _priceDiscountBpsForHour(day * 24 + i)\n            );\n            uint256 burnAmount = (newPoolBalance * burnRate) / BASE;\n            if (burnAmount == 0) break;\n            \n            // 累积动态奖励（15%）\n            dailyDynamicReward += (burnAmount * 15000) / BASE;\n            \n            // 更新余额（防止溢出）\n            if (newPoolBalance >= burnAmount) {\n                newPoolBalance -= burnAmount;\n            } else {\n                newPoolBalance = 0;\n            }\n        }\n        \n        return (dailyDynamicReward, newPoolBalance);\n    }\n    \n    /**\n     * @notice 将查询T1Y对WBNB的价格\n     */\n\n    function _getT1YAmountOutOfUSDT(uint256 amountIn) public view returns(uint256){\n        uint wbnbAmount = _getAmountOut(T1Y_TOKEN,WBNB,amountIn);\n        return _getAmountOut(WBNB,USDT,wbnbAmount);\n    }\n    function _getUSDTAmountOustOfT1Y(uint256 amountIn) public view returns(uint256){\n        uint wbnbAmount = _getAmountOut(USDT,WBNB,amountIn);\n        return _getAmountOut(WBNB,T1Y_TOKEN,wbnbAmount);\n    }\n    function _getAmountOut(address token0,address token1,uint256 amountIn) internal view returns(uint256){\n        address[] memory path = new address[](2);\n        path[0] = token0;\n        path[1] = token1;\n        uint256[] memory amounts = IPancakeRouter(ROUTER).getAmountsOut(amountIn, path);\n        return amounts[1];\n    }\n}\n// ============ 接口定义 ============\n\ninterface IPancakeRouter {\n    function factory() external pure returns (address);\n    function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts);\n    function addLiquidity(\n        address tokenA,\n        address tokenB,\n        uint256 amountADesired,\n        uint256 amountBDesired,\n        uint256 amountAMin,\n        uint256 amountBMin,\n        address to,\n        uint256 deadline\n    ) external returns (uint256 amountA, uint256 amountB, uint256 liquidity);\n    function removeLiquidity(\n        address tokenA,\n        address tokenB,\n        uint256 liquidity,\n        uint256 amountAMin,\n        uint256 amountBMin,\n        address to,\n        uint256 deadline\n    ) external returns (uint256 amountA, uint256 amountB);\n    function swapExactTokensForTokens(\n        uint256 amountIn,\n        uint256 amountOutMin,\n        address[] calldata path,\n        address to,\n        uint256 deadline\n    ) external returns (uint256[] memory amounts);\n    function swapExactETHForTokens(\n        uint256 amountOutMin,\n        address[] calldata path,\n        address to,\n        uint256 deadline\n    ) external payable returns (uint256[] memory amounts);\n}\n"
    },
    "contracts/test/MockPancake.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.24;\n\ninterface IMockERC20 {\n    function balanceOf(address account) external view returns (uint256);\n    function totalSupply() external view returns (uint256);\n    function transfer(address to, uint256 amount) external returns (bool);\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n\ncontract MockERC20 {\n    string public name;\n    string public symbol;\n    uint8 public decimals = 18;\n    uint256 public totalSupply;\n\n    mapping(address => uint256) public balanceOf;\n    mapping(address => mapping(address => uint256)) public allowance;\n\n    constructor(string memory name_, string memory symbol_) {\n        name = name_;\n        symbol = symbol_;\n    }\n\n    function transfer(address to, uint256 amount) external returns (bool) {\n        balanceOf[msg.sender] -= amount;\n        balanceOf[to] += amount;\n        return true;\n    }\n\n    function approve(address spender, uint256 amount) external returns (bool) {\n        allowance[msg.sender][spender] = amount;\n        return true;\n    }\n\n    function transferFrom(address from, address to, uint256 amount) external returns (bool) {\n        uint256 allowed = allowance[from][msg.sender];\n        if (allowed != type(uint256).max) {\n            allowance[from][msg.sender] = allowed - amount;\n        }\n        balanceOf[from] -= amount;\n        balanceOf[to] += amount;\n        return true;\n    }\n\n    function _mint(address to, uint256 amount) internal {\n        totalSupply += amount;\n        balanceOf[to] += amount;\n    }\n}\n\ncontract MockFalseTransferERC20 {\n    function transfer(address, uint256) external pure returns (bool) {\n        return false;\n    }\n}\n\ncontract MockWBNB is MockERC20(\"Wrapped BNB\", \"WBNB\") {\n    function deposit() external payable {\n        _mint(msg.sender, msg.value);\n    }\n\n    function withdraw(uint256 amount) external {\n        balanceOf[msg.sender] -= amount;\n        totalSupply -= amount;\n        payable(msg.sender).transfer(amount);\n    }\n}\n\ncontract MockPancakePair is MockERC20(\"Mock LP\", \"MLP\") {\n    function sendToken(address token, address to, uint256 amount) external {\n        IMockERC20(token).transfer(to, amount);\n    }\n\n    function mint(address to, uint256 amount) external {\n        _mint(to, amount);\n    }\n\n    function burn(address from, uint256 amount) external {\n        balanceOf[from] -= amount;\n        totalSupply -= amount;\n    }\n\n    function sync() external {}\n\n    function token0() external pure returns (address) {\n        return 0x9999999999999999999999999999999999999999;\n    }\n\n    function token1() external pure returns (address) {\n        return 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;\n    }\n}\n\ncontract MockPancakeRouter {\n    address private constant PAIR = 0x8888888888888888888888888888888888888888;\n\n    function factory() external pure returns (address) {\n        return 0x7777777777777777777777777777777777777777;\n    }\n\n    function getAmountsOut(uint256 amountIn, address[] calldata path) external pure returns (uint256[] memory amounts) {\n        amounts = new uint256[](path.length);\n        for (uint256 i = 0; i < path.length; i++) {\n            amounts[i] = amountIn;\n        }\n    }\n\n    function swapExactTokensForTokens(\n        uint256 amountIn,\n        uint256 amountOutMin,\n        address[] calldata path,\n        address to,\n        uint256\n    ) external returns (uint256[] memory amounts) {\n        require(amountIn >= amountOutMin, \"mock slippage\");\n        amounts = new uint256[](path.length);\n        for (uint256 i = 0; i < path.length; i++) {\n            amounts[i] = amountIn;\n        }\n\n        IMockERC20(path[0]).transferFrom(msg.sender, PAIR, amountIn);\n        MockPancakePair(PAIR).sendToken(path[path.length - 1], to, amountIn);\n    }\n\n    function addLiquidity(\n        address tokenA,\n        address tokenB,\n        uint256 amountADesired,\n        uint256 amountBDesired,\n        uint256 amountAMin,\n        uint256 amountBMin,\n        address to,\n        uint256\n    ) external returns (uint256 amountA, uint256 amountB, uint256 liquidity) {\n        require(amountADesired >= amountAMin, \"mock amountA\");\n        require(amountBDesired >= amountBMin, \"mock amountB\");\n        amountA = amountADesired;\n        amountB = amountBDesired;\n        liquidity = amountADesired < amountBDesired ? amountADesired : amountBDesired;\n\n        IMockERC20(tokenA).transferFrom(msg.sender, PAIR, amountA);\n        IMockERC20(tokenB).transferFrom(msg.sender, PAIR, amountB);\n        MockPancakePair(PAIR).mint(to, liquidity);\n    }\n\n    function removeLiquidity(\n        address tokenA,\n        address tokenB,\n        uint256 liquidity,\n        uint256 amountAMin,\n        uint256 amountBMin,\n        address to,\n        uint256\n    ) external returns (uint256 amountA, uint256 amountB) {\n        uint256 totalLiquidity = IMockERC20(PAIR).totalSupply();\n        amountA = (IMockERC20(tokenA).balanceOf(PAIR) * liquidity) / totalLiquidity;\n        amountB = (IMockERC20(tokenB).balanceOf(PAIR) * liquidity) / totalLiquidity;\n        require(amountA >= amountAMin, \"mock amountA\");\n        require(amountB >= amountBMin, \"mock amountB\");\n\n        IMockERC20(PAIR).transferFrom(msg.sender, PAIR, liquidity);\n        MockPancakePair(PAIR).burn(PAIR, liquidity);\n        MockPancakePair(PAIR).sendToken(tokenA, to, amountA);\n        MockPancakePair(PAIR).sendToken(tokenB, to, amountB);\n    }\n}\n\ncontract MockPancakeFactory {\n    function createPair(address, address) external pure returns (address) {\n        return 0x8888888888888888888888888888888888888888;\n    }\n}\n"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": true,
      "runs": 200
    },
    "evmVersion": "paris",
    "outputSelection": {
      "*": {
        "*": [
          "abi",
          "evm.bytecode",
          "evm.deployedBytecode",
          "evm.methodIdentifiers",
          "metadata"
        ],
        "": [
          "ast"
        ]
      }
    }
  }
}