Contract Name:
TokenPresale
Contract Source Code:
File 1 of 1 : TokenPresale
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IERC20 {
function transfer(address recipient, uint256 amount) external returns (bool);
function balanceOf(address account) external view returns (uint256);
}
contract TokenPresale {
IERC20 public token;
address public owner;
uint256 public phase1EndTime;
uint256 public phase2EndTime;
uint256 public tokenPricePhase1 = 0.01 ether;
uint256 public tokenPricePhase2 = 0.02 ether;
uint256 public tokensForPhase1;
uint256 public tokensForPhase2;
uint256 public soldTokensPhase1 = 0;
uint256 public soldTokensPhase2 = 0;
uint256 public maxTokensPerWallet = 1000;
bool public presaleActive = false;
mapping(address => uint256) public purchasedTokens;
mapping(address => bool) public whitelist; // وایتلیست
uint256 public whitelistCount = 0; // شمارش تعداد کیف پولها در وایتلیست
event PresaleStarted(uint256 startTime, uint256 phase1EndTime, uint256 phase2EndTime);
event TokensPurchased(address buyer, uint256 amount, uint256 totalPrice);
event TokensWithdrawn(address buyer, uint256 amount);
event WhitelistUpdated(address wallet, bool status); // رویداد برای تغییرات وایتلیست
modifier onlyOwner() {
require(msg.sender == owner, "Only owner can call this function.");
_;
}
modifier presaleOngoing() {
require(presaleActive, "Presale is not active.");
require(block.timestamp <= phase2EndTime, "Presale has ended.");
_;
}
constructor(IERC20 _token) {
token = _token;
owner = msg.sender;
tokensForPhase1 = 400_000_000; // 40% of total supply
tokensForPhase2 = 600_000_000; // 60% of total supply
}
function startPresale() external onlyOwner {
require(!presaleActive, "Presale already active.");
presaleActive = true;
phase1EndTime = block.timestamp + 30 days;
phase2EndTime = phase1EndTime + 14 days;
emit PresaleStarted(block.timestamp, phase1EndTime, phase2EndTime);
}
function getCurrentPrice() public view returns (uint256) {
if (block.timestamp <= phase1EndTime) {
return tokenPricePhase1;
} else {
return tokenPricePhase2;
}
}
function buyTokens(uint256 amount) external payable presaleOngoing {
uint256 currentPrice = getCurrentPrice();
uint256 totalPrice = amount * currentPrice;
require(msg.value >= totalPrice, "Insufficient funds.");
require(purchasedTokens[msg.sender] + amount <= maxTokensPerWallet, "Exceeds max tokens per wallet.");
if (block.timestamp <= phase1EndTime) {
require(tokensForPhase1 >= amount, "Not enough tokens available in Phase 1.");
tokensForPhase1 -= amount;
soldTokensPhase1 += amount;
} else {
require(tokensForPhase2 >= amount, "Not enough tokens available in Phase 2.");
tokensForPhase2 -= amount;
soldTokensPhase2 += amount;
}
uint256 excess = msg.value - totalPrice;
if (excess > 0) {
payable(msg.sender).transfer(excess);
}
purchasedTokens[msg.sender] += amount;
// اضافه کردن کاربر به وایتلیست
if (!whitelist[msg.sender]) {
whitelist[msg.sender] = true;
whitelistCount++; // افزایش تعداد کیف پولهای وایتلیست
emit WhitelistUpdated(msg.sender, true);
}
emit TokensPurchased(msg.sender, amount, totalPrice);
}
function withdrawTokens() external {
require(!presaleActive, "Presale must end before withdrawing tokens.");
uint256 amount = purchasedTokens[msg.sender];
require(amount > 0, "No tokens to withdraw.");
purchasedTokens[msg.sender] = 0;
require(token.transfer(msg.sender, amount), "Token transfer failed.");
emit TokensWithdrawn(msg.sender, amount);
}
function endPresale() external onlyOwner {
presaleActive = false;
}
function setMaxTokensPerWallet(uint256 _maxTokens) external onlyOwner {
maxTokensPerWallet = _maxTokens;
}
function setTokenPrice(uint256 _pricePhase1, uint256 _pricePhase2) external onlyOwner {
require(_pricePhase1 > 0 && _pricePhase2 > 0, "Price must be greater than 0.");
tokenPricePhase1 = _pricePhase1;
tokenPricePhase2 = _pricePhase2;
}
function withdrawFunds() external onlyOwner {
payable(owner).transfer(address(this).balance);
}
// توابع مرتبط با وایتلیست
function isWhitelisted(address wallet) public view returns (bool) {
return whitelist[wallet];
}
function getWhitelistCount() public view returns (uint256) {
return whitelistCount; // تعداد کیف پولهای وایتلیست
}
function grantSpecialRewards(address wallet, uint256 rewardAmount) external onlyOwner {
require(whitelist[wallet], "Address not in whitelist.");
require(token.transfer(wallet, rewardAmount), "Token transfer failed.");
}
}