Skip to main content
PulseScanner.io

Address

0xfa97ff17165d2b9aec5bf8bbdab9a14fb00f5db8
Current Holdings
$5.12
TXs sent
0
First Active
2026-04-12
block 26,266,820
Last Active
today
block 27,518,574
Funded By
0x0d6d…0f5b

Net worth historyi

383 snapshots · to block 27,518,575coverage change 26 Augcoverage change 27 Augcoverage change 27 Augcoverage change 27 Augcoverage change 27 Aug
exact matchbananasolc 0.8.34+commit.80d5c536runtime exact · creation exact
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";

interface IWPLS {
    function deposit() external payable;
    function withdraw(uint256) external;
    function balanceOf(address) external view returns (uint256);
}

interface IPLSXRouter {
    function WETH9() external view returns (address);

    function swapExactTokensForTokensV2(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to
    ) external payable returns (uint256 amountOut);
}

contract banana is ReentrancyGuard {
    using SafeERC20 for IERC20;

    address public owner;
    IPLSXRouter public router;
    IERC20 public token;
    IWPLS public wpls;

    uint256 public blockInterval;
    uint256 public minPLSAmount;
    uint256 public maxPLSAmount;

    uint256 public lastActionBlock;

    bool public isBuying = true;
    bool public isPaused = false;

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

    modifier onlyWhenRunning() {
        require(!isPaused, "Paused");
        _;
    }

    event BuyExecuted(uint256 plsIn, uint256 tokenOut);
    event SellExecuted(uint256 tokenIn, uint256 plsOut);

    constructor(
        address _router,
        address _token,
        uint256 _interval,
        uint256 _minPLS,
        uint256 _maxPLS
    ) payable {
        require(_minPLS > 0 && _maxPLS >= _minPLS, "Invalid range");

        owner = msg.sender;

        router = IPLSXRouter(_router);
        token = IERC20(_token);

        address _wpls = router.WETH9();
        wpls = IWPLS(_wpls);

        blockInterval = _interval;
        minPLSAmount = _minPLS;
        maxPLSAmount = _maxPLS;

        lastActionBlock = block.number;
        isBuying = true;

        IERC20(_wpls).approve(_router, type(uint256).max);
        token.approve(_router, type(uint256).max);
    }

    receive() external payable {}

    // =========================
    // RANDOM GENERATOR
    // =========================

    function _getRandomPLSAmount() internal view returns (uint256) {
        if (minPLSAmount == maxPLSAmount) return minPLSAmount;

        uint256 rand = uint256(
            keccak256(
                abi.encodePacked(
                    blockhash(block.number - 1),
                    block.timestamp,
                    address(this),
                    lastActionBlock
                )
            )
        );

        uint256 range = maxPLSAmount - minPLSAmount + 1;
        return minPLSAmount + (rand % range);
    }

    // =========================
    // CORE
    // =========================

    function checkAndAct() public onlyWhenRunning nonReentrant {
        require(block.number >= lastActionBlock + blockInterval, "Too soon");

        lastActionBlock = block.number;

        if (isBuying) {
            _buy();
        } else {
            _sell();
        }

        isBuying = !isBuying;
    }

    // =========================
    // BUY (RANDOMIZED SIZE)
    // =========================

    function _buy() internal {
        uint256 amountPLS = _getRandomPLSAmount();

        require(address(this).balance >= amountPLS, "NO_PLS");

        uint256 beforeBal = wpls.balanceOf(address(this));

        wpls.deposit{value: amountPLS}();

        uint256 afterBal = wpls.balanceOf(address(this));
        require(afterBal > beforeBal, "WRAP_FAILED");

        address[] memory path = new address[](2);
        path[0] = address(wpls);
        path[1] = address(token);

        uint256 tokenBefore = token.balanceOf(address(this));

        uint256 amountOut = router.swapExactTokensForTokensV2(
            amountPLS,
            1,
            path,
            address(this)
        );

        uint256 tokenAfter = token.balanceOf(address(this));
        require(tokenAfter > tokenBefore, "SWAP_FAILED");

        emit BuyExecuted(amountPLS, amountOut);
    }

    // =========================
    // SELL (ALL TOKENS)
    // =========================

    function _sell() internal {
        uint256 balance = token.balanceOf(address(this));
        require(balance > 0, "NO_TOKEN");

        address[] memory path = new address[](2);
        path[0] = address(token);
        path[1] = address(wpls);

        uint256 wplsBefore = wpls.balanceOf(address(this));

        uint256 amountOut = router.swapExactTokensForTokensV2(
            balance,
            1,
            path,
            address(this)
        );

        uint256 wplsAfter = wpls.balanceOf(address(this));
        require(wplsAfter > wplsBefore, "SELL_SWAP_FAILED");

        wpls.withdraw(wplsAfter);

        emit SellExecuted(balance, amountOut);
    }

    // =========================
    // ADMIN
    // =========================

    function setRange(uint256 _min, uint256 _max) external onlyOwner {
        require(_min > 0 && _max >= _min, "Invalid range");
        minPLSAmount = _min;
        maxPLSAmount = _max;
    }

    function withdrawPLS(uint256 amount) external onlyOwner {
        require(address(this).balance >= amount, "Insufficient");
        (bool success, ) = owner.call{value: amount}("");
        require(success, "Transfer failed");
    }
    
    function unwrapAndWithdrawWPLS() external onlyOwner {
        uint256 bal = wpls.balanceOf(address(this));
        wpls.withdraw(bal);
        (bool success, ) = owner.call{value: address(this).balance}("");
        require(success, "Transfer failed");
    }

    function withdrawToken() external onlyOwner {
        token.safeTransfer(owner, token.balanceOf(address(this)));
    }

    function pause() external onlyOwner {
        isPaused = true;
    }

    function unpause() external onlyOwner {
        isPaused = false;
    }
    // Add these functions to your contract
function getPLSBalance() public view returns (uint256) {
    return address(this).balance;
}

function getWPLSBalance() public view returns (uint256) {
    return wpls.balanceOf(address(this));
}

function getTokenBalance() public view returns (uint256) {
    return token.balanceOf(address(this));
}
}