// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; interface IERC20Minimal { function balanceOf(address account) external view returns (uint256); function transfer(address to, uint256 amount) external returns (bool); } contract JinKuVault { address public constant TREASURY_WALLET = 0xbe285db4a775f8a8fa8e7a6071c3851fcea092e0; address public owner; bool private locked; string public constant VAULT_NAME = unicode"金库"; string public constant TAX_TITLE = unicode"金库机制"; string public constant TAX_DETAILS = unicode"税收进入金库合约后自动汇入金库钱包,用于收入矩阵、分配引擎、运行模式和公开面板展示。金库会记录资金流入、释放、储备与执行情况,让用户在税收详情中看到清晰的机制文案。"; event NativeReceived(address indexed from, uint256 amount); event NativeForwarded(address indexed to, uint256 amount); event NativeForwardFailed(address indexed to, uint256 amount); event TokenForwarded(address indexed token, address indexed to, uint256 amount); event EmergencyWithdrawNative(address indexed to, uint256 amount); event EmergencyWithdrawToken(address indexed token, address indexed to, uint256 amount); event OwnershipTransferred(address indexed oldOwner, address indexed newOwner); modifier onlyOwner() { require(msg.sender == owner, "NOT_OWNER"); _; } modifier nonReentrant() { require(!locked, "REENTRANT"); locked = true; _; locked = false; } constructor() { owner = msg.sender; emit OwnershipTransferred(address(0), msg.sender); } receive() external payable { emit NativeReceived(msg.sender, msg.value); _tryForwardNative(msg.value); } fallback() external payable { if (msg.value > 0) { emit NativeReceived(msg.sender, msg.value); _tryForwardNative(msg.value); } } function taxInfo() external pure returns ( string memory name_, string memory title_, string memory details_, address treasury_ ) { return (VAULT_NAME, TAX_TITLE, TAX_DETAILS, TREASURY_WALLET); } function flapTaxDetails() external pure returns (string memory) { return TAX_DETAILS; } function vaultWallet() external pure returns (address) { return TREASURY_WALLET; } function forwardNative() external nonReentrant { uint256 amount = address(this).balance; require(amount > 0, "NO_NATIVE_BALANCE"); _sendNative(TREASURY_WALLET, amount); emit NativeForwarded(TREASURY_WALLET, amount); } function forwardToken(address token) external nonReentrant { require(token != address(0), "ZERO_TOKEN"); uint256 amount = IERC20Minimal(token).balanceOf(address(this)); require(amount > 0, "NO_TOKEN_BALANCE"); _safeTransferToken(token, TREASURY_WALLET, amount); emit TokenForwarded(token, TREASURY_WALLET, amount); } function withdrawNative(uint256 amount) external onlyOwner nonReentrant { uint256 balance = address(this).balance; if (amount == 0) { amount = balance; } require(amount > 0, "NO_NATIVE_BALANCE"); require(amount <= balance, "INSUFFICIENT_NATIVE"); _sendNative(TREASURY_WALLET, amount); emit EmergencyWithdrawNative(TREASURY_WALLET, amount); } function withdrawToken(address token, uint256 amount) external onlyOwner nonReentrant { require(token != address(0), "ZERO_TOKEN"); uint256 balance = IERC20Minimal(token).balanceOf(address(this)); if (amount == 0) { amount = balance; } require(amount > 0, "NO_TOKEN_BALANCE"); require(amount <= balance, "INSUFFICIENT_TOKEN"); _safeTransferToken(token, TREASURY_WALLET, amount); emit EmergencyWithdrawToken(token, TREASURY_WALLET, amount); } function transferOwnership(address newOwner) external onlyOwner { require(newOwner != address(0), "ZERO_OWNER"); address oldOwner = owner; owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } function renounceOwnership() external onlyOwner { address oldOwner = owner; owner = address(0); emit OwnershipTransferred(oldOwner, address(0)); } function _tryForwardNative(uint256 amount) internal { if (amount == 0) { return; } (bool success, ) = payable(TREASURY_WALLET).call{value: amount}(""); if (success) { emit NativeForwarded(TREASURY_WALLET, amount); } else { emit NativeForwardFailed(TREASURY_WALLET, amount); } } function _sendNative(address to, uint256 amount) internal { (bool success, ) = payable(to).call{value: amount}(""); require(success, "NATIVE_TRANSFER_FAILED"); } function _safeTransferToken(address token, address to, uint256 amount) internal { (bool success, bytes memory data) = token.call( abi.encodeWithSelector(IERC20Minimal.transfer.selector, to, amount) ); require( success && (data.length == 0 || abi.decode(data, (bool))), "TOKEN_TRANSFER_FAILED" ); } }