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:
{{
"language": "Solidity",
"sources": {
"contracts/Eth Presale.sol": {
"content": "//SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
}
function _nonReentrantAfter() private {
_status = _NOT_ENTERED;
}
}
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(
newOwner != address(0),
"Ownable: new owner is the zero address"
);
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
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 account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(
address owner,
address spender
) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
interface Aggregator {
function latestRoundData()
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
}
contract FRP_Presale is ReentrancyGuard, Ownable {
Aggregator internal aggregatorInterface;
address[] public allUsers;
address public fundReceiver;
address public refDistributor;
address public usdt;
uint256 public uniqueBuyers;
uint256 public overalllRaised;
uint256 public stageIdCount;
uint256 public currentStage;
uint256 public minTokenTobuy;
uint256 public minInvestRef;
uint256 public minClaimRef;
uint256 public usdMultiplier;
uint256 public ethMultiplier;
uint256 public tokenMultiplier;
uint256[9] public purchaseBonusAmount = [
150,
250,
500,
900,
1500,
2500,
5000,
10000,
100000
];
uint8[8] public purchaseBonusPercentage = [3, 4, 5, 6, 7, 8, 9, 10];
uint256[7] public refBonusAmount = [
100,
400,
1000,
2500,
5000,
10000,
100000
];
uint8[6] public refBonusPercentage = [3, 4, 5, 6, 7, 8];
struct PresaleData {
bool Active;
uint256 startTime;
uint256 endTime;
uint256 price;
uint256 nextStagePrice;
uint256 soldTokens;
uint256 tokensToSell;
uint256 usdHardcap;
uint256 amountRaisedUsd;
}
struct stageData {
uint256 investedAmount;
uint256 tokensBought;
}
struct PurchaseHistory {
string paymentToken;
uint256 investedUsd;
uint256 purchasedTokens;
uint256 bonusTokens;
}
struct UserData {
bool isExist;
address referrer;
uint256 purchaseCount;
uint256 totalInvestedUsd;
uint256 totalClaimableTokens;
uint256 purchasedTokens;
uint256 refBonusUsd;
uint256 ClaimedRefBonusUsd;
uint256 refBonusTokens;
uint256 purchaseBonusTokens;
address[] referrals;
}
mapping(address => UserData) public users;
mapping(address => mapping(uint256 => stageData)) public userStageData;
mapping(address => mapping(uint256 => PurchaseHistory)) public userHistory;
mapping(uint256 => PresaleData) public presale;
mapping(address => bool) public isPaymentToken;
mapping(uint256 => bool) public paused;
event TokensBought(
address indexed user,
uint256 indexed id,
address indexed purchaseToken,
uint256 tokensBought,
uint256 amountPaid,
uint256 timestamp
);
event PresaleTokenAddressUpdated(
address indexed prevValue,
address indexed newValue,
uint256 timestamp
);
event PresalePaused(uint256 indexed id, uint256 timestamp);
event PresaleUnpaused(uint256 indexed id, uint256 timestamp);
constructor() {
fundReceiver = 0x744412446Fa08D213FbFdDC5B3085e6caD8753Bd;
refDistributor = 0xA882D3bb9087140518EC67a75FEC68775AFdA25D;
usdt = 0xdAC17F958D2ee523a2206206994597C13D831ec7;
aggregatorInterface = Aggregator(
0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419 //0x694AA1769357215DE4FAC081bf1f309aDC325306 test
);
isPaymentToken[0xdAC17F958D2ee523a2206206994597C13D831ec7] = true;
isPaymentToken[0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48] = true;
isPaymentToken[0xc5f0f7b66764F6ec8C8Dff7BA683102295E16409] = true;
usdMultiplier = (10 ** 6);
tokenMultiplier = (10 ** 9);
ethMultiplier = (10 ** 18);
minTokenTobuy = (2000 * tokenMultiplier);
}
function createStage(
uint256 _price,
uint256 _nextStagePrice,
uint256 _tokensToSell,
uint256 _usdHardcap,
uint256 _startTime,
uint256 _endTime
) external onlyOwner {
require(_price > 0, "Zero price");
require(_tokensToSell > 0, "Zero tokens to sell");
stageIdCount++;
presale[stageIdCount] = PresaleData(
false,
_startTime,
_endTime,
_price,
_nextStagePrice,
0,
_tokensToSell,
_usdHardcap,
0
);
}
function setStage(uint256 _id) public onlyOwner {
require(presale[_id].tokensToSell > 0, "Presale don't exist");
if (currentStage != 0) {
presale[currentStage].endTime = block.timestamp;
presale[currentStage].Active = false;
}
presale[_id].startTime = block.timestamp;
presale[_id].Active = true;
currentStage = _id;
}
function updateStageData(
uint256 _id,
uint256 _price,
uint256 _nextStagePrice,
uint256 _tokensToSell,
uint256 _Hardcap,
uint256 _startTime,
uint256 _endTime
) external onlyOwner {
require(_price > 0, "Zero price");
require(_tokensToSell > 0, "Zero tokens to sell");
require(_Hardcap > 0, "Zero harcap");
presale[_id].price = _price;
presale[_id].nextStagePrice = _nextStagePrice;
presale[_id].tokensToSell = _tokensToSell;
presale[_id].usdHardcap = _Hardcap;
presale[_id].startTime = _startTime;
presale[_id].endTime = _endTime;
}
function changeFundWallet(address _wallet) external onlyOwner {
require(_wallet != address(0), "Invalid parameters");
fundReceiver = _wallet;
}
function changeRefWallet(address _wallet) external onlyOwner {
require(_wallet != address(0), "Invalid parameters");
refDistributor = _wallet;
}
function addPaymentToken(address _newAddress) external onlyOwner {
require(!isPaymentToken[_newAddress], "Already exist");
isPaymentToken[_newAddress] = true;
}
function removePaymentToken(address _newAddress) external onlyOwner {
require(isPaymentToken[_newAddress], "Not available");
isPaymentToken[_newAddress] = false;
}
function WithdrawTokens(address _token, uint256 amount) external onlyOwner {
IERC20(_token).transfer(fundReceiver, amount);
}
function WithdrawContractFunds(uint256 amount) external onlyOwner {
payable(fundReceiver).transfer(amount);
}
function ChangeMinTokenToBuy(uint256 _amount) public onlyOwner {
minTokenTobuy = _amount;
}
function ChangeOracleAddress(address _oracle) public onlyOwner {
aggregatorInterface = Aggregator(_oracle);
}
function ChangePurchaseBonusAmount(
uint256[9] memory _new
) public onlyOwner {
purchaseBonusAmount = _new;
}
function ChangePurchaseBonusPercent(uint8[8] memory _new) public onlyOwner {
purchaseBonusPercentage = _new;
}
function ChangeRefBonusAmount(uint256[7] memory _new) public onlyOwner {
refBonusAmount = _new;
}
function ChangeRefBonusPercent(uint8[6] memory _new) public onlyOwner {
refBonusPercentage = _new;
}
function ChangeRefValues(
uint256 _minInvest,
uint256 _minClaim
) public onlyOwner {
minInvestRef = _minInvest;
minClaimRef = _minClaim;
}
function pausePresale(uint256 _id) external checkPresaleId(_id) onlyOwner {
require(!paused[_id], "Already paused");
paused[_id] = true;
emit PresalePaused(_id, block.timestamp);
}
function unPausePresale(
uint256 _id
) external checkPresaleId(_id) onlyOwner {
require(paused[_id], "Not paused");
paused[_id] = false;
emit PresaleUnpaused(_id, block.timestamp);
}
function getLatestPrice() public view returns (uint256) {
(, int256 price, , , ) = aggregatorInterface.latestRoundData();
price = (price * (10 ** 10));
return uint256(price);
}
modifier checkPresaleId(uint256 _id) {
require(_id > 0 && _id == currentStage, "Invalid presale id");
_;
}
modifier checkSaleState(uint256 _id, uint256 amount) {
require(presale[_id].Active == true, "preSAle not Active");
require(
amount > 0 &&
amount <= presale[_id].tokensToSell - presale[_id].soldTokens,
"Invalid sale amount"
);
_;
}
function buyWithUsd(
address _referrer,
address _paymentToken,
uint256 usdAmount
)
external
checkPresaleId(currentStage)
checkSaleState(currentStage, usdtToTokens(currentStage, usdAmount))
nonReentrant
returns (bool)
{
require(isPaymentToken[_paymentToken], "Invalid payment token");
require(_referrer != _msgSender(), "Invalid referrer");
require(!paused[currentStage], "Presale paused");
require(
presale[currentStage].Active == true,
"Presale is not active yet"
);
require(
presale[currentStage].amountRaisedUsd + usdAmount <=
presale[currentStage].usdHardcap,
"Amount should be less than leftHardcap"
);
UserData storage user = users[_msgSender()];
if (
user.referrer == address(0) &&
users[_referrer].totalInvestedUsd >= minInvestRef
) {
user.referrer = _referrer;
}
if (!user.isExist) {
user.isExist = true;
allUsers.push(_msgSender());
if (user.referrer != address(0)) {
users[user.referrer].referrals.push(_msgSender());
}
uniqueBuyers++;
}
user.totalInvestedUsd += usdAmount;
uint256 tokens = usdtToTokens(currentStage, usdAmount);
user.purchasedTokens += tokens;
require(tokens >= minTokenTobuy, "Less than min amount");
uint256 refTokens;
if (usdAmount >= refBonusPercentage[0] && user.referrer != address(0)) {
uint256 refUsd = (usdAmount *
checkRefBonus(usdAmount / usdMultiplier)) / 100;
users[user.referrer].refBonusUsd += refUsd;
refTokens =
(tokens * checkRefBonus(usdAmount / usdMultiplier)) /
100;
user.refBonusTokens += refTokens;
}
uint256 bonusTokens = (tokens *
checkPurchaseBonus(usdAmount / usdMultiplier)) / 100;
if (bonusTokens > 0) {
user.purchaseBonusTokens += bonusTokens;
}
user.totalClaimableTokens += (tokens + bonusTokens + refTokens);
user.purchaseCount++;
presale[currentStage].soldTokens += tokens;
presale[currentStage].amountRaisedUsd += usdAmount;
overalllRaised += usdAmount;
userStageData[_msgSender()][currentStage].tokensBought += tokens;
userStageData[_msgSender()][currentStage].investedAmount += usdAmount;
userHistory[_msgSender()][user.purchaseCount] = PurchaseHistory(
IERC20(_paymentToken).symbol(),
usdAmount,
tokens,
bonusTokens
);
IERC20(_paymentToken).transferFrom(
_msgSender(),
fundReceiver,
usdAmount
);
emit TokensBought(
_msgSender(),
currentStage,
_paymentToken,
tokens,
usdAmount,
block.timestamp
);
return true;
}
function buyWithEth(
address _referrer
)
external
payable
checkPresaleId(currentStage)
checkSaleState(currentStage, ethToTokens(currentStage, msg.value))
nonReentrant
returns (bool)
{
require(_referrer != _msgSender(), "Invalid referrer");
uint256 usdAmount = (msg.value * getLatestPrice() * usdMultiplier) /
(ethMultiplier * ethMultiplier);
require(
presale[currentStage].amountRaisedUsd + usdAmount <=
presale[currentStage].usdHardcap,
"Amount should be less than leftHardcap"
);
require(!paused[currentStage], "Presale paused");
require(
presale[currentStage].Active == true,
"Presale is not active yet"
);
UserData storage user = users[_msgSender()];
if (user.referrer == address(0)) {
user.referrer = _referrer;
}
if (!user.isExist) {
user.isExist = true;
allUsers.push(_msgSender());
if (user.referrer != address(0)) {
users[user.referrer].referrals.push(_msgSender());
}
uniqueBuyers++;
}
user.totalInvestedUsd += usdAmount;
uint256 tokens = usdtToTokens(currentStage, usdAmount);
user.purchasedTokens += tokens;
require(tokens >= minTokenTobuy, "Insufficient amount!");
uint256 refTokens;
if (usdAmount >= refBonusPercentage[0] && user.referrer != address(0)) {
uint256 refUsd = (usdAmount *
checkRefBonus(usdAmount / usdMultiplier)) / 100;
users[user.referrer].refBonusUsd += refUsd;
refTokens =
(tokens * checkRefBonus(usdAmount / usdMultiplier)) /
100;
user.refBonusTokens += refTokens;
}
uint256 bonusTokens = (tokens *
checkPurchaseBonus(usdAmount / usdMultiplier)) / 100;
if (bonusTokens > 0) {
user.purchaseBonusTokens += bonusTokens;
}
user.totalClaimableTokens += (tokens + bonusTokens + refTokens);
user.purchaseCount++;
presale[currentStage].soldTokens += tokens;
presale[currentStage].amountRaisedUsd += usdAmount;
overalllRaised += usdAmount;
userStageData[_msgSender()][currentStage].tokensBought += tokens;
userStageData[_msgSender()][currentStage].investedAmount += usdAmount;
userHistory[_msgSender()][user.purchaseCount] = PurchaseHistory(
"ETH",
usdAmount,
tokens,
bonusTokens
);
payable(fundReceiver).transfer(msg.value);
emit TokensBought(
_msgSender(),
currentStage,
address(0),
tokens,
msg.value,
block.timestamp
);
return true;
}
function claimRefBonus() external nonReentrant {
UserData storage user = users[_msgSender()];
require(
user.refBonusUsd >= minClaimRef,
"Can't claim less than min amount"
);
IERC20(usdt).transferFrom(
refDistributor,
_msgSender(),
user.refBonusUsd
);
user.ClaimedRefBonusUsd += user.refBonusUsd;
user.refBonusUsd = 0;
}
function ethBuyHelper(
uint256 _id,
uint256 amount
) external view returns (uint256 ethAmount) {
uint256 usdPrice = (amount * presale[_id].price);
ethAmount =
(usdPrice * ethMultiplier) /
(getLatestPrice() * tokenMultiplier);
}
function ethToTokens(
uint256 _id,
uint256 amount
) public view returns (uint256 _tokens) {
uint256 usdAmount = (amount * getLatestPrice() * usdMultiplier) /
(ethMultiplier * ethMultiplier);
_tokens = usdtToTokens(_id, usdAmount);
}
function usdtBuyHelper(
uint256 _id,
uint256 amount
) external view returns (uint256 usdPrice) {
usdPrice = (amount * presale[_id].price) / tokenMultiplier;
}
function usdtToTokens(
uint256 _id,
uint256 amount
) public view returns (uint256 _tokens) {
_tokens = (amount * presale[_id].price) / usdMultiplier;
}
function checkPurchaseBonus(
uint256 _usdAmount
) public view returns (uint8 _percent) {
if (_usdAmount < purchaseBonusAmount[0]) return 0;
for (uint8 i = 0; i < refBonusPercentage.length; i++) {
if (
_usdAmount >= purchaseBonusAmount[i] &&
_usdAmount < purchaseBonusAmount[i + 1]
) {
_percent = refBonusPercentage[i];
}
}
}
function checkRefBonus(
uint256 _usdAmount
) public view returns (uint8 _percent) {
if (_usdAmount < refBonusAmount[0]) return 0;
for (uint8 i = 0; i <= refBonusPercentage.length; i++) {
if (
_usdAmount >= refBonusAmount[i] &&
_usdAmount < refBonusAmount[i + 1]
) {
_percent = refBonusPercentage[i];
}
}
}
function getUserAllReferrals(
address _user
) external view returns (address[] memory) {
return users[_user].referrals;
}
function getUserReferralsCount(
address _user
) external view returns (uint256) {
return users[_user].referrals.length;
}
function blockTimeStamp() public view returns (uint256) {
return block.timestamp;
}
}
"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 200
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}
}}
Submitted on: 2025-10-29 20:28:26
Comments
Log in to comment.
No comments yet.