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)
* - Trading auto-activates on first liquidity add (no openTrading function)
* - Taxes can only be PERMANENTLY disabled (irreversible)
* - No max transaction limit logic
* - 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;
}
// --- Base ERC20 (no project logic here) ---
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 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 in basis points (e.g., 300 = 3.00%)
uint256 public totalTaxRate; // combined buy/sell tax in bps
uint256 public liqFee; // split parts for liquidity
uint256 public ethFee; // split parts for treasury
address public treasuryReceiver;
bool public tradingEnabled;
bool private swapping;
bool public taxesDisabled; // once true, taxes are permanently off
mapping(address => bool) private _isTxLimitExempt; // only for trading gate exemption
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 (parts sum defines ratio)
address _treasury
) ERC20("WLFI CRUSH", "WLFIC") Ownable(msg.sender) {
_mint(_msgSender(), 10_000_000 ether);
dexRouter = IUniswapV2Router02(_router);
dexPair = IUniswapV2Factory(dexRouter.factory()).createPair(address(this), dexRouter.WETH());
totalTaxRate = _initialTaxRateBps; // fixed; only disable allowed
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");
// Auto-Enable Trading on first token flow into pair (bundle-friendly)
if (!tradingEnabled && to == dexPair) {
tradingEnabled = true;
emit TradingActivated(true);
}
// Trading gate for non-exempt addresses
if (!_isTxLimitExempt[from] || !_isTxLimitExempt[to]) {
require(tradingEnabled, "Trading not enabled");
}
uint256 taxAmount = 0;
// Apply tax on buys/sells (only once trading is enabled)
if (
tradingEnabled &&
!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) {
_handleLiquidity(contractBalance); // process ALL tokens
}
}
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: some swapped to ETH (treasury + half-liq), some kept as tokens (half-liq)
uint256 tokensForLiq = (amount * liqFee) / parts; // tokens allocated for liquidity
uint256 tokensForLiqHalf = tokensForLiq / 2; // token half for LP
uint256 tokensToSwap = amount - tokensForLiqHalf; // rest to swap 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;
if (tokensForLiqHalf > 0 && ethForLiq > 0) {
_addLiquidity(tokensForLiqHalf, ethForLiq);
}
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(), // you can lock/burn LP later for trust
block.timestamp
);
// (Redundant safeguard; trading already auto-enabled in _transfer on first pair flow)
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 (scanner-friendly) ---
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"); // avoid rug flags
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 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": []
}
}}
Submitted on: 2025-09-19 13:08:07
Comments
Log in to comment.
No comments yet.