WLFIC

Description:

Multi-signature wallet contract requiring multiple confirmations for transaction execution.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "wlfitest.sol": {
      "content": "//SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

/*
 * WLFI CRUSH (WLFIC) — streamlined for public safety checks
 * - Trading auto-activates on first liquidity add (no openTrading function)
 * - Taxes can only be PERMANENTLY disabled (irreversible)
 * - No max transaction limit logic (removed)
 * - Liquidity trigger threshold: 1000 tokens (1000 ether with 18 decimals)
 * - On trigger, process the ENTIRE contract token balance
 * - Cannot rescue this token itself (prevents rug flags on scanners)
 */

abstract contract Context {
    function _msgSender() internal view virtual returns (address) { return msg.sender; }
    function _msgData() internal view virtual returns (bytes calldata) { return msg.data; }
    function _contextSuffixLength() internal view virtual returns (uint256) { return 0; }
}

abstract contract Ownable is Context {
    address private _owner;

    error OwnableUnauthorizedAccount(address account);
    error OwnableInvalidOwner(address owner);
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    constructor(address initialOwner) {
        if (initialOwner == address(0)) revert OwnableInvalidOwner(address(0));
        _transferOwnership(initialOwner);
    }

    modifier onlyOwner() {
        if (owner() != _msgSender()) revert OwnableUnauthorizedAccount(_msgSender());
        _;
    }

    function owner() public view virtual returns (address) { return _owner; }

    function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); }

    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) revert OwnableInvalidOwner(address(0));
        _transferOwnership(newOwner);
    }

    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner; _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

interface IERC165 { function supportsInterface(bytes4 interfaceId) external view returns (bool); }

interface IERC20 {
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address to, uint256 value) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 value) external returns (bool);
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}

interface IERC20Metadata is IERC20 {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view returns (uint8);
}

interface IERC20Errors {
    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
    error ERC20InvalidSender(address sender);
    error ERC20InvalidReceiver(address receiver);
    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
    error ERC20InvalidApprover(address approver);
    error ERC20InvalidSpender(address spender);
}

abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
    mapping(address account => uint256) private _balances;
    mapping(address account => mapping(address spender => uint256)) private _allowances;
    uint256 private _totalSupply;
    string private _name; string private _symbol;

    constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; }

    function name() public view virtual returns (string memory) { return _name; }
    function symbol() public view virtual returns (string memory) { return _symbol; }
    function decimals() public view virtual returns (uint8) { return 18; }
    function totalSupply() public view virtual returns (uint256) { return _totalSupply; }
    function balanceOf(address account) public view virtual returns (uint256) { return _balances[account]; }

    function transfer(address to, uint256 value) public virtual returns (bool) {
        address owner_ = _msgSender(); _transfer(owner_, to, value); return true;
    }

    function allowance(address owner_, address spender) public view virtual returns (uint256) {
        return _allowances[owner_][spender];
    }

    function approve(address spender, uint256 value) public virtual returns (bool) {
        address owner_ = _msgSender(); _approve(owner_, spender, value); return true;
    }

    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
        address spender = _msgSender(); _spendAllowance(from, spender, value); _transfer(from, to, value); return true;
    }

    function _transfer(address from, address to, uint256 value) internal virtual {
        if (from == address(0)) revert ERC20InvalidSender(address(0));
        if (to == address(0)) revert ERC20InvalidReceiver(address(0));
        _update(from, to, value);
    }

    function _update(address from, address to, uint256 value) internal virtual {
        if (from == address(0)) {
            _totalSupply += value;
        } else {
            uint256 fromBalance = _balances[from];
            if (fromBalance < value) revert ERC20InsufficientBalance(from, fromBalance, value);
            unchecked { _balances[from] = fromBalance - value; }
        }
        if (to == address(0)) {
            unchecked { _totalSupply -= value; }
        } else {
            unchecked { _balances[to] += value; }
        }
        emit Transfer(from, to, value);
    }

    function _mint(address account, uint256 value) internal {
        if (account == address(0)) revert ERC20InvalidReceiver(address(0));
        _update(address(0), account, value);
    }

    function _burn(address account, uint256 value) internal {
        if (account == address(0)) revert ERC20InvalidSender(address(0));
        _update(account, address(0), value);
    }

    function _approve(address owner_, address spender, uint256 value) internal { _approve(owner_, spender, value, true); }

    function _approve(address owner_, address spender, uint256 value, bool emitEvent) internal virtual {
        if (owner_ == address(0)) revert ERC20InvalidApprover(address(0));
        if (spender == address(0)) revert ERC20InvalidSpender(address(0));
        _allowances[owner_][spender] = value; if (emitEvent) emit Approval(owner_, spender, value);
    }

    function _spendAllowance(address owner_, address spender, uint256 value) internal virtual {
        uint256 currentAllowance = allowance(owner_, spender);
        if (currentAllowance < type(uint256).max) {
            if (currentAllowance < value) revert ERC20InsufficientAllowance(spender, currentAllowance, value);
            unchecked { _approve(owner_, spender, currentAllowance - value, false); }
        }
    }
}

interface IERC1363 is IERC20, IERC165 {
    function transferAndCall(address to, uint256 value) external returns (bool);
    function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);
    function transferFromAndCall(address from, address to, uint256 value) external returns (bool);
    function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);
    function approveAndCall(address spender, uint256 value) external returns (bool);
    function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}

library SafeERC20 {
    error SafeERC20FailedOperation(address token);
    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);

    function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); }
    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); }
    function forceApprove(IERC20 token, address spender, uint256 value) internal {
        bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
        if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); }
    }
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        uint256 returnSize; uint256 returnValue;
        assembly ("memory-safe") {
            let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
            if iszero(success) { let ptr := mload(0x40) returndatacopy(ptr, 0, returndatasize()) revert(ptr, returndatasize()) }
            returnSize := returndatasize() returnValue := mload(0)
        }
        if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) revert SafeERC20FailedOperation(address(token));
    }
    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
        bool success; uint256 returnSize; uint256 returnValue;
        assembly ("memory-safe") {
            success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
            returnSize := returndatasize() returnValue := mload(0)
        }
        return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);
    }
}

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

interface IUniswapV2Router01 {
    function factory() external pure returns (address);
    function WETH() external pure returns (address);
    function addLiquidityETH(address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline)
        external payable returns (uint amountToken, uint amountETH, uint liquidity);
}

interface IUniswapV2Router02 is IUniswapV2Router01 {
    function swapExactTokensForETHSupportingFeeOnTransferTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external;
}

contract WLFIC is ERC20, Ownable {
    using SafeERC20 for IERC20;

    IUniswapV2Router02 public dexRouter;
    address public dexPair;

    // ↓ 1000 tokens (18 decimals)
    uint256 public liqTriggerAmount = 1000 ether;

    // totalTaxRate is stored in bps (e.g., 300 = 3.00%)
    uint256 public totalTaxRate; // combined buy/sell tax in bps (applies symmetrically)
    uint256 public liqFee;       // portion of tax routed to liquidity (relative parts)
    uint256 public ethFee;       // portion of tax routed to treasury (relative parts)

    address public treasuryReceiver;
    bool public tradingEnabled;
    bool private swapping;
    bool public taxesDisabled;   // once true, taxes are permanently off

    mapping(address => bool) private _isTxLimitExempt; // kept only for trading gate exemption (no maxTx logic)

    modifier swapLock() {
        require(!swapping, "Swap in progress");
        swapping = true;
        _;
        swapping = false;
    }

    event TaxDisabled();
    event TreasuryWithdrawn(address to, uint256 amount);
    event TokenRescue(address token, uint256 amount);
    event TradingActivated(bool enabled);
    event LiquidityTriggered(uint256 amountSwapped, uint256 tokensAdded, uint256 ethAdded);
    event ExemptionUpdated(address account, bool isExempt);

    constructor(
        address _router,
        uint256 _initialTaxRateBps, // e.g. 300 = 3%
        uint256 _ethFeePart,        // split parts, e.g. 2
        uint256 _liqFeePart,        // split parts, e.g. 1  (sum parts = relative split of totalTax)
        address _treasury
    ) ERC20("WLFI CRUSH", "WLFIC") Ownable(msg.sender) {
        require(_initialTaxRateBps >= 0, "Bad tax");
        _mint(_msgSender(), 10_000_000 ether);

        dexRouter = IUniswapV2Router02(_router);
        dexPair = IUniswapV2Factory(dexRouter.factory()).createPair(address(this), dexRouter.WETH());

        totalTaxRate = _initialTaxRateBps; // bps
        ethFee = _ethFeePart;
        liqFee = _liqFeePart;
        treasuryReceiver = _treasury;

        // exemptions: contract, owner, router, pair
        _isTxLimitExempt[address(this)] = true;
        _isTxLimitExempt[msg.sender] = true;
        _isTxLimitExempt[_router] = true;
        _isTxLimitExempt[dexPair] = true;
    }

    receive() external payable {}

    // --- Transfers with tax + auto-liquidity ---
    function _transfer(address from, address to, uint256 amount) internal override {
        require(amount > 0, "Amount > 0");

        // Trading gate: public trading only after first liquidity add
        if (!_isTxLimitExempt[from] || !_isTxLimitExempt[to]) {
            require(tradingEnabled, "Trading not enabled");
        }

        uint256 taxAmount = 0;

        // Apply tax on buys/sells (pair involved), unless taxes disabled or internal flows
        if (!taxesDisabled && totalTaxRate > 0 && from != address(this) && (from == dexPair || to == dexPair)) {
            taxAmount = (amount * totalTaxRate) / 10_000;
            super._transfer(from, address(this), taxAmount);
        }

        // Trigger liquidity/treasury swap on sells (to pair) when threshold met
        if (!swapping && to == dexPair && !_isTxLimitExempt[from]) {
            uint256 contractBalance = balanceOf(address(this));
            if (contractBalance >= liqTriggerAmount) {
                // Process the ENTIRE balance (not capped)
                _handleLiquidity(contractBalance);
            }
        }

        super._transfer(from, to, amount - taxAmount);
    }

    function _handleLiquidity(uint256 amount) private swapLock {
        if (taxesDisabled || (ethFee == 0 && liqFee == 0)) return;
        if (amount == 0) return;

        uint256 parts = ethFee + liqFee;
        if (parts == 0) return;

        // Split taxed tokens: some converted to ETH (treasury + half-liq), some paired as tokens (half-liq)
        uint256 tokensForLiq = (amount * liqFee) / parts;           // total tokens allocated for liquidity
        uint256 tokensForLiqHalf = tokensForLiq / 2;                // half kept as tokens to add with ETH
        uint256 tokensToSwap = amount - tokensForLiqHalf;           // swap rest to ETH

        uint256 initialETH = address(this).balance;

        _swapTokensForETH(tokensToSwap);

        uint256 ethGained = address(this).balance - initialETH;

        // Pro-rate ETH between liquidity and treasury by their parts
        uint256 ethForLiq = (ethGained * liqFee) / parts;
        uint256 ethForTreasury = ethGained - ethForLiq;

        // Add liquidity
        if (tokensForLiqHalf > 0 && ethForLiq > 0) {
            _addLiquidity(tokensForLiqHalf, ethForLiq);
        }

        // Send treasury
        if (ethForTreasury > 0) {
            (bool ok, ) = payable(treasuryReceiver).call{value: ethForTreasury}("");
            require(ok, "Treasury transfer failed");
        }

        emit LiquidityTriggered(tokensToSwap, tokensForLiqHalf, ethForLiq);
    }

    function _swapTokensForETH(uint256 tokens) private {
        if (tokens == 0) return;

        address[] memory route = new address[](2);
        route[0] = address(this);
        route[1] = dexRouter.WETH();

        _approve(address(this), address(dexRouter), tokens);
        dexRouter.swapExactTokensForETHSupportingFeeOnTransferTokens(
            tokens,
            0,
            route,
            address(this),
            block.timestamp
        );
    }




    function _addLiquidity(uint256 tokens, uint256 eth) private {
        if (tokens == 0 || eth == 0) return;

        _approve(address(this), address(dexRouter), tokens);
        dexRouter.addLiquidityETH{value: eth}(
            address(this),
            tokens,
            0,
            0,
            owner(),            // LP an Owner (Scanner-agnostisch; du kannst später locken/burnen)
            block.timestamp
        );

        // Auto-activate trading on first successful liquidity add
        if (!tradingEnabled) {
            tradingEnabled = true;
            emit TradingActivated(true);
        }
    }

    // --- OWNER: one-way tax kill-switch (irreversible) ---
    function disableTaxesPermanently() external onlyOwner {
        require(!taxesDisabled, "Already disabled");
        taxesDisabled = true;
        totalTaxRate = 0;
        liqFee = 0;
        ethFee = 0;
        emit TaxDisabled();
    }

    // --- OWNER: utilities (kept minimal for scanner green checks) ---
    function rescueETH(address payable recipient) external onlyOwner {
        uint256 amt = address(this).balance;
        require(amt > 0, "No ETH");
        (bool ok, ) = recipient.call{value: amt}("");
        require(ok, "ETH transfer failed");
        emit TreasuryWithdrawn(recipient, amt);
    }

    function rescueTokens(address token) external onlyOwner {
        require(token != address(this), "Cannot rescue this token"); // important for scanners
        uint256 bal = IERC20(token).balanceOf(address(this));
        require(bal > 0, "No tokens");
        IERC20(token).safeTransfer(owner(), bal);
        emit TokenRescue(token, bal);
    }

    function setExemption(address account, bool exempt) external onlyOwner {
        _isTxLimitExempt[account] = exempt; // only affects trading gate; no tx size enforcement
        emit ExemptionUpdated(account, exempt);
    }

    function updateLiqTriggerAmount(uint256 newAmount) external onlyOwner {
        require(newAmount > 0, "Invalid amount");
        liqTriggerAmount = newAmount;
    }

    function updateTreasuryReceiver(address newReceiver) external onlyOwner {
        require(newReceiver != address(0), "Invalid address");
        treasuryReceiver = newReceiver;
    }
}
"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": false,
      "runs": 200
    },
    "outputSelection": {
      "*": {
        "*": [
          "evm.bytecode",
          "evm.deployedBytecode",
          "devdoc",
          "userdoc",
          "metadata",
          "abi"
        ]
      }
    },
    "remappings": []
  }
}}

Tags:
ERC20, ERC165, Multisig, Swap, Liquidity, Multi-Signature, Factory|addr:0x49855c68c6a546e10a13f074e9d35da9c5c933c2|verified:true|block:23396174|tx:0x214665363c8d7f6432e9049197af030036c32c956e537e066b46aeb21a8fbea2|first_check:1758280061

Submitted on: 2025-09-19 13:07:42

Comments

Log in to comment.

No comments yet.