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;
/* ----------------------------- Context / Ownable ---------------------------- */
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);
}
}
/* --------------------------------- ERC20 ---------------------------------- */
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=>uint256) private _balances;
mapping(address=>mapping(address=>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 o=_msgSender(); _transfer(o,to,value); return true;
}
function allowance(address o,address s) public view virtual returns (uint256) { return _allowances[o][s]; }
function approve(address s,uint256 v) public virtual returns (bool) {
address o=_msgSender(); _approve(o,s,v); return true;
}
function transferFrom(address f,address t,uint256 v) public virtual returns (bool) {
address sp=_msgSender(); _spendAllowance(f,sp,v); _transfer(f,t,v); 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 fb=_balances[from]; if (fb<value) revert ERC20InsufficientBalance(from,fb,value);
unchecked { _balances[from] = fb - value; }
}
if (to==address(0)) { unchecked { _totalSupply -= value; } }
else { unchecked { _balances[to] += value; } }
emit Transfer(from,to,value);
}
function _mint(address a,uint256 v) internal { if (a==address(0)) revert ERC20InvalidReceiver(address(0)); _update(address(0),a,v); }
function _burn(address a,uint256 v) internal { if (a==address(0)) revert ERC20InvalidSender(address(0)); _update(a,address(0),v); }
function _approve(address o,address s,uint256 v) internal { _approve(o,s,v,true); }
function _approve(address o,address s,uint256 v,bool emitEvent) internal virtual {
if (o==address(0)) revert ERC20InvalidApprover(address(0));
if (s==address(0)) revert ERC20InvalidSpender(address(0));
_allowances[o][s]=v; if (emitEvent) emit Approval(o,s,v);
}
function _spendAllowance(address o,address s,uint256 v) internal virtual {
uint256 ca=allowance(o,s);
if (ca<type(uint256).max) {
if (ca<v) revert ERC20InsufficientAllowance(s,ca,v);
unchecked { _approve(o,s,ca-v,false); }
}
}
}
/* -------------------------------- SafeERC20 -------------------------------- */
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 callData = abi.encodeCall(token.approve,(spender,value));
if(!_callOptionalReturnBool(token, callData)){
_callOptionalReturn(token, abi.encodeCall(token.approve,(spender,0)));
_callOptionalReturn(token, callData);
}
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
(bool success, bytes memory returndata) = address(token).call(data);
if (!success) {
if (returndata.length > 0) {
assembly { revert(add(returndata,32), mload(returndata)) }
}
revert SafeERC20FailedOperation(address(token));
}
if (returndata.length > 0 && abi.decode(returndata,(bool)) != true) {
revert SafeERC20FailedOperation(address(token));
}
}
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool){
(bool success, bytes memory returndata) = address(token).call(data);
if (!success) return false;
if (returndata.length == 0) return address(token).code.length > 0;
return abi.decode(returndata,(bool));
}
}
/* ---------------------------- Uniswap V2 minimal --------------------------- */
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;
}
/* --------------------------------- Token ---------------------------------- */
contract WLFIC is ERC20, Ownable {
using SafeERC20 for IERC20;
IUniswapV2Router02 public dexRouter;
address public dexPair;
// Process entire contract balance when >= this threshold (18 decimals)
uint256 public liqTriggerAmount = 1000 ether;
// === FEES: immutable, only one-way disable ===
uint256 public immutable taxRateBps; // e.g. 300 = 3.00%; hard-capped ≤ 1000
uint256 public immutable ethFeePart; // e.g. 2
uint256 public immutable liqFeePart; // e.g. 1 (ratio eth:liq)
address public treasuryReceiver;
// Launch & swap state
bool public tradingEnabled;
bool private swapping;
bool public taxesDisabled; // once true, permanently off
// Launch allow-list (NOT a blacklist). Permanently locked after trading is enabled.
mapping(address=>bool) private _isTxLimitExempt;
bool public exemptionsLocked;
/* --------------------------------- Events -------------------------------- */
event TaxDisabled();
event TreasuryWithdrawn(address to,uint256 amount);
event TokenRescue(address token,uint256 amount);
event TradingActivated(bool enabled);
event ExemptionsLocked();
event LiquidityTriggered(uint256 amountSwapped,uint256 tokensAdded,uint256 ethAdded);
event ExemptionUpdated(address account,bool isExempt);
/* --------------------------------- Setup --------------------------------- */
constructor(
address _router,
uint256 _initialTaxRateBps,
uint256 _ethFeePart,
uint256 _liqFeePart,
address _treasury
) ERC20("WLFI CRUSH","WLFIC") Ownable(msg.sender)
{
// Hard cap to satisfy scanners: cannot exceed 10%
require(_initialTaxRateBps <= 1000, "Tax too high");
_mint(_msgSender(), 10_000_000 ether);
dexRouter = IUniswapV2Router02(_router);
dexPair = IUniswapV2Factory(dexRouter.factory()).createPair(address(this), dexRouter.WETH());
taxRateBps = _initialTaxRateBps;
ethFeePart = _ethFeePart;
liqFeePart = _liqFeePart;
treasuryReceiver = _treasury;
// Pre-launch exemptions (owner, contract, router, pair)
_isTxLimitExempt[address(this)] = true;
_isTxLimitExempt[msg.sender] = true;
_isTxLimitExempt[_router] = true;
_isTxLimitExempt[dexPair] = true;
}
receive() external payable {}
/* ------------------------------ Launch helper ---------------------------- */
function _activateTradingOnce() internal {
if (!tradingEnabled) {
tradingEnabled = true;
emit TradingActivated(true);
if (!exemptionsLocked) {
exemptionsLocked = true;
emit ExemptionsLocked();
}
}
}
/* -------------------------------- Transfers ------------------------------ */
modifier swapLock(){ require(!swapping,"Swap in progress"); swapping=true; _; swapping=false; }
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) {
_activateTradingOnce();
}
// Gate ONLY before launch. After launch, this branch never executes again.
if (!tradingEnabled) {
if (!_isTxLimitExempt[from] || !_isTxLimitExempt[to]) {
revert("Trading not enabled");
}
}
uint256 taxAmount = 0;
// Apply tax only after trading is enabled; can only be turned off permanently
if (
tradingEnabled &&
!taxesDisabled &&
taxRateBps > 0 &&
from != address(this) &&
(from == dexPair || to == dexPair)
) {
taxAmount = (amount * taxRateBps) / 10_000;
super._transfer(from, address(this), taxAmount);
}
// On sells, process full contract balance when threshold reached
if (!swapping && to == dexPair && tradingEnabled) {
uint256 contractBal = balanceOf(address(this));
if (contractBal >= liqTriggerAmount) {
_handleLiquidity(contractBal);
}
}
super._transfer(from, to, amount - taxAmount);
}
function _handleLiquidity(uint256 amount) private swapLock {
if (taxesDisabled || (ethFeePart == 0 && liqFeePart == 0)) return;
if (amount == 0) return;
uint256 parts = ethFeePart + liqFeePart;
if (parts == 0) return;
uint256 tokensForLiq = (amount * liqFeePart) / parts;
uint256 tokensForLiqHalf = tokensForLiq / 2;
uint256 tokensToSwap = amount - tokensForLiqHalf;
uint256 startETH = address(this).balance;
_swapTokensForETH(tokensToSwap);
uint256 ethGained = address(this).balance - startETH;
uint256 ethForLiq = (ethGained * liqFeePart) / 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(), block.timestamp);
_activateTradingOnce(); // locks exemptions permanently
}
/* ---------------------------- One-way fee switch ------------------------- */
function disableTaxesPermanently() external onlyOwner {
require(!taxesDisabled, "Already disabled");
taxesDisabled = true;
emit TaxDisabled();
}
/* ----------------------------- Owner utilities --------------------------- */
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");
uint256 bal = IERC20(token).balanceOf(address(this)); require(bal>0, "No tokens");
IERC20(token).safeTransfer(owner(), bal);
emit TokenRescue(token, bal);
}
// Exemptions are ONLY configurable pre-launch. After launch they are permanently locked.
function setExemption(address account,bool exempt) external onlyOwner {
require(!exemptionsLocked, "Exemptions permanently locked");
require(!tradingEnabled, "Exemptions locked after launch");
_isTxLimitExempt[account] = exempt;
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:09:19
Comments
Log in to comment.
No comments yet.