// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PausableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20FlashMintUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
contract BlackNaga is
Initializable,
ERC20BurnableUpgradeable,
ERC20PausableUpgradeable,
OwnableUpgradeable,
ERC20PermitUpgradeable,
ERC20VotesUpgradeable,
ERC20FlashMintUpgradeable
{
// Mapping to store nonces for permit function
mapping(address => uint256) public nonces;
// Addresses for tokenomics and limits
address public constant BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD;
address public marketingDevAddress;
address public reflectionAddress;
address public teamDevelopmentAddress;
address public charityAddress;
// Tokenomics parameters
uint256 public burnPercent;
uint256 public marketingDevFeePercent;
uint256 public reflectionFeePercent;
uint256 public charityFeePercent;
uint256 public teamDevelopmentFeePercent;
// Limits and balances
uint256 public maxTransactionAmount;
uint256 public maxBurnAmount;
uint256 public maxWalletBalance;
// Events
event MaxTransactionAmountChanged(uint256 newMaxTransactionAmount);
event MaxWalletBalanceChanged(uint256 newMaxWalletBalance);
/**
* @dev Constructor function to disable initializers and setup the BlackNaga token.
*/
constructor() {
_disableInitializers();
}
/**
* @dev Initializes the contract with initial parameters and sets the token name and symbol.
* @param initialOwner The initial owner of the contract.
*/
function initialize(address initialOwner) external initializer {
__ERC20Burnable_init();
__ERC20Pausable_init();
__Ownable_init(initialOwner);
__ERC20Permit_init("BlackNaga");
__ERC20Votes_init();
__ERC20FlashMint_init();
string memory name = "BlackNaga";
string memory symbol = "BLNA";
uint256 initialSupply = 400_000_000_000_000_000_000_000; // 400 sextillion tokens with 18 decimals
uint256 tokensToBurn = initialSupply / 2; // Burn 50% of the initial supply
_mint(initialOwner, initialSupply); // Mint initial supply to the deployer
_burn(initialOwner, tokensToBurn); // Burn tokens immediately
// Set initial values for tokenomics
burnPercent = 5;
marketingDevFeePercent = 2;
reflectionFeePercent = 2;
charityFeePercent = 1;
teamDevelopmentFeePercent = 2;
// Set initial limits and balances
maxTransactionAmount = initialSupply / 100; // 1% of total supply
maxBurnAmount = 200_000_000_000_000_000_000_000; // 200 sextillion tokens
maxWalletBalance = initialSupply; // 100% of total supply
// Initialize fee addresses
marketingDevAddress = 0xfeB4660C633beE5ecE0955e3330B4619923B6d7C;
reflectionAddress = 0x81B6777039559c7396938ED17Ba39e71cE740cE7;
teamDevelopmentAddress = 0x10a0FF128b37176277EC259E2CC469cD3cd10276;
charityAddress = 0xD1b3A8E763d6c36d57BF9696a8595402BD54120E;
// Ensure addresses are set correctly
require(marketingDevAddress != address(0), "Invalid marketingDevAddress");
require(reflectionAddress != address(0), "Invalid reflectionAddress");
require(teamDevelopmentAddress != address(0), "Invalid teamDevelopmentAddress");
require(charityAddress != address(0), "Invalid charityAddress");
transferOwnership(initialOwner);
}
/**
* @dev Sets the maximum transaction amount allowed.
* @param amount The new maximum transaction amount.
*/
function setMaxTransactionAmount(uint256 amount) external onlyOwner {
require(amount > 0, "Max transaction amount must be greater than zero");
maxTransactionAmount = amount;
emit MaxTransactionAmountChanged(amount);
}
/**
* @dev Sets the maximum wallet balance allowed.
* @param balance The new maximum wallet balance.
*/
function setMaxWalletBalance(uint256 balance) external onlyOwner {
require(balance > 0, "Max wallet balance must be greater than zero");
maxWalletBalance = balance;
emit MaxWalletBalanceChanged(balance);
}
/**
* @dev Transfers ownership of the contract.
* @param newOwner The address of the new owner.
*/
function transferOwnership(address newOwner) public override onlyOwner {
require(newOwner != address(0), "New owner is the zero address");
emit OwnershipTransferred(owner(), newOwner);
_transferOwnership(newOwner);
}
/**
* @dev Transfers tokens from sender to recipient with specific logic for fees and burning.
* @param sender The address sending the tokens.
* @param recipient The address receiving the tokens.
* @param amount The amount of tokens to transfer.
*/
function _customTransfer(
address sender,
address recipient,
uint256 amount
) internal {
require(sender != address(0), "Transfer from the zero address");
require(recipient != address(0), "Transfer to the zero address");
require(amount > 0, "Transfer amount must be greater than zero");
require(
amount <= maxTransactionAmount,
"Transfer amount exceeds the max transaction limit"
);
require(
recipient.code.length == 0,
"Transfer to a contract address is not allowed"
);
uint256 senderBalance = balanceOf(sender);
require(senderBalance >= amount, "Transfer amount exceeds balance");
if (sender != owner() && recipient != owner()) {
require(
balanceOf(recipient) + amount <= maxWalletBalance,
"Transfer amount exceeds the max wallet balance"
);
}
uint256 burnAmount = (amount * burnPercent) / 100;
uint256 marketingDevFee = (amount * marketingDevFeePercent) / 100;
uint256 reflectionFee = (amount * reflectionFeePercent) / 100;
uint256 charityFee = (amount * charityFeePercent) / 100;
uint256 teamDevelopmentFee = (amount * teamDevelopmentFeePercent) / 100;
uint256 transferAmount = amount -
(burnAmount +
marketingDevFee +
reflectionFee +
charityFee +
teamDevelopmentFee);
unchecked {
_transfer(sender, recipient, transferAmount);
_transfer(sender, BURN_ADDRESS, burnAmount);
_transfer(sender, marketingDevAddress, marketingDevFee);
_transfer(sender, reflectionAddress, reflectionFee);
_transfer(sender, charityAddress, charityFee);
_transfer(sender, teamDevelopmentAddress, teamDevelopmentFee);
}
}
// Additional functions and events as needed...
}