PedroCoinPresale

Description:

ERC20 token contract with Factory capabilities. Standard implementation for fungible tokens on Ethereum.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

/**
 *Submitted for verification at Etherscan.io on 2025-09-20
*/

/**
 *Submitted for verification at Etherscan.io on 2025-08-29
*/

//SPDX-License-Identifier: MIT Licensed
pragma solidity ^0.8.18;
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }
    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}
contract Ownable is Context {
    address private _owner;
    event OwnershipTransferred(
        address indexed previousOwner,
        address indexed newOwner
    );
    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }
    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }
    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }
    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(
            newOwner != address(0),
            "Ownable: new owner is the zero address"
        );
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}
interface IERC20 {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view returns (uint8);
    function totalSupply() external view returns (uint256);
    function balanceOf(address owner) external view returns (uint256);
    function allowance(address owner, address spender)
        external
        view
        returns (uint256);
    function approve(address spender, uint256 value) external;
    function transfer(address to, uint256 value) external;
    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external;
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
    event Transfer(address indexed from, address indexed to, uint256 value);
}
interface AggregatorV3Interface {
    function decimals() external view returns (uint8);
    function description() external view returns (string memory);
    function version() external view returns (uint256);
    function getRoundData(uint80 _roundId)
        external
        view
        returns (
            uint80 roundId,
            int256 answer,
            uint256 startedAt,
            uint256 updatedAt,
            uint80 answeredInRound
        );
    function latestRoundData()
        external
        view
        returns (
            uint80 roundId,
            int256 answer,
            uint256 startedAt,
            uint256 updatedAt,
            uint80 answeredInRound
        );
}
contract PedroCoinPresale is Ownable {
    IERC20 public mainToken;
    IERC20 public USDT = IERC20(0xdAC17F958D2ee523a2206206994597C13D831ec7);
    AggregatorV3Interface public priceFeed;
    struct Phase {
        uint256 tokensToSell;
        uint256 totalSoldTokens;
        uint256 tokenPerUsdPrice;
    }
    mapping(uint256 => Phase) public phases;
    // Stats
    uint256 public refPercent = 50;
    uint256 public totalStages;
    uint256 public currentStage;
    uint256 public soldToken;
    uint256 public amountRaised;
    uint256 public amountRaisedUSDT;
    uint256 public amountRaisedUSDC;
    uint256 public amountRaisedOverall;
    uint256 public uniqueBuyers;
    uint256[] public tokenPerUsdPrice = [
        13333333333333333333333,
        8888888888888888888888,
        6666666666666666666666,
        5333333333333333333333,
        4444444444444444444444,
        3809523809523809523809,
        3333333333333333333333,
        2962962962962962962962,
        2666666666666666666666,
        2424242424242424242424,
        2222222222222222222222,
        2051282051282051282051,
        1904761904761904761904,
        1777777777777777777777,
        1666666666666666666666,
        1568627450980392156862,
        1481481481481481481481,
        1403508771929824561403,
        1333333333333333333333,
        1111111111111111111111,
        888888888888888888888,
        666666666666666666666
    ];
    uint256[] public tokensToSell = [
        350_000_000 * 10**18,
        350_000_000 * 10**18,
        350_000_000 * 10**18,
        350_000_000 * 10**18,
        700_000_000 * 10**18,
        700_000_000 * 10**18,
        1_000_000_000 * 10**18,
        1_000_000_000 * 10**18,
        1_750_000_000 * 10**18,
        1_750_000_000 * 10**18,
        2_250_000_000 * 10**18,
        2_250_000_000 * 10**18,
        2_750_000_000 * 10**18,
        2_750_000_000 * 10**18,
        3_500_000_000 * 10**18,
        3_500_000_000 * 10**18,
        4_000_000_000 * 10**18,
        6_500_000_000 * 10**18,
        8_000_000_000 * 10**18,
        9_700_000_000 * 10**18,
        10_000_000_000 * 10**18,
        10_000_000_000 * 10**18

    ];
    address payable public fundReceiver;
    bool public presaleStatus;
    bool public isPresaleEnded;
    uint256 public claimStartTime;
    address[] public UsersAddresses;
    struct User {
        uint256 eth_invested;
        uint256 usdt_invested;
        uint256 tokens_purchased;
        uint256 ref_reward;
        uint256 total_claimable;
        uint256 tokens_claimed;
    }
    struct TopBuyer {
        address buyerAddress;
        uint256 tokenAmount;
    }
    TopBuyer[15] public topBuyersData;
    mapping(address => User) public users;
    mapping(address => bool) public isExist;
    event BuyTokenETh(
        address indexed _user,
        uint256 buyingAmount,
        uint256 indexed _tokenamount
    );
    event BuyTokenUSDT(
        address indexed _user,
        uint256 buyingAmount,
        uint256 indexed _tokenamount
    );
    event ClaimToken(address indexed _user, uint256 indexed _amount);
    constructor(IERC20 _token, address _fundReceiver) {
        mainToken = _token;
        fundReceiver = payable(_fundReceiver);
        priceFeed = AggregatorV3Interface(
            0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419
        );
        for (uint256 i = 0; i < tokensToSell.length; i++) {
            phases[i].tokensToSell = tokensToSell[i];
            phases[i].tokenPerUsdPrice = tokenPerUsdPrice[i];
        }
        totalStages = tokensToSell.length;
    }
    // update a presale
    function updatePresale(
        uint256 _phaseId,
        uint256 _tokensToSell,
        uint256 _tokenPerUsdPrice
    ) public onlyOwner {
        require(phases[_phaseId].tokensToSell > 0, "presale don't exist");
        phases[_phaseId].tokensToSell = _tokensToSell;
        phases[_phaseId].tokenPerUsdPrice = _tokenPerUsdPrice;
    }
    // to get real time price of Eth
    function getLatestPrice() public view returns (uint256) {
        (, int256 price, , , ) = priceFeed.latestRoundData();
        return uint256(price);
    }
    // to buy token during preSale time with Eth => for web3 use
    function buyToken(address _referral) public payable {
        require(!isPresaleEnded, "Presale ended!");
        require(presaleStatus, " Presale is Paused, check back later");
        if (!isExist[msg.sender]) {
            isExist[msg.sender] = true;
            uniqueBuyers++;
            UsersAddresses.push(msg.sender);
        }
        fundReceiver.transfer(msg.value);
        uint256 numberOfTokens;
        numberOfTokens = nativeToToken(msg.value, currentStage);
        uint256 refReward;
        if (_referral != address(0) && _referral != msg.sender) {
            refReward = ((numberOfTokens * refPercent) / 1000);
            users[_referral].ref_reward += refReward;
            users[_referral].total_claimable += refReward;
        }
        require(
            phases[currentStage].totalSoldTokens + numberOfTokens <=
                phases[currentStage].tokensToSell,
            "Phase Limit Reached"
        );
        soldToken = soldToken + (numberOfTokens);
        amountRaised = amountRaised + (msg.value);
        amountRaisedOverall = amountRaisedOverall + nativeToUsd(msg.value);
        users[msg.sender].eth_invested += msg.value;
        users[msg.sender].tokens_purchased += numberOfTokens;
        users[msg.sender].total_claimable += numberOfTokens;
        phases[currentStage].totalSoldTokens += numberOfTokens;
        updateTopBuyerData(msg.sender, users[msg.sender].tokens_purchased);
        emit BuyTokenETh(msg.sender, msg.value, numberOfTokens);
    }
    // to buy token during preSale time with USDT => for web3 use
    function buyTokenUSDT(address _referral,uint256 amount) public {
        require(!isPresaleEnded, "Presale ended!");
        require(presaleStatus, " Presale is Paused, check back later");
        if (!isExist[msg.sender]) {
            isExist[msg.sender] = true;
            uniqueBuyers++;
            UsersAddresses.push(msg.sender);
        }
        USDT.transferFrom(msg.sender, fundReceiver, amount);
        uint256 numberOfTokens;
        numberOfTokens = usdtToToken(amount, currentStage);
        uint256 refReward;
        if (_referral != address(0) && _referral != msg.sender) {
            refReward = ((numberOfTokens * refPercent) / 1000);
            users[_referral].ref_reward += refReward;
            users[_referral].total_claimable += refReward;
        }
        require(
            phases[currentStage].totalSoldTokens + numberOfTokens <=
                phases[currentStage].tokensToSell,
            "Phase Limit Reached"
        );
        soldToken = soldToken + numberOfTokens;
        amountRaisedUSDT = amountRaisedUSDT + amount;
        amountRaisedOverall = amountRaisedOverall + amount;
        users[msg.sender].usdt_invested += amount;
        users[msg.sender].tokens_purchased += numberOfTokens;
        users[msg.sender].total_claimable += numberOfTokens;
        phases[currentStage].totalSoldTokens += numberOfTokens;
        updateTopBuyerData(msg.sender, users[msg.sender].tokens_purchased);
        emit BuyTokenUSDT(msg.sender, amount, numberOfTokens);
    } 
    function updateTopBuyerData(address _user, uint256 _tokenAmount) internal {
        for (uint256 i = 0; i < topBuyersData.length; i++) {
            if (_tokenAmount > topBuyersData[i].tokenAmount) {
                for (uint256 j = topBuyersData.length - 1; j > i; j--) {
                    topBuyersData[j] = topBuyersData[j - 1];
                }

                topBuyersData[i] = TopBuyer(_user, _tokenAmount);
                break;
            }
        }
    }
    function claimTokens() external {
        require(isPresaleEnded, "Presale has not ended yet");
        User storage user = users[msg.sender];
        require(user.total_claimable > 0, "No tokens purchased");
        uint256 claimableTokens = user.total_claimable - user.tokens_claimed;
        require(claimableTokens > 0, "No tokens to claim");
        user.tokens_claimed += claimableTokens;
        mainToken.transfer(msg.sender, claimableTokens);
        emit ClaimToken(msg.sender, claimableTokens);
    }
    function whitelistAddresses(
        address[] memory _addresses,
        uint256[] memory _tokenAmount
    ) external onlyOwner {
        require(
            _addresses.length == _tokenAmount.length,
            "Addresses and amounts must be equal"
        );

        for (uint256 i = 0; i < _addresses.length; i++) {
            users[_addresses[i]].total_claimable += _tokenAmount[i];
        }
    }
    function getPhaseDetail(uint256 phaseInd)
        external
        view
        returns (
            uint256 tokenToSell,
            uint256 soldTokens,
            uint256 priceUsd
        )
    {
        Phase memory phase = phases[phaseInd];
        return (
            phase.tokensToSell,
            phase.totalSoldTokens,
            phase.tokenPerUsdPrice
        );
    }
    function setPresaleStatus(bool _status) external onlyOwner {
        presaleStatus = _status;
    }
    function endPresale() external onlyOwner {
        isPresaleEnded = true;
        claimStartTime = block.timestamp;
    }
    // to check number of token for given Eth
    function nativeToToken(uint256 _amount, uint256 phaseId)
        public
        view
        returns (uint256)
    {
        uint256 ethToUsd = (_amount * (getLatestPrice())) / (1 ether);
        uint256 numberOfTokens = (ethToUsd * phases[phaseId].tokenPerUsdPrice) /
            (1e8);
        return numberOfTokens;
    }
    // to check number of token for given usdt
    function usdtToToken(uint256 _amount, uint256 phaseId)
        public
        view
        returns (uint256)
    {
        uint256 numberOfTokens = (_amount * phases[phaseId].tokenPerUsdPrice) /
            (1e6);
        return numberOfTokens;
    }
    // Eth to USD
    function nativeToUsd(uint256 _amount) public view returns (uint256) {
        uint256 nativeTousd = (_amount * (getLatestPrice())) / (1e20);
        return nativeTousd;
    }
    // change tokens
    function updateToken(address _token) external onlyOwner {
        mainToken = IERC20(_token);
    }
    // to withdraw funds for liquidity
    function initiateTransfer(uint256 _value) external onlyOwner {
        fundReceiver.transfer(_value);
    }
    // to withdraw funds for liquidity
    function changeFundReciever(address _addr) external onlyOwner {
        fundReceiver = payable(_addr);
    }
    // funtion is used to change the stage of presale
    function changeRefPercentage(uint256 _refPercent) public onlyOwner {
        refPercent = _refPercent;
    }
        // funtion is used to change the stage of presale
    function setCurrentStage(uint256 _stageNum) public onlyOwner {
        currentStage = _stageNum;
    }
    // to withdraw out tokens
    function transferTokens(IERC20 token, uint256 _value) external onlyOwner {
        token.transfer(msg.sender, _value);
    }
    function totalUsersCount() external view returns (uint256) {
        return UsersAddresses.length;
    }
}

Tags:
ERC20, Token, Factory|addr:0xdc6b81f8839ead03fd835bede4fb4904d2da2c7b|verified:true|block:23413582|tx:0x324da09aaea4ed52d49e5143e9a0af6a78d879ecad1df27736456c9dcf692481|first_check:1758531495

Submitted on: 2025-09-22 10:58:15

Comments

Log in to comment.

No comments yet.