Skip to main content
PulseScanner.io

Address

0x35f531e5f5cd254dfe79bc500aee025ea63fe55d
Current Holdings
$0.00
TXs sent
not counted
First Active
2025-03-05
block 22,871,278
Last Active
354 days ago
block 24,606,987
Funded By
not identified

Net worth historyi

95 snapshots · to block 27,488,945coverage change 26 Augcoverage change 27 Augcoverage change 27 Augcoverage change 27 Augcoverage change 27 Aug
partial matchKSBTsolc 0.8.30+commit.73712a01runtime partial · creation not verified
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/utils/math/Math.sol";

interface IPulseXRouter {
    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);
    function swapExactTokensForTokensSupportingFeeOnTransferTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external;
    function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] calldata amounts);
}

interface IPulseXFactory {
    function createPair(address tokenA, address tokenB) external returns (address pair);
    function getPair(address tokenA, address tokenB) external view returns (address pair);
}

error FailedToTransfer(address from, address to, uint256 amount);
error InsufficientAllowance(uint256 amount);
error InsufficientBalance(uint256 amount);
error InvalidAddress(address _address);
error LPDoesNotExist(address tokenA, address tokenB);
error LPMinimumTooLow(uint256 amount);
error OverMaxTransferAmount(uint256 amount);
error TaxIsTooHigh(uint256 percent);

contract KSBT is Ownable (msg.sender) {
    using SafeERC20 for IERC20;
    
    mapping(address => uint256) public balanceOf;
    mapping(address => mapping(address => uint256)) public allowance;

    string public name = "DOUBT";
    string public symbol = unicode"DOUBT";
    uint256 public decimals = 18;
    uint256 public totalSupply = 5555 * 10**decimals;

    bool public taxActivated;
    uint64 public taxPercent;
    address public taxReceiverAddress;
    mapping(address => bool) public taxExempt;
    mapping(address => bool) public taxTrigger;
    
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);

    IERC20 SelfERC20 = IERC20(address(this));

    IERC20 KSBERC20;
    IERC20 WPLSERC20 = IERC20(address(0xA1077a294dDE1B09bB078844df40758a5D0f9a27));
    IPulseXRouter PulseXV1Router = IPulseXRouter(address(0x98bf93ebf5c380C0e6Ae8e192A7e2AE08edAcc02));
    IPulseXRouter PulseXV2Router = IPulseXRouter(address(0x165C3410fC91EF562C50559f7d2289fEbed552d9));
    IPulseXFactory PulseXV1Factory = IPulseXFactory(address(0x1715a3E4A142d8b698131108995174F37aEBA10D));
    IPulseXFactory PulseXV2Factory = IPulseXFactory(address(0x29eA7545DEf87022BAdc76323F373EA1e707C523));

    bool reLockOn = false;
    bool lpActivated = true;
    address public lpTokenA;
    address public lpTokenB;
    uint256 lpMinAmount = 0;
    
    constructor(uint64 _taxPercent, address _tokenAddress, bool _taxActivated, bool _lpActivated) {
        require(_tokenAddress != address(0), "Set the address for the main token");
        KSBERC20 = IERC20(_tokenAddress);

        // set initial tax configs
        taxReceiverAddress = msg.sender;
        taxPercent = _taxPercent; // 1% is 100, 100% is 10000
        taxActivated = _taxActivated;

        // set initial lpc onfigs
        lpActivated = _lpActivated;
        lpTokenA = _tokenAddress;
        lpTokenB = address(this);
        
        // set deployer as tax exempt
        taxExempt[msg.sender] = true;

        // create empty pairs
        address lpAddressV1 = PulseXV1Factory.createPair(_tokenAddress, address(this));
        address lpAddressV2 = PulseXV2Factory.createPair(_tokenAddress, address(this));
        address lpSelfWPLSV1 = PulseXV1Factory.createPair(address(this), address(WPLSERC20));
        address lpSelfWPLSV2 = PulseXV2Factory.createPair(address(this), address(WPLSERC20));

        // set them as taxable triggers
        taxTrigger[lpAddressV1] = true;
        taxTrigger[lpAddressV2] = true;
        taxTrigger[lpSelfWPLSV1] = true;
        taxTrigger[lpSelfWPLSV2] = true;

        // approve pulsex v1 and v2 to spend tokens belonging to this contract
        allowance[address(this)][address(PulseXV1Router)] = type(uint256).max;
        allowance[address(this)][address(PulseXV2Router)] = type(uint256).max;

        // send initial supply to the deployer
        balanceOf[msg.sender] = totalSupply;
        emit Transfer(address(0), msg.sender, totalSupply);
    }

    receive() external payable { }

    modifier reLock() {
        // reentrant lock
        reLockOn = true;
        _;
        reLockOn = false;
    }

    function approve(address spender, uint256 amount) public {
        // approve spender to access tokens using transferFrom
        allowance[msg.sender][spender] = amount;
        emit Approval(msg.sender, spender, amount);
    }

    function _transferWithFees(address from, address to, uint256 amount, uint256 fees) internal {
        // add amount to receiver
        (bool taxSuccess, uint256 amountSubFee) = Math.trySub(amount, fees);
        (bool toSuccess, uint256 toBalance) = Math.tryAdd(balanceOf[to], amountSubFee);
        if (taxSuccess)
            if (toSuccess)
                balanceOf[to] = toBalance;
        // sub amount from sender
        (bool fromSuccess, uint256 fromBalance) = Math.trySub(balanceOf[from], amount);
        if (fromSuccess)
            balanceOf[from] = fromBalance;
        // check if both actions succeeded and emit or revert
        if (fromSuccess && toSuccess && taxSuccess)
            emit Transfer(from, to, amountSubFee);
        else
            revert FailedToTransfer(from, to, amount);
    }
    
    function _transfer(address from, address to, uint256 amount) internal {
        // transfer like normal if reLock engaged
        uint256 fees = 0;
        if (!reLockOn) {
            // check balance
            if (balanceOf[from] < amount)
                revert InsufficientBalance(amount);
            // get amount to send with/without tax
            if (triggerTax(from, to)) {
                if (triggerSwapForLP())
                    swapForLP();
                if (!isTaxExempt(from, to))
                    if (taxActivated)
                        fees = takeTax(from, amount);
            }
        }
        // transfer the final amount
        _transferWithFees(from, to, amount, fees);
    }
    
    function transfer(address to, uint256 amount) public {
        // transfer token amount from source
        _transfer(msg.sender, to, amount);
    }
    
    function transferFrom(address from, address to, uint256 amount) public {
        // check allowance
        if (allowance[from][msg.sender] < amount)
            revert InsufficientAllowance(amount);
        // transfer token amount
        _transfer(from, to, amount);
    }

    function triggerTax(address from, address to) internal view returns (bool) {
        // triggers on known lp pools or other addresses
        if (taxTrigger[from] || taxTrigger[to])
            return true;
        return false;
    }

    function approveToken(IERC20 token, IPulseXRouter router) internal returns (bool) {
        // approves any erc20 with a chosen router for this contract
        if (token.allowance(address(this), address(router)) < (type(uint256).max / 2))
            token.approve(address(router), type(uint256).max);
        return true;
    }

    function triggerSwapForLP() internal view returns (bool) {
        // triggers if enough tokens accrued with lp activated and reentrant is not locked
        if (!reLockOn 
            && lpActivated 
            && balanceOf[address(this)] >= lpMinAmount)
                return true;
        return false;
    }

    function getBetterRouterForPath(uint256 amount, address[] memory lpPath) internal view returns (bool, IPulseXRouter, uint256) {
        IPulseXRouter router;
        uint256 outputAmount;
        // check pulsex v1
        uint256 tokenAmountV1 = 0;
        try PulseXV1Router.getAmountsOut(
            amount,
            lpPath
        ) returns (uint256[] memory amountOutMinV1) {
            tokenAmountV1 = amountOutMinV1[amountOutMinV1.length - 1];
        } catch {}
        // check pulsex v2
        uint256 tokenAmountV2 = 0;
        try PulseXV2Router.getAmountsOut(
            amount,
            lpPath
        ) returns (uint256[] memory amountOutMinV2) {
            tokenAmountV2 = amountOutMinV2[amountOutMinV2.length - 1];
        } catch {}
        // compare the output amounts
        if (tokenAmountV1 >= tokenAmountV2) {
            router = PulseXV1Router;
            outputAmount = tokenAmountV1;
        } else {
            router = PulseXV2Router;
            outputAmount = tokenAmountV2;
        }
        // sucess if one of the amounts is not zero
        // return the better router and output amount
        return (tokenAmountV1 != 0 && tokenAmountV2 != 0, router, outputAmount);
    }

    function getBetterPathAndRouter(uint256 amount, address tokenA, address tokenB) internal view returns (bool, address[] memory, IPulseXRouter) {
        // route with two hops
        address[] memory lpPath3 = new address[](3);
        lpPath3[0] = tokenA == address(this) ? address(this) : tokenA;
        lpPath3[1] = address(WPLSERC20);
        lpPath3[2] = tokenB == address(this) ? address(this) : tokenB;
        // route with one hop
        address[] memory lpPath2 = new address[](2);
        lpPath2[0] = lpPath3[0];
        lpPath2[1] = lpPath3[2];
        // find and return the best router
        (bool success1, IPulseXRouter router1, uint256 outputAmount1) = getBetterRouterForPath(amount, lpPath3);
        (bool success2, IPulseXRouter router2, uint256 outputAmount2) = getBetterRouterForPath(amount, lpPath2);
        // both paths resulted in a router
        if (success1 && success2)
            // check the best result of those
            if (outputAmount1 < outputAmount2)
                return (true, lpPath2, router2);
        // only one of the paths were found
        if (success1)
            return (true, lpPath3, router1);
        // default to the other path
        return (true, lpPath2, router2);
    }

    function swapForLP() public reLock {
        if (lpTokenA == address(this))
            if (lpTokenB == address(this))
                return;
        // get the balance of this token in the contract and divide in half
        uint256 splitAmount = (balanceOf[address(this)] / 2);
        // get the better path and router based on estimates
        (bool successA, address[] memory lpPathA, IPulseXRouter routerA) = getBetterPathAndRouter(splitAmount, address(this), lpTokenA);
        (bool successB, address[] memory lpPathB, IPulseXRouter routerB) = getBetterPathAndRouter(splitAmount, address(this), lpTokenB);
        // perform the swap if routes were found
        if (successA)
            if (successB) {
                // first half
                if (lpTokenA != address(this))
                    routerA.swapExactTokensForTokensSupportingFeeOnTransferTokens(
                        splitAmount,
                        0,
                        lpPathA,
                        taxReceiverAddress, // receiver
                        block.timestamp
                    );
                // second half
                if (lpTokenB != address(this))
                    routerB.swapExactTokensForTokensSupportingFeeOnTransferTokens(
                        splitAmount,
                        0,
                        lpPathB,
                        taxReceiverAddress, // receiver
                        block.timestamp
                    );
                // send the other half if one of the swaps were skipped
                if (lpTokenA == address(this) || lpTokenB == address(this))
                    _transferWithFees(
                        address(this), 
                        taxReceiverAddress,  // receiver
                        splitAmount, 
                        0 // ignore fee
                    );
            }
    }

    function setLPSwapState(bool state) public onlyOwner {
        // set lp swap enabled/disabled
        lpActivated = state;
    }

    function setLP(address tokenA, address tokenB) public onlyOwner returns (bool) {
        // update lp tokenA/B values
        // must be matched with a companion contract receiving the tokens
        if (tokenA != address(0))
            if (tokenB != address(0)) {
                lpTokenA = tokenA;
                lpTokenB = tokenB;
                return true;
            }
        return false;
    }

    function takeTax(address from, uint256 amount) internal returns (uint256) {
        // returns the amount after taking fees
        uint256 fees = 0;
        if (!taxExempt[from]) {
            // 1% is represented as 100 so dividing should be 10000
            fees = Math.mulDiv(amount, taxPercent, 10000);
            // add fees taken to contract balances
            balanceOf[address(this)] += fees;
            // emit transfer event for the fees taken
            emit Transfer(from, address(this), fees);
        }
        return fees;
    }

    function setTaxExempt(address _address, bool _exemption) public onlyOwner {
        // set tax exempt enabled/disabled per address
        taxExempt[_address] = _exemption;
    }

    function isTaxExempt(address from, address to) view public returns (bool) {
        // from sender only to prevent abusing lp
        return taxExempt[from] || taxExempt[to];
    }

    function setTaxPercent(uint64 percent) public onlyOwner {
        // set tax fee percent out of 100
        if (percent >= 10000)
            revert TaxIsTooHigh(percent);
        taxPercent = percent;
    }

    function setTaxState(bool state) public onlyOwner {
        // set tax enabled/disabled
        taxActivated = state;
    }

    function setTaxReceiver(address _address) public onlyOwner {
        // set receiver of lp tokens
        taxReceiverAddress = _address;
    }

    function setTaxableTrigger(address _address, bool state) public onlyOwner {
        // enable/disable tax for addresses to/from
        // opposite effect of taxExempt
        taxTrigger[_address] = state;
    }

    function withdrawPLS() public onlyOwner {
        // sends any pls in the balance to the contract owner
        payable(owner()).transfer(address(this).balance);
    }

    function withdrawERC20(address token) public onlyOwner {
        // sends any erc20 in the balance to the contract owner
        IERC20 tokenERC20 = IERC20(token);
        tokenERC20.transfer(owner(), tokenERC20.balanceOf(address(this)));
    }
}