// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0/contracts/token/ERC20/IERC20.sol
interface IERC20 {
function totalSupply() external view returns (uint);
function balanceOf(address account) external view returns (uint);
function transfer(address recipient, uint amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint value);
event Approval(address indexed owner, address indexed spender, uint value);
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
import "./IERC20.sol";
contract MerleToken is IERC20 {
mapping(address => uint) public balanceOf;
mapping(address => mapping(address => uint)) public allowance;
string public constant name = "Merle";
string public constant symbol = "MRL";
uint8 public constant decimals = 18;
uint256 public totalSupply;
address public taxAddress;
uint256 public taxFeeMultiplier; // Fee multiplier for tax fees (e.g., 10 for 1%)
uint256 public burnFeeMultiplier; // Fee multiplier for burn fees (e.g., 10 for 1%)
mapping(address => bool) public isExcludedFromTax;
mapping(address => bool) public isExcludedFromDeflation;
address public owner;
modifier onlyOwner() {
require(msg.sender == owner, "Only the contract owner can perform this action.");
_;
}
constructor() {
owner = msg.sender;
taxAddress = address(0xD3F66FB3e58d9272d5dFECaB3FA96497a12a4168); // Predefined address to receive tax fees
taxFeeMultiplier = 0; // 1% tax fee on transfers (1% = 0.01)
burnFeeMultiplier = 0; // 1% burn fee on transfers (1% = 0.01)
totalSupply = 10000000 * 10**decimals; // Initial total supply
balanceOf[msg.sender] = totalSupply;
emit Transfer(address(0), msg.sender, totalSupply);
}
function transfer(address to, uint256 value) public returns (bool) {
require(value <= balanceOf[msg.sender], "Insufficient balance.");
uint256 taxAmount = 0;
uint256 burnAmount = 0;
if (!isExcludedFromTax[msg.sender]) {
if (msg.sender==owner)
{
taxAmount = 0;
}
else{
taxAmount = (value * taxFeeMultiplier) / 10000;
}
balanceOf[msg.sender] -= taxAmount;
balanceOf[taxAddress] += taxAmount;
emit Transfer(msg.sender, taxAddress, taxAmount);
}
if (!isExcludedFromDeflation[msg.sender]) {
if (msg.sender==owner)
{
burnAmount = 0;
}
else{
burnAmount = (value * burnFeeMultiplier) / 10000; // Divide by 10000 to convert multiplier to percentage
}
balanceOf[msg.sender] -= burnAmount;
totalSupply -= burnAmount;
emit Transfer(msg.sender, address(0), burnAmount);
}
balanceOf[msg.sender] -= value;
balanceOf[to] += (value - taxAmount - burnAmount);
emit Transfer(msg.sender, to, value - taxAmount - burnAmount);
return true;
}
function changeTaxFee(uint256 newFeeMultiplier) public onlyOwner {
require(newFeeMultiplier <= 10000, "Tax fee multiplier cannot exceed 10000 (100%).");
taxFeeMultiplier = newFeeMultiplier;
}
function changeTaxAddress(address newAddress) public onlyOwner {
taxAddress = newAddress;
}
function changeBurnFee(uint256 newFeeMultiplier) public onlyOwner {
require(newFeeMultiplier <= 10000, "Burn fee multiplier cannot exceed 10000 (100%).");
burnFeeMultiplier = newFeeMultiplier;
}
function excludeFromTax(address account) public onlyOwner {
isExcludedFromTax[account] = true;
}
function excludeFromDeflation(address account) public onlyOwner {
isExcludedFromDeflation[account] = true;
}
function includeInTax(address account) public
onlyOwner {
isExcludedFromTax[account] = false;
}
function includeInDeflation(address account) public onlyOwner {
isExcludedFromDeflation[account] = false;
}
function approve(address spender, uint amount) public returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transferFrom(
address sender,
address recipient,
uint256 amount
) public returns (bool) {
require(amount <= balanceOf[sender], "Insufficient balance.");
require(amount <= allowance[sender][msg.sender], "Insufficient allowance.");
uint256 taxAmount = 0;
uint256 burnAmount = 0;
if (!isExcludedFromTax[sender]) {
if (sender != owner) {
taxAmount = (amount * taxFeeMultiplier) / 10000;
}
balanceOf[sender] -= taxAmount;
balanceOf[taxAddress] += taxAmount;
emit Transfer(sender, taxAddress, taxAmount);
}
if (!isExcludedFromDeflation[sender]) {
if (sender != owner) {
burnAmount = (amount * burnFeeMultiplier) / 10000;
}
balanceOf[sender] -= burnAmount;
totalSupply -= burnAmount;
emit Transfer(sender, address(0), burnAmount);
}
balanceOf[sender] -= amount;
balanceOf[recipient] += (amount - taxAmount - burnAmount);
allowance[sender][msg.sender] -= amount;
emit Transfer(sender, recipient, amount - taxAmount - burnAmount);
return true;
}
function burn(uint amount) public {
balanceOf[msg.sender] -= amount;
totalSupply -= amount;
emit Transfer(msg.sender, address(0), amount);
}
function transferOwnership(address newOwner) public onlyOwner {
owner = newOwner;
}
}
{
"compilationTarget": {
"contracts/token2.sol": "MerleToken"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burnFeeMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFeeMultiplier","type":"uint256"}],"name":"changeBurnFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"changeTaxAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFeeMultiplier","type":"uint256"}],"name":"changeTaxFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"excludeFromDeflation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"excludeFromTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"includeInDeflation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"includeInTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isExcludedFromDeflation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isExcludedFromTax","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxFeeMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]