Skip to main content
PulseScanner.io

Address

0x364d45abbbd4fbb015fb32d18a2c3d20b5a7bb70
Current Holdings
$0.00
TXs sent
not counted
First Active
2026-01-06
block 25,457,439
Last Active
256 days ago
block 25,457,672
Funded By
not identified

Net worth historyi

2 snapshots · to block 27,488,952coverage change 26 Augcoverage change 27 Augcoverage change 27 Augcoverage change 27 Augcoverage change 27 Aug
exact matchREMIXsolc 0.8.33+commit.64118f21runtime exact · creation exact
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

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

/**
 * @title SwapHelper - Intermediary for swaps to avoid INVALID_TO error
 */
contract SwapHelper {
    address public immutable parent;
    
    constructor() {
        parent = msg.sender;
    }
    
    function forward(address token, address to) external {
        require(msg.sender == parent, "Only parent");
        uint256 balance = IERC20(token).balanceOf(address(this));
        if (balance > 0) {
            require(IERC20(token).transfer(to, balance), "Forward failed");
        }
    }
}

/**
 * @title REMIX - Autonomous Bot Funding
 */

interface IERC20Extended {
    function balanceOf(address) external view returns (uint256);
    function transfer(address, uint256) external returns (bool);
    function approve(address, uint256) external returns (bool);
    function transferFrom(address, address, uint256) external returns (bool);
}

interface IDexRouter {
    function factory() external view returns (address);
    function addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB, uint liquidity);
    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;
    function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB);
}

interface IDexFactory {
    function getPair(address, address) external view returns (address);
    function createPair(address, address) external returns (address);
}

interface IDexPair {
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function totalSupply() external view returns (uint256);
    function sync() external;
}

contract REMIX is ERC20, Ownable, ReentrancyGuard {

    // ========== CONSTANTS ==========
    IDexRouter public immutable router;
    SwapHelper public immutable swapHelper;
    address public constant HEX = 0x2b591e99afE9f32eAA6214f7B7629768c40Eeb39;
    address public constant AER = 0x92337f43FB462163869342E72538744E030EAF55;
    
    address public immutable pairRMXHEX;
    address public immutable pairRMXAER;
    
    uint256 private constant MIN_LIQUIDITY = 1000000;
    uint256 private constant MAX_SLIPPAGE = 2000;
    uint256 private constant POOL_DEPLETION_LIMIT = 9000;
    uint256 private constant FAILED_CALL_REDUCTION = 80;
    uint256 private constant SAME_BLOCK_REDUCTION = 90;
    uint256 private constant JACKPOT_IMMEDIATE = 50;
    uint256 private constant BURN_IMMEDIATE = 1000;
    uint256 private constant POOL_CONTRIBUTION = 100;

    // ========== CONFIG ==========
    address public bot1 = 0x5839F1728ccd1cA6013F1858C4400b58B0173eb9;
    address public bot2 = 0x26a5ca8735e04df70a3F4219fA091E730c51a7ED;
    
    uint256 public bot1HEX = 200000000000;
    uint256 public bot1AER = 40000000000;
    uint256 public bot2HEX = 200000000000;
    uint256 public bot2AER = 40000000000;
    uint256 public targetSupply = 150000000000000000;
    
    uint8 public burnPercentage = 5;
    uint8 public maxLPBurnPercentage = 5;
    uint16 public mintBuffer = 200;
    
    bool public paused;
    bool public mintingPaused;
    bool public burningPaused;
    bool public rewardsPaused;
    
    uint256 public minHexReserve = 50000000000;
    uint256 public minAerReserve = 10000000000;
    uint256 public rewardPool;
    uint256 public minMaintenanceReward = 500000000;
    uint256 public poolRefillThreshold = 5000000000;
    uint256 public poolRefillAmount = 10000000000;
    bool public autoRefillEnabled = true;
    
    mapping(address => uint256) public lastCallTime;
    uint32 public callerCooldown = 5 minutes;
    uint256 public lastWorkBlock;
    uint256 public cooldownChangeTime;
    uint32 public oldCooldownValue;
    
    mapping(address => bool) public hasEverCalled;
    mapping(address => uint256) public callCount;
    mapping(address => uint256) public totalEarnedByAddress;
    
    uint256 public totalMinted;
    uint256 public totalBurned;
    uint256 public totalHexSent;
    uint256 public totalAerSent;
    uint256 public totalRewardsPaid;
    uint256 public totalPoolRefills;
    
    // ========== EVENTS ==========
    event BotRefilled(address indexed bot, uint256 hexAmount, uint256 aerAmount);
    event LPBurned(uint256 amount);
    event CallerRewarded(address indexed caller, uint256 reward, string rewardType);
    event LiquidityAdded(address indexed pair, uint256 amountRMX, uint256 amountToken, uint256 liquidity);
    event EmergencyLPWithdraw(address indexed pair, uint256 amount);
    event ConfigUpdated(string param, uint256 value);
    event PoolAutoRefilled(uint256 amount);
    event PauseToggled(string pauseType, bool state);

    // ========== CONSTRUCTOR ==========
    constructor() ERC20("Remix", "RMX") Ownable(msg.sender) {
        router = IDexRouter(0x165C3410fC91EF562C50559f7d2289fEbed552d9);
        swapHelper = new SwapHelper();
        
        IDexFactory factory = IDexFactory(router.factory());
        
        pairRMXHEX = _getOrCreatePair(factory, address(this), HEX);
        pairRMXAER = _getOrCreatePair(factory, address(this), AER);
        
        _mint(msg.sender, 200000000000000000);
    }
    
    function _getOrCreatePair(IDexFactory factory, address tokenA, address tokenB) private returns (address pair) {
        pair = factory.getPair(tokenA, tokenB);
        if (pair == address(0)) {
            pair = factory.createPair(tokenA, tokenB);
        }
    }

    function decimals() public pure override returns (uint8) {
        return 8;
    }

    // ========== ADD LIQUIDITY ==========
    
    function addInitialLiquidity(
        uint256 hexAmount,
        uint256 aerAmount,
        uint256 rmxForHexPool,
        uint256 rmxForAerPool
    ) external onlyOwner {
        require(hexAmount > 0 && rmxForHexPool > 0, "Invalid HEX");
        require(aerAmount > 0 && rmxForAerPool > 0, "Invalid AER");
        require(rmxForHexPool >= MIN_LIQUIDITY && rmxForAerPool >= MIN_LIQUIDITY, "Below min");
        
        _transfer(msg.sender, address(this), rmxForHexPool + rmxForAerPool);
        
        _addLiquidity(HEX, hexAmount, rmxForHexPool, pairRMXHEX);
        _addLiquidity(AER, aerAmount, rmxForAerPool, pairRMXAER);
    }
    
    function _addLiquidity(address token, uint256 tokenAmount, uint256 rmxAmount, address pair) private {
        require(IERC20Extended(token).transferFrom(msg.sender, address(this), tokenAmount), "Transfer fail");
        
        _approve(address(this), address(router), rmxAmount);
        IERC20Extended(token).approve(address(router), tokenAmount);
        
        (uint256 amountA, uint256 amountB, uint256 liquidity) = router.addLiquidity(
            address(this), token, rmxAmount, tokenAmount, 0, 0, address(this), block.timestamp + 300
        );
        
        require(liquidity > 0, "No liquidity");
        emit LiquidityAdded(pair, amountA, amountB, liquidity);
    }

    // ========== REGULATION ==========
    
    function regulate() external nonReentrant {
        require(!paused, "Paused");
        require(gasleft() >= 500000, "Low gas");
        
        if (lastWorkBlock == block.number) {
            lastCallTime[msg.sender] = block.timestamp - (uint256(callerCooldown) * SAME_BLOCK_REDUCTION / 100);
            return;
        }
        
        bool isFirstCall = lastCallTime[msg.sender] == 0 && !hasEverCalled[msg.sender];
        
        if (msg.sender != owner() && !isFirstCall) {
            uint256 effectiveCooldown = _getEffectiveCooldown(msg.sender);
            require(block.timestamp >= lastCallTime[msg.sender] + effectiveCooldown, "Cooldown");
        }
        
        uint256 mintedBefore = totalMinted;
        uint256 burnedBefore = totalBurned;
        bool workDone = false;
        bool needsRefill = false;
        
        if (bot1 != address(0) && !mintingPaused) {
            (bool hexLow, bool aerLow) = _checkBot(bot1, bot1HEX, bot1AER);
            if (hexLow || aerLow) {
                needsRefill = true;
                workDone = true;
                _refillBot(bot1, bot1HEX, bot1AER, hexLow, aerLow);
            }
        }
        
        if (bot2 != address(0) && !mintingPaused) {
            (bool hexLow, bool aerLow) = _checkBot(bot2, bot2HEX, bot2AER);
            if (hexLow || aerLow) {
                needsRefill = true;
                workDone = true;
                _refillBot(bot2, bot2HEX, bot2AER, hexLow, aerLow);
            }
        }
        
        if (!needsRefill && !burningPaused && totalSupply() > targetSupply) {
            uint256 burned = _burnLP();
            if (burned > 0) workDone = true;
        }
        
        if (autoRefillEnabled && rewardPool < poolRefillThreshold && !mintingPaused) {
            _refillRewardPool();
        }
        
        if (workDone) {
            hasEverCalled[msg.sender] = true;
            lastWorkBlock = block.number;
            lastCallTime[msg.sender] = block.timestamp;
            callCount[msg.sender]++;
            
            if (!rewardsPaused) {
                _rewardCaller(msg.sender, mintedBefore, burnedBefore);
            }
        } else {
            if (!isFirstCall) {
                lastCallTime[msg.sender] = block.timestamp - (uint256(callerCooldown) * FAILED_CALL_REDUCTION / 100);
            }
        }
    }
    
    function _refillRewardPool() private {
        _mint(address(this), poolRefillAmount);
        rewardPool += poolRefillAmount;
        totalMinted += poolRefillAmount;
        totalPoolRefills++;
        emit PoolAutoRefilled(poolRefillAmount);
    }
    
    function _getEffectiveCooldown(address caller) private view returns (uint256) {
        uint256 lastCall = lastCallTime[caller];
        if (cooldownChangeTime > 0 && lastCall > 0 && lastCall < cooldownChangeTime) {
            return uint256(oldCooldownValue);
        }
        return uint256(callerCooldown);
    }
    
    function _rewardCaller(address caller, uint256 mintedBefore, uint256 burnedBefore) private {
        uint256 mintedAmount = totalMinted - mintedBefore;
        uint256 burnedAmount = totalBurned - burnedBefore;
        
        uint256 rewardToPay = 0;
        string memory rewardType = "";
        
        if (mintedAmount > 0) {
            uint256 poolContribution = mintedAmount / POOL_CONTRIBUTION;
            rewardPool += poolContribution;
            rewardToPay = mintedAmount / JACKPOT_IMMEDIATE;
            
            if (rewardPool >= poolContribution * 2) {
                uint256 bonus = poolContribution / 2;
                rewardToPay += bonus;
                rewardPool -= bonus;
            }
            rewardType = "jackpot";
        } else if (burnedAmount > 0) {
            uint256 poolContribution = burnedAmount / POOL_CONTRIBUTION;
            rewardPool += poolContribution;
            rewardToPay = (burnedAmount * 15) / BURN_IMMEDIATE;
            rewardType = "burn";
        } else {
            if (rewardPool >= 10000000000) {
                rewardToPay = 2000000000;
            } else if (rewardPool >= 5000000000) {
                rewardToPay = 1000000000;
            } else if (rewardPool >= minMaintenanceReward) {
                rewardToPay = minMaintenanceReward;
            }
            
            if (rewardToPay > rewardPool) rewardToPay = rewardPool;
            if (rewardToPay > 0) rewardPool -= rewardToPay;
            rewardType = "maintenance";
        }
        
        if (rewardToPay > 0) {
            totalEarnedByAddress[caller] += rewardToPay;
            _mint(caller, rewardToPay);
            totalRewardsPaid += rewardToPay;
            emit CallerRewarded(caller, rewardToPay, rewardType);
        }
    }
    
    // ========== BOT MANAGEMENT ==========
    
    function _checkBot(address bot, uint256 optimalHex, uint256 optimalAer) private view returns (bool needsHex, bool needsAer) {
        uint256 botHex = IERC20Extended(HEX).balanceOf(bot);
        uint256 botAer = IERC20Extended(AER).balanceOf(bot);
        needsHex = optimalHex > 0 && botHex < optimalHex;
        needsAer = optimalAer > 0 && botAer < optimalAer;
    }
    
    function _refillBot(address bot, uint256 optimalHex, uint256 optimalAer, bool needsHex, bool needsAer) private {
        uint256 hexSent = 0;
        uint256 aerSent = 0;
        
        if (needsHex) {
            uint256 botHex = IERC20Extended(HEX).balanceOf(bot);
            if (botHex < optimalHex) {
                uint256 needed = optimalHex - botHex;
                hexSent = _getTokenAndSend(HEX, needed, bot);
                totalHexSent += hexSent;
            }
        }
        
        if (needsAer) {
            uint256 botAer = IERC20Extended(AER).balanceOf(bot);
            if (botAer < optimalAer) {
                uint256 needed = optimalAer - botAer;
                aerSent = _getTokenAndSend(AER, needed, bot);
                totalAerSent += aerSent;
            }
        }
        
        emit BotRefilled(bot, hexSent, aerSent);
    }
    
    function _getTokenAndSend(address token, uint256 amount, address recipient) private returns (uint256 sent) {
        require(amount > 0, "Zero amount");
        
        uint256 balance = IERC20Extended(token).balanceOf(address(this));
        uint256 minReserve = token == HEX ? minHexReserve : minAerReserve;
        uint256 available = balance > minReserve ? balance - minReserve : 0;
        
        if (available < amount) {
            uint256 needed = amount - available;
            uint256 rmxNeeded = _calculateRMXNeeded(token, needed);
            
            if (rmxNeeded == 0) {
                if (available > 0) {
                    require(IERC20Extended(token).transfer(recipient, available), "Transfer fail");
                    return available;
                }
                return 0;
            }
            
            uint256 toMint = (rmxNeeded * uint256(mintBuffer)) / 100;
            _mint(address(this), toMint);
            totalMinted += toMint;
            
            uint256 swapped = _swap(token, toMint);
            available += swapped;
        }
        
        sent = available >= amount ? amount : available;
        if (sent > 0) {
            require(IERC20Extended(token).transfer(recipient, sent), "Transfer fail");
        }
        return sent;
    }
    
    function _calculateRMXNeeded(address token, uint256 tokenAmount) private view returns (uint256) {
        if (tokenAmount == 0) return 0;
        
        address pair = token == HEX ? pairRMXHEX : pairRMXAER;
        (uint112 r0, uint112 r1,) = IDexPair(pair).getReserves();
        address token0 = IDexPair(pair).token0();
        
        uint256 rmxReserve = token0 == address(this) ? uint256(r0) : uint256(r1);
        uint256 tokenReserve = token0 == address(this) ? uint256(r1) : uint256(r0);
        
        if (rmxReserve == 0 || tokenReserve == 0) return 0;
        
        uint256 maxPurchase = (tokenReserve * POOL_DEPLETION_LIMIT) / 10000;
        if (tokenAmount >= maxPurchase) tokenAmount = maxPurchase;
        if (tokenAmount >= tokenReserve) return 0;
        
        uint256 numerator = rmxReserve * tokenAmount;
        if (numerator / rmxReserve != tokenAmount) return 0;
        numerator = numerator * 1000;
        
        uint256 denominator = (tokenReserve - tokenAmount) * 997;
        if (denominator == 0) return 0;
        
        uint256 rmxNeeded = numerator / denominator;
        rmxNeeded = (rmxNeeded * 102) / 100;
        if (rmxNeeded > rmxReserve * 10) return 0;
        
        return rmxNeeded;
    }
    
    function _swap(address tokenOut, uint256 rmxIn) private returns (uint256 received) {
        if (rmxIn == 0) return 0;
        
        _approve(address(this), address(router), rmxIn);
        
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = tokenOut;
        
        uint256 expected = 0;
        try router.getAmountsOut(rmxIn, path) returns (uint[] memory amounts) {
            expected = amounts.length >= 2 ? amounts[1] : 0;
        } catch {
            return 0;
        }
        
        if (expected == 0) return 0;
        
        uint256 slippage = 1000;
        if (slippage > MAX_SLIPPAGE) slippage = MAX_SLIPPAGE;
        uint256 minOut = (expected * (10000 - slippage)) / 10000;
        
        uint256 balanceBefore = IERC20Extended(tokenOut).balanceOf(address(this));
        
        try router.swapExactTokensForTokensSupportingFeeOnTransferTokens(
            rmxIn, minOut, path, address(swapHelper), block.timestamp + 300
        ) {
            swapHelper.forward(tokenOut, address(this));
        } catch {
            return 0;
        }
        
        uint256 balanceAfter = IERC20Extended(tokenOut).balanceOf(address(this));
        received = balanceAfter > balanceBefore ? balanceAfter - balanceBefore : 0;
        return received;
    }
    
    // ========== LP BURNING ==========
    
    function _burnLP() private returns (uint256 totalBurnedNow) {
        if (totalSupply() <= targetSupply) return 0;
        
        uint256 excess = totalSupply() - targetSupply;
        uint256 toBurn = (excess * uint256(burnPercentage)) / 100;
        
        if (toBurn > excess) toBurn = excess;
        if (toBurn == 0) return 0;
        
        uint256 burned1 = _burnFromPool(pairRMXHEX, HEX, toBurn / 2);
        uint256 burned2 = _burnFromPool(pairRMXAER, AER, toBurn / 2);
        
        totalBurnedNow = burned1 + burned2;
        
        if (totalBurnedNow > 0) {
            totalBurned += totalBurnedNow;
            emit LPBurned(totalBurnedNow);
        }
        
        return totalBurnedNow;
    }
    
    function _burnFromPool(address pair, address token, uint256 targetBurn) private returns (uint256 burned) {
        if (targetBurn == 0) return 0;
        
        uint256 lpToRemove;
        {
            (uint112 r0, uint112 r1,) = IDexPair(pair).getReserves();
            if (r0 == 0 || r1 == 0) return 0;
            
            address token0 = IDexPair(pair).token0();
            uint256 rmxReserve = token0 == address(this) ? uint256(r0) : uint256(r1);
            uint256 totalLP = IDexPair(pair).totalSupply();
            uint256 ourLP = IERC20Extended(pair).balanceOf(address(this));
            
            if (ourLP == 0 || totalLP == 0 || rmxReserve == 0) return 0;
            
            lpToRemove = (targetBurn * totalLP) / rmxReserve;
            if (lpToRemove > ourLP) lpToRemove = ourLP;
            
            uint256 maxLP = (totalLP * uint256(maxLPBurnPercentage)) / 100;
            if (lpToRemove > maxLP) lpToRemove = maxLP;
            if (lpToRemove < 100) return 0;
        }
        
        IERC20Extended(pair).approve(address(router), lpToRemove);
        
        uint256 rmxBefore = balanceOf(address(this));
        uint256 tokenBefore = IERC20Extended(token).balanceOf(address(this));
        
        try router.removeLiquidity(address(this), token, lpToRemove, 0, 0, address(this), block.timestamp + 300) 
        returns (uint256, uint256) {} catch {
            return 0;
        }
        
        uint256 rmxGot = balanceOf(address(this));
        rmxGot = rmxGot > rmxBefore ? rmxGot - rmxBefore : 0;
        
        uint256 tokenGot = IERC20Extended(token).balanceOf(address(this));
        tokenGot = tokenGot > tokenBefore ? tokenGot - tokenBefore : 0;
        
        if (rmxGot > 0) {
            _burn(address(this), rmxGot);
            burned = rmxGot;
        }
        
        if (tokenGot > 0) {
            IERC20Extended(token).transfer(pair, tokenGot);
            IDexPair(pair).sync();
        }
        
        return burned;
    }

    // ========== ADMIN ==========
    
    function setBots(address _bot1, address _bot2) external onlyOwner {
        require(_bot1 != address(this) && _bot2 != address(this), "Invalid bot");
        bot1 = _bot1;
        bot2 = _bot2;
    }
    
    function setBot1Levels(uint256 hexAmount, uint256 aerAmount) external onlyOwner {
        require(hexAmount <= 10000000000000 && aerAmount <= 10000000000000, "Too high");
        bot1HEX = hexAmount;
        bot1AER = aerAmount;
    }
    
    function setBot2Levels(uint256 hexAmount, uint256 aerAmount) external onlyOwner {
        require(hexAmount <= 10000000000000 && aerAmount <= 10000000000000, "Too high");
        bot2HEX = hexAmount;
        bot2AER = aerAmount;
    }
    
    function setTargetSupply(uint256 target) external onlyOwner {
        require(target > 0, "Invalid");
        targetSupply = target;
    }
    
    function setBurnPercentage(uint8 percentage) external onlyOwner {
        require(percentage > 0 && percentage <= 100, "Invalid");
        burnPercentage = percentage;
        emit ConfigUpdated("burnPercentage", percentage);
    }
    
    function setMaxLPBurnPercentage(uint8 percentage) external onlyOwner {
        require(percentage > 0 && percentage <= 100, "Invalid");
        maxLPBurnPercentage = percentage;
        emit ConfigUpdated("maxLPBurnPercentage", percentage);
    }
    
    function setMintBuffer(uint16 bufferPercent) external onlyOwner {
        require(bufferPercent >= 100 && bufferPercent <= 500, "Invalid");
        mintBuffer = bufferPercent;
        emit ConfigUpdated("mintBuffer", bufferPercent);
    }
    
    function setMinReserves(uint256 hexReserve, uint256 aerReserve) external onlyOwner {
        require(hexReserve <= 10000000000000 && aerReserve <= 10000000000000, "Too high");
        minHexReserve = hexReserve;
        minAerReserve = aerReserve;
        emit ConfigUpdated("minReserves", hexReserve);
    }
    
    function setMinMaintenanceReward(uint256 amount) external onlyOwner {
        require(amount > 0 && amount <= 10000000000, "Invalid");
        minMaintenanceReward = amount;
        emit ConfigUpdated("minMaintenanceReward", amount);
    }
    
    function setCallerCooldown(uint32 cooldownSeconds) external onlyOwner {
        require(cooldownSeconds >= 60 && cooldownSeconds <= 1 days, "Invalid");
        
        uint32 oldCooldown = callerCooldown;
        if (cooldownSeconds > oldCooldown) {
            cooldownChangeTime = block.timestamp;
            oldCooldownValue = oldCooldown;
        }
        
        callerCooldown = cooldownSeconds;
        emit ConfigUpdated("callerCooldown", cooldownSeconds);
    }
    
    function setAutoRefillConfig(uint256 threshold, uint256 amount, bool enabled) external onlyOwner {
        require(threshold <= 100000000000 && amount <= 1000000000000, "Invalid");
        poolRefillThreshold = threshold;
        poolRefillAmount = amount;
        autoRefillEnabled = enabled;
        emit ConfigUpdated("autoRefill", enabled ? 1 : 0);
    }
    
    function manualRefillRewardPool(uint256 amount) external onlyOwner {
        require(amount > 0 && amount <= 10000000000000, "Invalid");
        _mint(address(this), amount);
        rewardPool += amount;
        totalMinted += amount;
        totalPoolRefills++;
        emit PoolAutoRefilled(amount);
    }
    
    function pause() external onlyOwner {
        paused = true;
        emit PauseToggled("main", true);
    }
    
    function unpause() external onlyOwner {
        paused = false;
        emit PauseToggled("main", false);
    }
    
    function toggleMintingPause() external onlyOwner {
        mintingPaused = !mintingPaused;
        emit PauseToggled("minting", mintingPaused);
    }
    
    function toggleBurningPause() external onlyOwner {
        burningPaused = !burningPaused;
        emit PauseToggled("burning", burningPaused);
    }
    
    function toggleRewardsPause() external onlyOwner {
        rewardsPaused = !rewardsPaused;
        emit PauseToggled("rewards", rewardsPaused);
    }
    
    function withdraw(address token, uint256 amount) external onlyOwner {
        require(paused && token != address(this), "Invalid");
        require(IERC20Extended(token).transfer(owner(), amount), "Fail");
    }

    function emergencyWithdrawLP(address pair, uint256 amount) external onlyOwner {
        require(paused && (pair == pairRMXHEX || pair == pairRMXAER), "Invalid");
        require(amount <= IERC20Extended(pair).balanceOf(address(this)), "Insufficient");
        require(IERC20Extended(pair).transfer(owner(), amount), "Fail");
        emit EmergencyLPWithdraw(pair, amount);
    }
    
    function emergencyWithdrawAllLP() external onlyOwner {
        require(paused, "Not paused");
        
        uint256 hexLP = IERC20Extended(pairRMXHEX).balanceOf(address(this));
        if (hexLP > 0) {
            require(IERC20Extended(pairRMXHEX).transfer(owner(), hexLP), "Fail");
            emit EmergencyLPWithdraw(pairRMXHEX, hexLP);
        }
        
        uint256 aerLP = IERC20Extended(pairRMXAER).balanceOf(address(this));
        if (aerLP > 0) {
            require(IERC20Extended(pairRMXAER).transfer(owner(), aerLP), "Fail");
            emit EmergencyLPWithdraw(pairRMXAER, aerLP);
        }
    }

    // ========== ESSENTIAL VIEWS ==========
    
    function getCooldownRemaining() external view returns (uint256) {
        uint256 effectiveCooldown = _getEffectiveCooldown(msg.sender);
        if (block.timestamp >= lastCallTime[msg.sender] + effectiveCooldown) return 0;
        return (lastCallTime[msg.sender] + effectiveCooldown) - block.timestamp;
    }
    
    function getCooldownRemainingFor(address caller) external view returns (uint256) {
        uint256 effectiveCooldown = _getEffectiveCooldown(caller);
        if (block.timestamp >= lastCallTime[caller] + effectiveCooldown) return 0;
        return (lastCallTime[caller] + effectiveCooldown) - block.timestamp;
    }
    
    function checkBots() external view returns (bool, bool, bool, bool) {
        bool bot1NeedsHex;
        bool bot1NeedsAer;
        bool bot2NeedsHex;
        bool bot2NeedsAer;
        
        if (bot1 != address(0)) {
            (bot1NeedsHex, bot1NeedsAer) = _checkBot(bot1, bot1HEX, bot1AER);
        }
        if (bot2 != address(0)) {
            (bot2NeedsHex, bot2NeedsAer) = _checkBot(bot2, bot2HEX, bot2AER);
        }
        
        return (bot1NeedsHex, bot1NeedsAer, bot2NeedsHex, bot2NeedsAer);
    }
    
    function getStats() external view returns (uint256, uint256, uint256, uint256, uint256, uint256) {
        return (totalMinted, totalBurned, totalHexSent, totalAerSent, totalSupply(), totalRewardsPaid);
    }
    
    function getPoolInfo() external view returns (uint256, uint256, uint256, bool, uint256) {
        return (rewardPool, poolRefillThreshold, poolRefillAmount, autoRefillEnabled, totalPoolRefills);
    }
    
    function getCallerStats(address caller) external view returns (uint256, uint256, uint256) {
        return (callCount[caller], totalEarnedByAddress[caller], this.getCooldownRemainingFor(caller));
    }
    
    receive() external payable {
        revert("No ETH");
    }
}