LILPENGU_Presale_Source

Description:

Proxy contract enabling upgradeable smart contract patterns. Delegates calls to an implementation contract.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "contracts/PreSale/PreSaleSource.sol": {
      "content": "//SPDX-License-Identifier: MIT\r
pragma solidity ^0.8.20;\r
\r
abstract contract ReentrancyGuard {\r
    uint256 private constant _NOT_ENTERED = 1;\r
    uint256 private constant _ENTERED = 2;\r
\r
    uint256 private _status;\r
\r
    constructor() {\r
        _status = _NOT_ENTERED;\r
    }\r
\r
    modifier nonReentrant() {\r
        _nonReentrantBefore();\r
        _;\r
        _nonReentrantAfter();\r
    }\r
\r
    function _nonReentrantBefore() private {\r
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");\r
\r
        _status = _ENTERED;\r
    }\r
\r
    function _nonReentrantAfter() private {\r
        _status = _NOT_ENTERED;\r
    }\r
}\r
\r
abstract contract Context {\r
    function _msgSender() internal view virtual returns (address) {\r
        return msg.sender;\r
    }\r
\r
    function _msgData() internal view virtual returns (bytes calldata) {\r
        return msg.data;\r
    }\r
}\r
\r
abstract contract Ownable is Context {\r
    address private _owner;\r
\r
    event OwnershipTransferred(\r
        address indexed previousOwner,\r
        address indexed newOwner\r
    );\r
\r
    constructor() {\r
        _transferOwnership(_msgSender());\r
    }\r
\r
    modifier onlyOwner() {\r
        _checkOwner();\r
        _;\r
    }\r
\r
    function owner() public view virtual returns (address) {\r
        return _owner;\r
    }\r
\r
    function _checkOwner() internal view virtual {\r
        require(owner() == _msgSender(), "Ownable: caller is not the owner");\r
    }\r
\r
    function renounceOwnership() public virtual onlyOwner {\r
        _transferOwnership(address(0));\r
    }\r
\r
    function transferOwnership(address newOwner) public virtual onlyOwner {\r
        require(\r
            newOwner != address(0),\r
            "Ownable: new owner is the zero address"\r
        );\r
        _transferOwnership(newOwner);\r
    }\r
\r
    function _transferOwnership(address newOwner) internal virtual {\r
        address oldOwner = _owner;\r
        _owner = newOwner;\r
        emit OwnershipTransferred(oldOwner, newOwner);\r
    }\r
}\r
\r
library Address {\r
    function isContract(address account) internal view returns (bool) {\r
        return account.code.length > 0;\r
    }\r
\r
    function sendValue(address payable recipient, uint256 amount) internal {\r
        require(\r
            address(this).balance >= amount,\r
            "Address: insufficient balance"\r
        );\r
\r
        (bool success, ) = recipient.call{value: amount}("");\r
        require(\r
            success,\r
            "Address: unable to send value, recipient may have reverted"\r
        );\r
    }\r
\r
    function functionCall(\r
        address target,\r
        bytes memory data\r
    ) internal returns (bytes memory) {\r
        return\r
            functionCallWithValue(\r
                target,\r
                data,\r
                0,\r
                "Address: low-level call failed"\r
            );\r
    }\r
\r
    function functionCall(\r
        address target,\r
        bytes memory data,\r
        string memory errorMessage\r
    ) internal returns (bytes memory) {\r
        return functionCallWithValue(target, data, 0, errorMessage);\r
    }\r
\r
    function functionCallWithValue(\r
        address target,\r
        bytes memory data,\r
        uint256 value\r
    ) internal returns (bytes memory) {\r
        return\r
            functionCallWithValue(\r
                target,\r
                data,\r
                value,\r
                "Address: low-level call with value failed"\r
            );\r
    }\r
\r
    function functionCallWithValue(\r
        address target,\r
        bytes memory data,\r
        uint256 value,\r
        string memory errorMessage\r
    ) internal returns (bytes memory) {\r
        require(\r
            address(this).balance >= value,\r
            "Address: insufficient balance for call"\r
        );\r
        (bool success, bytes memory returndata) = target.call{value: value}(\r
            data\r
        );\r
        return\r
            verifyCallResultFromTarget(\r
                target,\r
                success,\r
                returndata,\r
                errorMessage\r
            );\r
    }\r
\r
    function functionStaticCall(\r
        address target,\r
        bytes memory data\r
    ) internal view returns (bytes memory) {\r
        return\r
            functionStaticCall(\r
                target,\r
                data,\r
                "Address: low-level static call failed"\r
            );\r
    }\r
\r
    function functionStaticCall(\r
        address target,\r
        bytes memory data,\r
        string memory errorMessage\r
    ) internal view returns (bytes memory) {\r
        (bool success, bytes memory returndata) = target.staticcall(data);\r
        return\r
            verifyCallResultFromTarget(\r
                target,\r
                success,\r
                returndata,\r
                errorMessage\r
            );\r
    }\r
\r
    function functionDelegateCall(\r
        address target,\r
        bytes memory data\r
    ) internal returns (bytes memory) {\r
        return\r
            functionDelegateCall(\r
                target,\r
                data,\r
                "Address: low-level delegate call failed"\r
            );\r
    }\r
\r
    function functionDelegateCall(\r
        address target,\r
        bytes memory data,\r
        string memory errorMessage\r
    ) internal returns (bytes memory) {\r
        (bool success, bytes memory returndata) = target.delegatecall(data);\r
        return\r
            verifyCallResultFromTarget(\r
                target,\r
                success,\r
                returndata,\r
                errorMessage\r
            );\r
    }\r
\r
    function verifyCallResultFromTarget(\r
        address target,\r
        bool success,\r
        bytes memory returndata,\r
        string memory errorMessage\r
    ) internal view returns (bytes memory) {\r
        if (success) {\r
            if (returndata.length == 0) {\r
                require(isContract(target), "Address: call to non-contract");\r
            }\r
            return returndata;\r
        } else {\r
            _revert(returndata, errorMessage);\r
        }\r
    }\r
\r
    function verifyCallResult(\r
        bool success,\r
        bytes memory returndata,\r
        string memory errorMessage\r
    ) internal pure returns (bytes memory) {\r
        if (success) {\r
            return returndata;\r
        } else {\r
            _revert(returndata, errorMessage);\r
        }\r
    }\r
\r
    function _revert(\r
        bytes memory returndata,\r
        string memory errorMessage\r
    ) private pure {\r
        if (returndata.length > 0) {\r
            assembly {\r
                let returndata_size := mload(returndata)\r
                revert(add(32, returndata), returndata_size)\r
            }\r
        } else {\r
            revert(errorMessage);\r
        }\r
    }\r
}\r
\r
interface IERC20 {\r
    event Transfer(address indexed from, address indexed to, uint256 value);\r
\r
    event Approval(\r
        address indexed owner,\r
        address indexed spender,\r
        uint256 value\r
    );\r
\r
    function totalSupply() external view returns (uint256);\r
\r
    function balanceOf(address account) external view returns (uint256);\r
\r
    function transfer(address to, uint256 amount) external returns (bool);\r
\r
    function allowance(\r
        address owner,\r
        address spender\r
    ) external view returns (uint256);\r
\r
    function approve(address spender, uint256 amount) external returns (bool);\r
\r
    function transferFrom(\r
        address from,\r
        address to,\r
        uint256 amount\r
    ) external returns (bool);\r
}\r
\r
interface IERC20Metadata is IERC20 {\r
    function name() external view returns (string memory);\r
\r
    function symbol() external view returns (string memory);\r
\r
    function decimals() external view returns (uint8);\r
}\r
\r
interface Aggregator {\r
    function latestRoundData()\r
        external\r
        view\r
        returns (\r
            uint80 roundId,\r
            int256 answer,\r
            uint256 startedAt,\r
            uint256 updatedAt,\r
            uint80 answeredInRound\r
        );\r
}\r
\r
contract LILPENGU_Presale_Source is ReentrancyGuard, Ownable {\r
    uint256 public overalllRaised;\r
    uint256 public presaleId;\r
    uint256 public USDT_MULTIPLIER;\r
    uint256 public ETH_MULTIPLIER;\r
    address public fundReceiver;\r
    uint256 public uniqueBuyers;\r
    address[] private participantsList;\r
\r
    struct PresaleData {\r
        uint256 startTime;\r
        uint256 endTime;\r
        uint256 price;\r
        uint256 nextStagePrice;\r
        uint256 Sold;\r
        uint256 tokensToSell;\r
        uint256 UsdtHardcap;\r
        uint256 amountRaised;\r
        bool Active;\r
        bool isEnableClaim;\r
    }\r
\r
    struct VestingData {\r
        uint256 vestingStartTime;\r
        uint256 initialClaimPercent;\r
        uint256 vestingTime;\r
        uint256 vestingPercentage;\r
        uint256 totalClaimCycles;\r
    }\r
\r
    struct UserData {\r
        uint256 investedAmount;\r
        uint256 claimAt;\r
        uint256 claimAbleAmount;\r
        uint256 claimedVestingAmount;\r
        uint256 claimedAmount;\r
        uint256 claimCount;\r
        uint256 activePercentAmount;\r
    }\r
\r
    IERC20Metadata public USDTInterface;\r
    IERC20Metadata public USDCInterface;\r
    Aggregator internal aggregatorInterface;\r
\r
    mapping(uint256 => bool) public paused;\r
    mapping(uint256 => PresaleData) public presale;\r
    mapping(uint256 => VestingData) public vesting;\r
    mapping(address => mapping(uint256 => UserData)) public userClaimData;\r
    mapping(address => bool) public isExcludeMinToken;\r
    mapping(address => bool) public isBlackList;\r
    mapping(address => bool) public isExist;\r
    mapping(address => bool) private isInList;\r
\r
    uint256 public MinTokenTobuy;\r
    uint256 public currentSale;\r
    address public SaleToken;\r
\r
    event PresaleCreated(\r
        uint256 indexed _id,\r
        uint256 _totalTokens,\r
        uint256 _startTime,\r
        uint256 _endTime\r
    );\r
\r
    event PresaleUpdated(\r
        bytes32 indexed key,\r
        uint256 prevValue,\r
        uint256 newValue,\r
        uint256 timestamp\r
    );\r
\r
    event TokensBought(\r
        address indexed user,\r
        uint256 indexed id,\r
        address indexed purchaseToken,\r
        uint256 tokensBought,\r
        uint256 amountPaid,\r
        uint256 timestamp\r
    );\r
\r
    event TokensClaimed(\r
        address indexed user,\r
        uint256 indexed id,\r
        uint256 amount,\r
        uint256 timestamp\r
    );\r
\r
    event PresaleTokenAddressUpdated(\r
        address indexed prevValue,\r
        address indexed newValue,\r
        uint256 timestamp\r
    );\r
\r
    event PresalePaused(uint256 indexed id, uint256 timestamp);\r
    event PresaleUnpaused(uint256 indexed id, uint256 timestamp);\r
\r
    constructor(\r
        address _oracle,\r
        address _usdt,\r
        address _usdc,\r
        address _SaleToken,\r
        uint256 _MinTokenTobuy\r
    ) {\r
        aggregatorInterface = Aggregator(_oracle);\r
        SaleToken = _SaleToken;\r
        MinTokenTobuy = _MinTokenTobuy;\r
        USDTInterface = IERC20Metadata(_usdt);\r
        USDCInterface = IERC20Metadata(_usdc);\r
        ETH_MULTIPLIER = (10 ** 18);\r
        USDT_MULTIPLIER = (10 ** 6);\r
        fundReceiver = msg.sender;\r
    }\r
\r
    function createPresale(\r
        uint256 _price,\r
        uint256 _nextStagePrice,\r
        uint256 _tokensToSell,\r
        uint256 _UsdtHardcap\r
    ) external onlyOwner {\r
        require(_price > 0, "Zero price");\r
        require(_tokensToSell > 0, "Zero tokens to sell");\r
\r
        presaleId++;\r
\r
        presale[presaleId] = PresaleData(\r
            0,\r
            0,\r
            _price,\r
            _nextStagePrice,\r
            0,\r
            _tokensToSell,\r
            _UsdtHardcap,\r
            0,\r
            false,\r
            false\r
        );\r
\r
        emit PresaleCreated(presaleId, _tokensToSell, 0, 0);\r
    }\r
\r
    function setPresaleStage(uint256 _id) public onlyOwner {\r
        require(presale[_id].tokensToSell > 0, "Presale don't exist");\r
        if (currentSale != 0) {\r
            presale[currentSale].endTime = block.timestamp;\r
            presale[currentSale].Active = false;\r
        }\r
        presale[_id].startTime = block.timestamp;\r
        presale[_id].Active = true;\r
        currentSale = _id;\r
    }\r
\r
    function setPresaleVesting(\r
        uint256[] memory _id,\r
        uint256[] memory vestingStartTime,\r
        uint256[] memory _initialClaimPercent,\r
        uint256[] memory _vestingTime,\r
        uint256[] memory _vestingPercentage\r
    ) public onlyOwner {\r
        for (uint256 i = 0; i < _id.length; i++) {\r
            vesting[_id[i]] = VestingData(\r
                vestingStartTime[i],\r
                _initialClaimPercent[i],\r
                _vestingTime[i],\r
                _vestingPercentage[i],\r
                (1000 - _initialClaimPercent[i]) / _vestingPercentage[i]\r
            );\r
        }\r
    }\r
\r
    function updatePresaleVesting(\r
        uint256 _id,\r
        uint256 _vestingStartTime,\r
        uint256 _initialClaimPercent,\r
        uint256 _vestingTime,\r
        uint256 _vestingPercentage\r
    ) public onlyOwner {\r
        vesting[_id].vestingStartTime = _vestingStartTime;\r
        vesting[_id].initialClaimPercent = _initialClaimPercent;\r
        vesting[_id].vestingTime = _vestingTime;\r
        vesting[_id].vestingPercentage = _vestingPercentage;\r
        vesting[_id].totalClaimCycles =\r
            (100 - _initialClaimPercent) /\r
            _vestingPercentage;\r
    }\r
\r
    uint256 initialClaimPercent;\r
    uint256 vestingTime;\r
    uint256 vestingPercentage;\r
    uint256 totalClaimCycles;\r
\r
    function enableClaim(uint256 _id, bool _status) public onlyOwner {\r
        presale[_id].isEnableClaim = _status;\r
    }\r
\r
    function updatePresale(\r
        uint256 _id,\r
        uint256 _price,\r
        uint256 _nextStagePrice,\r
        uint256 _tokensToSell,\r
        uint256 _Hardcap,\r
        bool isclaimAble\r
    ) external onlyOwner {\r
        require(_price > 0, "Zero price");\r
        require(_tokensToSell > 0, "Zero tokens to sell");\r
        require(_Hardcap > 0, "Zero harcap");\r
        presale[_id].price = _price;\r
        presale[_id].nextStagePrice = _nextStagePrice;\r
        presale[_id].tokensToSell = _tokensToSell;\r
        presale[_id].UsdtHardcap = _Hardcap;\r
        presale[_id].isEnableClaim = isclaimAble;\r
    }\r
\r
    function changeFundWallet(address _wallet) external onlyOwner {\r
        require(_wallet != address(0), "Invalid parameters");\r
        fundReceiver = _wallet;\r
    }\r
\r
    function changeUSDTToken(address _newAddress) external onlyOwner {\r
        require(_newAddress != address(0), "Zero token address");\r
        USDTInterface = IERC20Metadata(_newAddress);\r
    }\r
\r
    function changeUSDCToken(address _newAddress) external onlyOwner {\r
        require(_newAddress != address(0), "Zero token address");\r
        USDCInterface = IERC20Metadata(_newAddress);\r
    }\r
\r
    function pausePresale(uint256 _id) external checkPresaleId(_id) onlyOwner {\r
        require(!paused[_id], "Already paused");\r
        paused[_id] = true;\r
        emit PresalePaused(_id, block.timestamp);\r
    }\r
\r
    function unPausePresale(\r
        uint256 _id\r
    ) external checkPresaleId(_id) onlyOwner {\r
        require(paused[_id], "Not paused");\r
        paused[_id] = false;\r
        emit PresaleUnpaused(_id, block.timestamp);\r
    }\r
\r
    function getLatestPrice() public view returns (uint256) {\r
        (, int256 price, , , ) = aggregatorInterface.latestRoundData();\r
        price = (price * (10 ** 10));\r
        return uint256(price);\r
    }\r
\r
    modifier checkPresaleId(uint256 _id) {\r
        require(_id > 0 && _id == currentSale, "Invalid presale id");\r
        _;\r
    }\r
\r
    modifier checkSaleState(uint256 _id, uint256 amount) {\r
        require(presale[_id].Active == true, "preSAle not Active");\r
        require(\r
            amount > 0 &&\r
                amount <= presale[_id].tokensToSell - presale[_id].Sold,\r
            "Invalid sale amount"\r
        );\r
        _;\r
    }\r
\r
    function ExcludeAccouctFromMinBuy(\r
        address _user,\r
        bool _status\r
    ) external onlyOwner {\r
        isExcludeMinToken[_user] = _status;\r
    }\r
\r
    function buyWithUSDT(\r
        uint256 usdAmount\r
    )\r
        external\r
        checkPresaleId(currentSale)\r
        checkSaleState(currentSale, usdtToTokens(currentSale, usdAmount))\r
        nonReentrant\r
        returns (bool)\r
    {\r
        require(!paused[currentSale], "Presale paused");\r
        require(\r
            presale[currentSale].Active == true,\r
            "Presale is not active yet"\r
        );\r
        require(!isBlackList[msg.sender], "Account is blackListed");\r
        require(\r
            presale[currentSale].amountRaised + usdAmount <=\r
                presale[currentSale].UsdtHardcap,\r
            "Amount should be less than leftHardcap"\r
        );\r
        if (!isExist[msg.sender]) {\r
            isExist[msg.sender] = true;\r
            uniqueBuyers++;\r
\r
            if (!isInList[msg.sender]) {\r
                participantsList.push(msg.sender);\r
                isInList[msg.sender] = true;\r
            }\r
        }\r
        uint256 tokens = usdtToTokens(currentSale, usdAmount);\r
        presale[currentSale].Sold += tokens;\r
        presale[currentSale].amountRaised += usdAmount;\r
        overalllRaised += usdAmount;\r
\r
        if (isExcludeMinToken[msg.sender] == false) {\r
            require(tokens >= MinTokenTobuy, "Less than min amount");\r
        }\r
        if (userClaimData[_msgSender()][currentSale].claimAbleAmount > 0) {\r
            userClaimData[_msgSender()][currentSale].claimAbleAmount += tokens;\r
            userClaimData[_msgSender()][currentSale]\r
                .investedAmount += usdAmount;\r
        } else {\r
            userClaimData[_msgSender()][currentSale] = UserData(\r
                usdAmount,\r
                0,\r
                tokens,\r
                0,\r
                0,\r
                0,\r
                0\r
            );\r
        }\r
\r
        uint256 ourAllowance = USDTInterface.allowance(\r
            _msgSender(),\r
            address(this)\r
        );\r
        require(usdAmount <= ourAllowance, "Make sure to add enough allowance");\r
        (bool success, ) = address(USDTInterface).call(\r
            abi.encodeWithSignature(\r
                "transferFrom(address,address,uint256)",\r
                _msgSender(),\r
                fundReceiver,\r
                usdAmount\r
            )\r
        );\r
        require(success, "Token payment failed");\r
        emit TokensBought(\r
            _msgSender(),\r
            currentSale,\r
            address(USDTInterface),\r
            tokens,\r
            usdAmount,\r
            block.timestamp\r
        );\r
        return true;\r
    }\r
\r
    function changeClaimAddress(\r
        address _oldAddress,\r
        address _newWallet\r
    ) public onlyOwner {\r
        for (uint256 i = 1; i < presaleId; i++) {\r
            require(isExist[_oldAddress], "User not a participant");\r
            userClaimData[_newWallet][i].claimAbleAmount = userClaimData[\r
                _oldAddress\r
            ][i].claimAbleAmount;\r
            userClaimData[_oldAddress][i].claimAbleAmount = 0;\r
        }\r
        isExist[_oldAddress] = false;\r
        isExist[_newWallet] = true;\r
    }\r
\r
    function blackListUser(address _user, bool _value) public onlyOwner {\r
        isBlackList[_user] = _value;\r
    }\r
\r
    function buyWithUSDC(\r
        uint256 usdcAmount\r
    )\r
        external\r
        checkPresaleId(currentSale)\r
        checkSaleState(currentSale, usdtToTokens(currentSale, usdcAmount))\r
        nonReentrant\r
        returns (bool)\r
    {\r
        require(!paused[currentSale], "Presale paused");\r
        require(\r
            presale[currentSale].Active == true,\r
            "Presale is not active yet"\r
        );\r
        require(\r
            presale[currentSale].amountRaised + usdcAmount <=\r
                presale[currentSale].UsdtHardcap,\r
            "Amount should be less than leftHardcap"\r
        );\r
        require(!isBlackList[msg.sender], "Account is blackListed");\r
        if (!isExist[msg.sender]) {\r
            isExist[msg.sender] = true;\r
            uniqueBuyers++;\r
        }\r
        uint256 tokens = usdtToTokens(currentSale, usdcAmount);\r
        presale[currentSale].Sold += tokens;\r
        presale[currentSale].amountRaised += usdcAmount;\r
        overalllRaised += usdcAmount;\r
\r
        if (isExcludeMinToken[msg.sender] == false) {\r
            require(tokens >= MinTokenTobuy, "Less than min amount");\r
        }\r
        if (userClaimData[_msgSender()][currentSale].claimAbleAmount > 0) {\r
            userClaimData[_msgSender()][currentSale].claimAbleAmount += tokens;\r
            userClaimData[_msgSender()][currentSale]\r
                .investedAmount += usdcAmount;\r
        } else {\r
            userClaimData[_msgSender()][currentSale] = UserData(\r
                usdcAmount,\r
                0,\r
                tokens,\r
                0,\r
                0,\r
                0,\r
                0\r
            );\r
            require(isExist[_msgSender()], "User not a participant");\r
        }\r
\r
        uint256 ourAllowance = USDTInterface.allowance(\r
            _msgSender(),\r
            address(this)\r
        );\r
        require(\r
            usdcAmount <= ourAllowance,\r
            "Make sure to add enough allowance"\r
        );\r
        (bool success, ) = address(USDCInterface).call(\r
            abi.encodeWithSignature(\r
                "transferFrom(address,address,uint256)",\r
                _msgSender(),\r
                fundReceiver,\r
                usdcAmount\r
            )\r
        );\r
        require(success, "Token payment failed");\r
        emit TokensBought(\r
            _msgSender(),\r
            currentSale,\r
            address(USDTInterface),\r
            tokens,\r
            usdcAmount,\r
            block.timestamp\r
        );\r
        return true;\r
    }\r
\r
    function buyWithEth()\r
        external\r
        payable\r
        checkPresaleId(currentSale)\r
        checkSaleState(currentSale, ethToTokens(currentSale, msg.value))\r
        nonReentrant\r
        returns (bool)\r
    {\r
        uint256 usdAmount = (msg.value * getLatestPrice() * USDT_MULTIPLIER) /\r
            (ETH_MULTIPLIER * ETH_MULTIPLIER);\r
        require(\r
            presale[currentSale].amountRaised + usdAmount <=\r
                presale[currentSale].UsdtHardcap,\r
            "Amount should be less than leftHardcap"\r
        );\r
        require(!isBlackList[msg.sender], "Account is blackListed");\r
        require(!paused[currentSale], "Presale paused");\r
        require(\r
            presale[currentSale].Active == true,\r
            "Presale is not active yet"\r
        );\r
        if (!isExist[msg.sender]) {\r
            isExist[msg.sender] = true;\r
            uniqueBuyers++;\r
        }\r
\r
        uint256 tokens = usdtToTokens(currentSale, usdAmount);\r
        if (isExcludeMinToken[msg.sender] == false) {\r
            require(tokens >= MinTokenTobuy, "Insufficient amount!");\r
        }\r
        presale[currentSale].Sold += tokens;\r
        presale[currentSale].amountRaised += usdAmount;\r
        overalllRaised += usdAmount;\r
\r
        if (userClaimData[_msgSender()][currentSale].claimAbleAmount > 0) {\r
            userClaimData[_msgSender()][currentSale].claimAbleAmount += tokens;\r
            userClaimData[_msgSender()][currentSale]\r
                .investedAmount += usdAmount;\r
        } else {\r
            userClaimData[_msgSender()][currentSale] = UserData(\r
                usdAmount,\r
                0, // Last claimed at\r
                tokens, // total tokens to be claimed\r
                0, // vesting claimed amount\r
                0, // claimed amount\r
                0, // claim count\r
                0 // vesting percent\r
            );\r
        }\r
\r
        sendValue(payable(fundReceiver), msg.value);\r
        emit TokensBought(\r
            _msgSender(),\r
            currentSale,\r
            address(0),\r
            tokens,\r
            msg.value,\r
            block.timestamp\r
        );\r
        return true;\r
    }\r
\r
    function ethBuyHelper(\r
        uint256 _id,\r
        uint256 amount\r
    ) external view returns (uint256 ethAmount) {\r
        uint256 usdPrice = (amount * presale[_id].price);\r
        ethAmount =\r
            (usdPrice * ETH_MULTIPLIER) /\r
            (getLatestPrice() * 10 ** IERC20Metadata(SaleToken).decimals());\r
    }\r
\r
    function usdtBuyHelper(\r
        uint256 _id,\r
        uint256 amount\r
    ) external view returns (uint256 usdPrice) {\r
        usdPrice =\r
            (amount * presale[_id].price) /\r
            10 ** IERC20Metadata(SaleToken).decimals();\r
    }\r
\r
    function ethToTokens(\r
        uint256 _id,\r
        uint256 amount\r
    ) public view returns (uint256 _tokens) {\r
        uint256 usdAmount = (amount * getLatestPrice() * USDT_MULTIPLIER) /\r
            (ETH_MULTIPLIER * ETH_MULTIPLIER);\r
        _tokens = usdtToTokens(_id, usdAmount);\r
    }\r
\r
    function usdtToTokens(\r
        uint256 _id,\r
        uint256 amount\r
    ) public view returns (uint256 _tokens) {\r
        _tokens = (amount * presale[_id].price) / USDT_MULTIPLIER;\r
    }\r
\r
    function sendValue(address payable recipient, uint256 amount) internal {\r
        require(address(this).balance >= amount, "Low balance");\r
        (bool success, ) = recipient.call{value: amount}("");\r
        require(success, "ETH Payment failed");\r
    }\r
\r
    function claimableAmount(\r
        address user,\r
        uint256 _id\r
    ) public view returns (uint256) {\r
        UserData memory _user = userClaimData[user][_id];\r
\r
        require(_user.claimAbleAmount > 0, "Nothing to claim");\r
        uint256 amount = _user.claimAbleAmount;\r
        require(amount > 0, "Already claimed");\r
        return amount;\r
    }\r
\r
    function claimMultiple() public {\r
        for (uint8 i = 1; i <= presaleId; i++) {\r
            if (\r
                userClaimData[msg.sender][i].claimAbleAmount > 0 &&\r
                block.timestamp > vesting[i].vestingStartTime\r
            ) {\r
                claim(msg.sender, i);\r
            }\r
        }\r
    }\r
\r
    function claimAmount(uint256 _id) public {\r
        claim(msg.sender, _id);\r
    }\r
\r
    function claim(address _user, uint256 _id) internal returns (bool) {\r
        require(isExist[_msgSender()], "User not a participant");\r
        uint256 amount = claimableAmount(_user, _id);\r
        require(amount > 0, "No claimable amount");\r
        require(!isBlackList[_user], "Account is blackListed");\r
        require(SaleToken != address(0), "Presale token address not set");\r
        require(\r
            amount <= IERC20(SaleToken).balanceOf(address(this)),\r
            "Not enough tokens in the contract"\r
        );\r
        require((presale[_id].isEnableClaim == true), "Claim is not enable");\r
        require(\r
            block.timestamp > vesting[_id].vestingStartTime,\r
            "Vesting time is not started yet"\r
        );\r
        uint256 transferAmount;\r
        if (userClaimData[_user][_id].claimCount == 0) {\r
            transferAmount =\r
                (amount * (vesting[_id].initialClaimPercent)) /\r
                1000;\r
            userClaimData[_user][_id].activePercentAmount =\r
                (amount * vesting[_id].vestingPercentage) /\r
                1000;\r
            bool status = IERC20(SaleToken).transfer(_user, transferAmount);\r
            require(status, "Token transfer failed");\r
            userClaimData[_user][_id].claimAbleAmount -= transferAmount;\r
            userClaimData[_user][_id].claimedAmount += transferAmount;\r
            userClaimData[_user][_id].claimCount++;\r
        } else if (\r
            userClaimData[_user][_id].claimAbleAmount >\r
            userClaimData[_user][_id].activePercentAmount\r
        ) {\r
            uint256 duration = block.timestamp - vesting[_id].vestingStartTime;\r
            uint256 multiplier = duration / vesting[_id].vestingTime;\r
            if (multiplier > vesting[_id].totalClaimCycles) {\r
                multiplier = vesting[_id].totalClaimCycles;\r
            }\r
            uint256 _amount = multiplier *\r
                userClaimData[_user][_id].activePercentAmount;\r
            transferAmount =\r
                _amount -\r
                userClaimData[_user][_id].claimedVestingAmount;\r
            require(transferAmount > 0, "Please wait till next claim");\r
            bool status = IERC20(SaleToken).transfer(_user, transferAmount);\r
            require(status, "Token transfer failed");\r
            userClaimData[_user][_id].claimAbleAmount -= transferAmount;\r
            userClaimData[_user][_id].claimedVestingAmount += transferAmount;\r
            userClaimData[_user][_id].claimedAmount += transferAmount;\r
            userClaimData[_user][_id].claimCount++;\r
        } else {\r
            uint256 duration = block.timestamp - vesting[_id].vestingStartTime;\r
            uint256 multiplier = duration / vesting[_id].vestingTime;\r
            if (multiplier > vesting[_id].totalClaimCycles + 1) {\r
                transferAmount = userClaimData[_user][_id].claimAbleAmount;\r
                require(transferAmount > 0, "Please wait till next claim");\r
                bool status = IERC20(SaleToken).transfer(_user, transferAmount);\r
                require(status, "Token transfer failed");\r
                userClaimData[_user][_id].claimAbleAmount -= transferAmount;\r
                userClaimData[_user][_id].claimedAmount += transferAmount;\r
                userClaimData[_user][_id]\r
                    .claimedVestingAmount += transferAmount;\r
                userClaimData[_user][_id].claimCount++;\r
            } else {\r
                revert("Wait for next claiim");\r
            }\r
        }\r
        return true;\r
    }\r
\r
    function WithdrawTokens(address _token, uint256 amount) external onlyOwner {\r
        IERC20(_token).transfer(fundReceiver, amount);\r
    }\r
\r
    function WithdrawContractFunds(uint256 amount) external onlyOwner {\r
        sendValue(payable(fundReceiver), amount);\r
    }\r
\r
    function ChangeTokenToSell(address _token) public onlyOwner {\r
        SaleToken = _token;\r
    }\r
\r
    function ChangeMinTokenToBuy(uint256 _amount) public onlyOwner {\r
        MinTokenTobuy = _amount;\r
    }\r
\r
    function ChangeOracleAddress(address _oracle) public onlyOwner {\r
        aggregatorInterface = Aggregator(_oracle);\r
    }\r
\r
    function blockTimeStamp() public view returns (uint256) {\r
        return block.timestamp;\r
    }\r
\r
    struct ExportUserData {\r
        address user;\r
        uint256 totalInvestedAmount;\r
        uint256 totalClaimableAmount;\r
    }\r
\r
    function getExportData(\r
        address[] memory _users\r
    ) external view onlyOwner returns (ExportUserData[] memory) {\r
        ExportUserData[] memory exportData = new ExportUserData[](\r
            _users.length\r
        );\r
\r
        for (uint256 i = 0; i < _users.length; i++) {\r
            address user = _users[i];\r
            uint256 totalInvested = 0;\r
            uint256 totalClaimable = 0;\r
\r
            // Sum across all presale stages\r
            for (uint256 j = 1; j <= presaleId; j++) {\r
                totalInvested += userClaimData[user][j].investedAmount;\r
                totalClaimable += userClaimData[user][j].claimAbleAmount;\r
            }\r
\r
            exportData[i] = ExportUserData({\r
                user: user,\r
                totalInvestedAmount: totalInvested,\r
                totalClaimableAmount: totalClaimable\r
            });\r
        }\r
\r
        return exportData;\r
    }\r
\r
    function getAllParticipants()\r
        external\r
        view\r
        onlyOwner\r
        returns (address[] memory)\r
    {\r
        return participantsList;\r
    }\r
\r
    function getUserSummary(\r
        address _user\r
    )\r
        external\r
        view\r
        returns (\r
            uint256 totalInvested,\r
            uint256 totalClaimable,\r
            uint256 stagesParticipated\r
        )\r
    {\r
        uint256 stages = 0;\r
\r
        for (uint256 i = 1; i <= presaleId; i++) {\r
            if (userClaimData[_user][i].claimAbleAmount > 0) {\r
                totalInvested += userClaimData[_user][i].investedAmount;\r
                totalClaimable += userClaimData[_user][i].claimAbleAmount;\r
                stages++;\r
            }\r
        }\r
\r
        return (totalInvested, totalClaimable, stages);\r
    }\r
}\r
"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": true,
      "runs": 1000
    },
    "evmVersion": "paris",
    "viaIR": true,
    "outputSelection": {
      "*": {
        "*": [
          "evm.bytecode",
          "evm.deployedBytecode",
          "devdoc",
          "userdoc",
          "metadata",
          "abi"
        ]
      }
    }
  }
}}

Tags:
ERC20, Proxy, Upgradeable, Factory|addr:0x3aaa141d0eb320d737a7af3847cc383ffd6ecef7|verified:true|block:23586968|tx:0x945dacbbc26a1988261df713e6bf6379c78dc41909a589b44d79505a10716c91|first_check:1760606285

Submitted on: 2025-10-16 11:18:08

Comments

Log in to comment.

No comments yet.