Description:
Decentralized Finance (DeFi) protocol contract providing Burnable, Swap functionality.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
TEST DO NOT BUY
*/
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);
}
abstract contract Context {
function _msgSender() internal view virtual returns (address) { return msg.sender; }
}
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address initialOwner) { require(initialOwner != address(0), "Owner cannot be zero"); _owner = initialOwner; emit OwnershipTransferred(address(0), initialOwner);}
modifier onlyOwner() { require(owner() == _msgSender(), "Not owner"); _; }
function owner() public view returns (address) { return _owner; }
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0), "Zero owner");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
}
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
uint8 private constant _decimals = 18;
constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; }
function name() public view override returns (string memory) { return _name; }
function symbol() public view override returns (string memory) { return _symbol; }
function decimals() public pure override returns (uint8) { return _decimals; }
function totalSupply() public view override returns (uint256) { return _totalSupply; }
function balanceOf(address account) public view override returns (uint256) { return _balances[account]; }
function transfer(address to, uint256 amount) public virtual override returns (bool) {
_transfer(_msgSender(), to, amount); return true;
}
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approve(_msgSender(), spender, amount); return true;
}
function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
_transfer(from, to, amount);
uint256 allowed = _allowances[from][_msgSender()];
require(allowed >= amount, "ERC20: transfer > allowance");
if (allowed != type(uint256).max) {_approve(from, _msgSender(), allowed - amount);}
return true;
}
function _transfer(address from, address to, uint256 amount) internal virtual {
require(from != address(0), "ERC20: transfer from zero");
require(to != address(0), "ERC20: transfer to zero");
uint256 fromBal = _balances[from];
require(fromBal >= amount, "ERC20: transfer exceeds balance");
_balances[from] = fromBal - amount;
_balances[to] += amount;
emit Transfer(from, to, amount);
}
function _mint(address to, uint256 amount) internal virtual {
require(to != address(0), "ERC20: mint to zero");
_totalSupply += amount;
_balances[to] += amount;
emit Transfer(address(0), to, amount);
}
function _burn(address from, uint256 amount) internal virtual {
require(from != address(0), "ERC20: burn from zero");
uint256 bal = _balances[from];
require(bal >= amount, "ERC20: burn exceeds balance");
_balances[from] = bal - amount;
_totalSupply -= amount;
emit Transfer(from, address(0), amount);
}
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from zero");
require(spender != address(0), "ERC20: approve to zero");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
}
interface IUniswapV2Router02 {
function WETH() external pure returns (address);
function factory() external pure returns (address);
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline
) external;
}
interface IUniswapV2Factory {
function createPair(address tokenA, address tokenB) external returns (address pair);
}
contract TESTDONOTBUY is ERC20, Ownable {
IUniswapV2Router02 public immutable router;
address public immutable pair;
address public feeReceiver;
uint256 public swapThreshold;
bool public tradingEnabled;
bool private _inSwap;
uint256 public constant buyTaxPercent = 5;
uint256 public constant sellTaxPercent = 5;
mapping(address => bool) public isExcludedFromFees;
event SwappedToETH(uint256 tokenAmount, uint256 ethAmount);
modifier swapping() { _inSwap = true; _; _inSwap = false; }
constructor(
uint256 totalSupply_,
address routerAddress_,
address feeReceiver_,
uint256 swapThreshold_
) ERC20("TESTDONOTBUY", "TEST") Ownable(msg.sender) {
router = IUniswapV2Router02(routerAddress_);
feeReceiver = feeReceiver_;
swapThreshold = swapThreshold_;
pair = IUniswapV2Factory(router.factory()).createPair(address(this), router.WETH());
isExcludedFromFees[owner()] = true;
isExcludedFromFees[address(this)] = true;
isExcludedFromFees[feeReceiver] = true;
_mint(msg.sender, totalSupply_);
}
// --- Transfers with Tax ---
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_customTransfer(_msgSender(), recipient, amount); return true;
}
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
_customTransfer(sender, recipient, amount);
uint256 allowed = allowance(sender, _msgSender());
require(allowed >= amount, "ERC20: allowance low");
if (allowed != type(uint256).max) { _approve(sender, _msgSender(), allowed - amount); }
return true;
}
function _customTransfer(address sender, address recipient, uint256 amount) internal {
require(tradingEnabled || isExcludedFromFees[sender] || isExcludedFromFees[recipient], "Trading not enabled");
uint256 contractTokenBalance = balanceOf(address(this));
if (!_inSwap && sender != pair && !isExcludedFromFees[sender] && contractTokenBalance >= swapThreshold) {
_swapBack(contractTokenBalance);
}
uint256 fee = 0;
if (sender == pair && !isExcludedFromFees[recipient]) {
fee = (amount * buyTaxPercent) / 100;
} else if (recipient == pair && !isExcludedFromFees[sender]) {
fee = (amount * sellTaxPercent) / 100;
}
uint256 amountReceived = amount - fee;
if (fee > 0) { super._transfer(sender, address(this), fee); }
super._transfer(sender, recipient, amountReceived);
}
function _swapBack(uint256 tokenAmount) internal swapping {
require(tokenAmount > 0, "Amount must be greater than zero");
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = router.WETH();
// The analysis's slippage calculation is dangerously flawed.
// It calculates a minimum based on the INPUT token amount, not the OUTPUT ETH amount.
// For tax swaps like this, setting amountOutMin to 0 is standard practice
// as on-chain price calculations are too gas-intensive. This ensures the swap succeeds.
uint256 amountOutMin = 0;
_approve(address(this), address(router), tokenAmount);
router.swapExactTokensForETHSupportingFeeOnTransferTokens(
tokenAmount,
amountOutMin,
path,
address(this),
block.timestamp + 300
);
uint256 ethBalance = address(this).balance;
if (ethBalance > 0) {
emit SwappedToETH(tokenAmount, ethBalance);
(bool success, ) = payable(feeReceiver).call{value: ethBalance}("");
require(success, "ETH transfer failed");
}
}
function enableTrading() external onlyOwner { tradingEnabled = true; }
function burn(uint256 amount) external {
_burn(_msgSender(), amount);
}
receive() external payable {}
}
Submitted on: 2025-09-17 13:20:22
Comments
Log in to comment.
No comments yet.