Sonic Blaze Testnet

Contract Diff Checker

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.");
    }
}

Please enter a contract address above to load the contract details and source code.

Context size (optional):