Skip to main content
PulseScanner.io

Address

0x9e1237ab0fed052a30d7279a1b4d58d4f7b220d2
Current Holdings
$311.83
TXs sent
0
First Active
2026-04-18
block 26,312,640
Last Active
today
block 27,513,363
Funded By
0x25bc…3ab3

Net worth historyi

5,000 snapshots · to block 27,521,383coverage change 26 Augcoverage change 27 Augcoverage change 27 Augcoverage change 27 Augcoverage change 27 Augpartial
partial matchClankersolc 0.8.26+commit.8a97fa7aruntime partial · creation partial
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

interface IRouter {
    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountA, uint256 amountB, uint256 liquidity);
}

interface IERC20 {
    function balanceOf(address account) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function decimals() external view returns (uint8);
    function transfer(address to, uint256 amount) external returns (bool);
}

interface IPair {
    function getReserves() external view returns (uint112, uint112, uint32);
    function token0() external view returns (address);
    function token1() external view returns (address);
}

interface IClickerSlot {
    function click() external returns (uint8);
}

contract ClickerFixedLPRatio {
    address public constant ROUTER = 0x98bf93ebf5c380C0e6Ae8e192A7e2AE08edAcc02;
    address public constant WPLS   = 0xA1077a294dDE1B09bB078844df40758a5D0f9a27;

    address public constant TOKEN_A = 0x037645963Aece8C5Beb947dA5621362c9f7dB5a6;
    address public constant TOKEN_B = 0xC607606C0DC9B084D4e4458449963a975a762093;
    address public constant PAIR    = 0xc53f7DDf0D3429D6B602a060Ae6241617225b396;

    address public owner;
    bool public enabled = true;

    address public watchedAccount = 0xe64628a65aD7611a99ca994CCC498e4f515768eE;
    uint256 public plsThreshold = 1 ether;

    // WPLS per 1 TOKEN_A, scaled to 1e18.
    uint256 public targetRatio = 1 ether;

    // TOKEN_B per 1 TOKEN_A, scaled to 1e18.
    uint256 public constant FIXED_LP_RATIO = 1618154261642834;

    uint256 public boostFloorRatio = 1 ether;
    uint256 public minBoost = 1 ether;
    uint256 public maxBoost = 2 ether;

    uint256 public lpAddsPerSweep = 6;
    uint256 public lpAddCount;
    uint256 public lastSweepAt;

    uint256 public minTokenBForBuy = 1e6;
    uint256 public buyDivider = 99999;

    uint256 public minTokenAForLP = 1e6;
    uint256 public lpDivider = 10;

    uint256 private _unlocked = 1;

    IRouter private constant router = IRouter(ROUTER);
    IERC20 private constant tokenA = IERC20(TOKEN_A);
    IERC20 private constant tokenB = IERC20(TOKEN_B);
    IPair private constant ratioPair = IPair(PAIR);

    enum Step {
        SKIP_DISABLED,
        SKIP_THRESHOLD,
        WAIT,
        BUY,
        ADD_LP
    }

    Step public lastStep;

    uint8 private immutable TOKEN_A_DECIMALS;
    uint8 private immutable TOKEN_B_DECIMALS;

    event NativeFunded(address indexed sender, uint256 amount);
    event ClickGateChecked(
        address indexed caller,
        address indexed watchedAccount,
        uint256 watchedBalance,
        uint256 threshold,
        bool passed
    );
    event ClickAction(
        address indexed caller,
        string action,
        uint256 ratio,
        uint256 amountAUsed,
        uint256 amountBUsed,
        uint256 buyInputUsed
    );
    event SweepReady(uint256 lpCount, uint256 remainingA, uint256 remainingB, uint256 remainingPLS);
    event Note(string message, uint256 value);
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }

    modifier lock() {
        require(_unlocked == 1, "LOCKED");
        _unlocked = 0;
        _;
        _unlocked = 1;
    }

    constructor() {
        owner = msg.sender;
        emit OwnershipTransferred(address(0), msg.sender);

        uint8 a = 18;
        uint8 b = 18;

        try IERC20(TOKEN_A).decimals() returns (uint8 da) {
            a = da;
        } catch {}

        try IERC20(TOKEN_B).decimals() returns (uint8 db) {
            b = db;
        } catch {}

        TOKEN_A_DECIMALS = a;
        TOKEN_B_DECIMALS = b;
    }

    function fund() external payable lock {
        require(msg.value > 0, "No PLS sent");
        emit NativeFunded(msg.sender, msg.value);
    }

    function watchedPlsBalance() public view returns (uint256) {
        return watchedAccount.balance;
    }

    function gatePassed() public view returns (bool) {
        return enabled && watchedAccount.balance >= plsThreshold;
    }

    function click() public lock returns (uint8) {
        if (!enabled) {
            lastStep = Step.SKIP_DISABLED;
            emit ClickGateChecked(msg.sender, watchedAccount, watchedAccount.balance, plsThreshold, false);
            emit ClickAction(msg.sender, "DISABLED", 0, 0, 0, 0);
            return uint8(lastStep);
        }

        uint256 watchedBalance = watchedAccount.balance;
        bool thresholdPassed = watchedBalance >= plsThreshold;
        emit ClickGateChecked(msg.sender, watchedAccount, watchedBalance, plsThreshold, thresholdPassed);

        uint256 ratio = getRatio();
        if (ratio == 0) {
            lastStep = Step.WAIT;
            emit ClickAction(msg.sender, "NO_RATIO", 0, 0, 0, 0);
            return uint8(lastStep);
        }

        // If watched PLS is below threshold, always buy.
        if (!thresholdPassed) {
            uint256 boostBelowThreshold = _computeBoostMultiplier(ratio);
            if (_buy(ratio, boostBelowThreshold)) {
                lastStep = Step.BUY;
            } else {
                lastStep = Step.WAIT;
            }
            return uint8(lastStep);
        }

        // LP is only allowed when both conditions are true:
        // 1) watched PLS is at/above threshold
        // 2) ratio is above target
        if (ratio > targetRatio) {
            if (_addLiquidityFixedRatio(ratio)) {
                lastStep = Step.ADD_LP;
            } else {
                lastStep = Step.WAIT;
            }
            return uint8(lastStep);
        }

        lastStep = Step.WAIT;
        emit ClickAction(msg.sender, "WAIT", ratio, 0, 0, 0);
        return uint8(lastStep);
    }

    function getRatio() public view returns (uint256) {
        (uint112 r0, uint112 r1,) = ratioPair.getReserves();
        address t0 = ratioPair.token0();

        uint256 reserveTokenA;
        uint256 reserveWPLS;

        if (t0 == TOKEN_A) {
            reserveTokenA = uint256(r0);
            reserveWPLS = uint256(r1);
        } else {
            reserveTokenA = uint256(r1);
            reserveWPLS = uint256(r0);
        }

        if (reserveTokenA == 0) return 0;

        uint256 tokenA18 = _to18(reserveTokenA, TOKEN_A_DECIMALS);
        return (reserveWPLS * 1e18) / tokenA18;
    }

    function getFixedLPRatio() external pure returns (uint256) {
        return FIXED_LP_RATIO;
    }

    function _buy(uint256 ratio, uint256 boost) internal returns (bool) {
        uint256 balB = tokenB.balanceOf(address(this));
        if (balB <= minTokenBForBuy) {
            emit Note("Not enough TOKEN_B for buy", balB);
            return false;
        }

        uint256 base = balB / buyDivider;
        if (base == 0) {
            emit Note("Base buy is zero", balB);
            return false;
        }

        uint256 amountIn = (base * boost) / 1e18;
        if (amountIn > balB) amountIn = balB;

        if (amountIn == 0) {
            emit Note("Boosted buy is zero", 0);
            return false;
        }

        tokenB.approve(ROUTER, type(uint256).max);

        address[] memory path = new address[](3);
        path[0] = TOKEN_B;
        path[1] = WPLS;
        path[2] = TOKEN_A;

        router.swapExactTokensForTokensSupportingFeeOnTransferTokens(
            amountIn,
            0,
            path,
            address(this),
            block.timestamp + 900
        );

        emit ClickAction(msg.sender, "BUY", ratio, 0, 0, amountIn);
        return true;
    }

    function _addLiquidityFixedRatio(uint256 policyRatio) internal returns (bool) {
        uint256 balA = tokenA.balanceOf(address(this));
        uint256 balB = tokenB.balanceOf(address(this));

        if (balA <= minTokenAForLP || balB == 0) {
            emit Note("Insufficient balances for LP", balA);
            return false;
        }

        uint256 matchedA = _matchedTokenAForBalancesFixedRatio(FIXED_LP_RATIO, balA, balB);
        if (matchedA == 0) {
            emit Note("Matched TOKEN_A is zero", 0);
            return false;
        }

        uint256 amountA = matchedA / lpDivider;
        if (amountA == 0) amountA = matchedA;
        if (amountA > balA) amountA = balA;

        uint256 amountA18 = _to18(amountA, TOKEN_A_DECIMALS);
        uint256 amountB18 = (amountA18 * FIXED_LP_RATIO) / 1e18;
        uint256 amountB = _from18(amountB18, TOKEN_B_DECIMALS);

        if (amountB > balB) {
            amountB = balB;
            uint256 amountB18Adjusted = _to18(amountB, TOKEN_B_DECIMALS);
            uint256 amountA18Adjusted = (amountB18Adjusted * 1e18) / FIXED_LP_RATIO;
            amountA = _from18(amountA18Adjusted, TOKEN_A_DECIMALS);
        }

        if (amountA == 0 || amountB == 0) {
            emit Note("LP desired amount is zero", 0);
            return false;
        }

        tokenA.approve(ROUTER, type(uint256).max);
        tokenB.approve(ROUTER, type(uint256).max);

        router.addLiquidity(
            TOKEN_A,
            TOKEN_B,
            amountA,
            amountB,
            0,
            0,
            address(this),
            block.timestamp + 900
        );

        lpAddCount += 1;

        emit ClickAction(msg.sender, "ADD_LP", policyRatio, amountA, amountB, 0);

        if (lpAddsPerSweep > 0 && (lpAddCount % lpAddsPerSweep == 0)) {
            lastSweepAt = block.timestamp;
            emit SweepReady(
                lpAddCount,
                tokenA.balanceOf(address(this)),
                tokenB.balanceOf(address(this)),
                address(this).balance
            );
        }

        return true;
    }

    function _matchedTokenAForBalancesFixedRatio(
        uint256 fixedRatio,
        uint256 balA,
        uint256 balB
    ) internal view returns (uint256) {
        if (fixedRatio == 0 || balA == 0 || balB == 0) return 0;

        uint256 balB18 = _to18(balB, TOKEN_B_DECIMALS);
        uint256 maxA18FromB = (balB18 * 1e18) / fixedRatio;
        uint256 maxAFromB = _from18(maxA18FromB, TOKEN_A_DECIMALS);

        return balA < maxAFromB ? balA : maxAFromB;
    }

    function _computeBoostMultiplier(uint256 currentRatio) internal view returns (uint256) {
        if (currentRatio >= boostFloorRatio) return 1 ether;

        uint256 below = boostFloorRatio - currentRatio;
        uint256 frac = (below * 1e18) / boostFloorRatio;
        uint256 delta = maxBoost - minBoost;
        uint256 boost = minBoost + ((delta * frac) / 1e18);

        if (boost < minBoost) return minBoost;
        if (boost > maxBoost) return maxBoost;
        return boost;
    }

    function _pow10(uint8 n) internal pure returns (uint256) {
        return 10 ** uint256(n);
    }

    function _to18(uint256 amount, uint8 decimals_) internal pure returns (uint256) {
        if (decimals_ == 18) return amount;
        if (decimals_ < 18) return amount * _pow10(18 - decimals_);
        return amount / _pow10(decimals_ - 18);
    }

    function _from18(uint256 amount18, uint8 decimals_) internal pure returns (uint256) {
        if (decimals_ == 18) return amount18;
        if (decimals_ < 18) return amount18 / _pow10(18 - decimals_);
        return amount18 * _pow10(decimals_ - 18);
    }

    function transferOwnership(address newOwner) external onlyOwner {
        require(newOwner != address(0), "zero addr");
        emit OwnershipTransferred(owner, newOwner);
        owner = newOwner;
    }

    function setEnabled(bool newEnabled) external onlyOwner {
        enabled = newEnabled;
    }

    function setWatchedAccount(address newWatchedAccount) external onlyOwner {
        require(newWatchedAccount != address(0), "zero addr");
        watchedAccount = newWatchedAccount;
    }

    function setPlsThreshold(uint256 newThreshold) external onlyOwner {
        plsThreshold = newThreshold;
    }

    function setTargetRatio(uint256 newRatio) external onlyOwner {
        targetRatio = newRatio;
    }

    function setBoostRange(
        uint256 newFloorRatio,
        uint256 newMinBoost,
        uint256 newMaxBoost
    ) external onlyOwner {
        require(newFloorRatio > 0, "floor 0");
        require(newMinBoost <= newMaxBoost, "min > max");

        boostFloorRatio = newFloorRatio;
        minBoost = newMinBoost;
        maxBoost = newMaxBoost;
    }

    function setLpAddsPerSweep(uint256 newCount) external onlyOwner {
        lpAddsPerSweep = newCount;
    }

    function setBuyDivider(uint256 newDivider) external onlyOwner {
        require(newDivider > 0, "divider 0");
        buyDivider = newDivider;
    }

    function setMinTokenBForBuy(uint256 newMin) external onlyOwner {
        minTokenBForBuy = newMin;
    }

    function setMinTokenAForLP(uint256 newMin) external onlyOwner {
        minTokenAForLP = newMin;
    }

    function setLPDivider(uint256 newDivider) external onlyOwner {
        require(newDivider > 0, "divider 0");
        lpDivider = newDivider;
    }

    function recoverPLS(address payable to, uint256 amount) external onlyOwner {
        require(to != address(0), "zero addr");
        if (amount == 0) amount = address(this).balance;
        (bool ok,) = to.call{value: amount}("");
        require(ok, "transfer failed");
    }

    function recoverToken(address tokenAddr, address to, uint256 amount) external onlyOwner {
        require(to != address(0), "zero addr");
        IERC20 t = IERC20(tokenAddr);
        if (amount == 0) amount = t.balanceOf(address(this));
        require(t.transfer(to, amount), "token transfer failed");
    }

    receive() external payable {}
    fallback() external payable {}
}

contract Clanker {
    struct Slot {
        address clicker;
        bool active;
    }

    address public owner;
    Slot[] private _slots;

    mapping(address => uint256) public lastClankAt;

    uint256 public callerCooldown = 60;
    uint256 public rebateBps = 10100; // 100% estimated cost + 1% extra.
    uint256 public gasOverhead = 40000; // Buffer for tx/frame costs not fully visible to gasleft().
    bool public rebatesEnabled = true;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    event SlotSet(uint256 indexed slotId, address indexed clicker, bool active);
    event SlotCleared(uint256 indexed slotId);
    event SlotActiveChanged(uint256 indexed slotId, bool active);
    event SlotClicked(uint256 indexed slotId, address indexed clicker, uint8 code);
    event SlotClickFailed(uint256 indexed slotId, address indexed clicker, string reason);
    event SlotClickFailedLowLevel(uint256 indexed slotId, address indexed clicker, bytes data);
    event Clanked(address indexed caller, uint256 start, uint256 end, uint256 attempted, uint256 succeeded);
    event NativeFunded(address indexed sender, uint256 amount);
    event RebatePaid(
        address indexed caller,
        uint256 gasUsed,
        uint256 gasPrice,
        uint256 estimatedCost,
        uint256 rebatePaid
    );
    event RebateSkipped(address indexed caller, uint256 gasUsed, uint256 gasPrice, uint256 estimatedCost);

    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }

    constructor() {
        owner = msg.sender;
        emit OwnershipTransferred(address(0), msg.sender);
    }

    function transferOwnership(address newOwner) external onlyOwner {
        require(newOwner != address(0), "zero addr");
        emit OwnershipTransferred(owner, newOwner);
        owner = newOwner;
    }

    function fund() external payable {
        require(msg.value > 0, "No PLS sent");
        emit NativeFunded(msg.sender, msg.value);
    }

    function slotCount() external view returns (uint256) {
        return _slots.length;
    }

    function getSlot(uint256 slotId) external view returns (address clicker, bool active) {
        require(slotId < _slots.length, "slot oob");
        Slot memory s = _slots[slotId];
        return (s.clicker, s.active);
    }

    function setSlot(uint256 slotId, address clicker, bool active) external onlyOwner {
        require(clicker != address(0), "zero clicker");

        if (slotId == _slots.length) {
            _slots.push(Slot({clicker: clicker, active: active}));
        } else {
            require(slotId < _slots.length, "slot oob");
            _slots[slotId] = Slot({clicker: clicker, active: active});
        }

        emit SlotSet(slotId, clicker, active);
    }

    function setSlotActive(uint256 slotId, bool active) external onlyOwner {
        require(slotId < _slots.length, "slot oob");
        _slots[slotId].active = active;
        emit SlotActiveChanged(slotId, active);
    }

    function clearSlot(uint256 slotId) external onlyOwner {
        require(slotId < _slots.length, "slot oob");
        _slots[slotId] = Slot({clicker: address(0), active: false});
        emit SlotCleared(slotId);
    }

    function setCallerCooldown(uint256 newCooldown) external onlyOwner {
        callerCooldown = newCooldown;
    }

    function setRebateBps(uint256 newBps) external onlyOwner {
        require(newBps <= 20000, "bps too high");
        rebateBps = newBps;
    }

    function setGasOverhead(uint256 newGasOverhead) external onlyOwner {
        gasOverhead = newGasOverhead;
    }

    function setRebatesEnabled(bool newEnabled) external onlyOwner {
        rebatesEnabled = newEnabled;
    }

    function recoverPLS(address payable to, uint256 amount) external onlyOwner {
        require(to != address(0), "zero addr");
        if (amount == 0) amount = address(this).balance;
        (bool ok,) = to.call{value: amount}("");
        require(ok, "transfer failed");
    }

    function nextClankTime(address caller) external view returns (uint256) {
        return lastClankAt[caller] + callerCooldown;
    }

    function clank() external returns (uint256 attempted, uint256 succeeded) {
        return _clankRange(0, _slots.length);
    }

    function clankRange(uint256 start, uint256 end) external returns (uint256 attempted, uint256 succeeded) {
        return _clankRange(start, end);
    }

    function _clankRange(uint256 start, uint256 end) internal returns (uint256 attempted, uint256 succeeded) {
        require(start <= end, "bad range");
        require(end <= _slots.length, "end oob");

        uint256 lastAt = lastClankAt[msg.sender];
        require(block.timestamp >= lastAt + callerCooldown, "caller cooldown");
        lastClankAt[msg.sender] = block.timestamp;

        uint256 gasStart = gasleft();

        for (uint256 i = start; i < end; i++) {
            Slot memory s = _slots[i];
            if (!s.active || s.clicker == address(0)) {
                continue;
            }

            attempted += 1;

            try IClickerSlot(s.clicker).click() returns (uint8 code) {
                succeeded += 1;
                emit SlotClicked(i, s.clicker, code);
            } catch Error(string memory reason) {
                emit SlotClickFailed(i, s.clicker, reason);
            } catch (bytes memory data) {
                emit SlotClickFailedLowLevel(i, s.clicker, data);
            }
        }

        emit Clanked(msg.sender, start, end, attempted, succeeded);
        _payRebate(msg.sender, gasStart);
    }

    function _payRebate(address caller, uint256 gasStart) internal {
        uint256 gasUsed = (gasStart - gasleft()) + gasOverhead;
        uint256 estimatedCost = gasUsed * tx.gasprice;

        if (!rebatesEnabled || estimatedCost == 0) {
            emit RebateSkipped(caller, gasUsed, tx.gasprice, estimatedCost);
            return;
        }

        uint256 rebateAmount = (estimatedCost * rebateBps) / 10000;
        uint256 balance = address(this).balance;

        if (rebateAmount == 0 || balance == 0) {
            emit RebateSkipped(caller, gasUsed, tx.gasprice, estimatedCost);
            return;
        }

        if (rebateAmount > balance) {
            rebateAmount = balance;
        }

        (bool ok,) = payable(caller).call{value: rebateAmount}("");
        if (!ok) {
            emit RebateSkipped(caller, gasUsed, tx.gasprice, estimatedCost);
            return;
        }

        emit RebatePaid(caller, gasUsed, tx.gasprice, estimatedCost, rebateAmount);
    }

    receive() external payable {
        emit NativeFunded(msg.sender, msg.value);
    }

    fallback() external payable {
        if (msg.value > 0) {
            emit NativeFunded(msg.sender, msg.value);
        }
    }
}