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": {
"PresaleStake.sol": {
"content": "// SPDX-License-Identifier: MIT\r
pragma solidity ^0.8.0;\r
\r
interface IERC20 {\r
function totalSupply() external view returns (uint256);\r
function balanceOf(address account) external view returns (uint256);\r
function transfer(address recipient, uint256 amount) external returns (bool);\r
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\r
function allowance(address owner, address spender) external view returns (uint256);\r
function approve(address spender, uint256 amount) external returns (bool);\r
event Transfer(address indexed from, address indexed to, uint256 value);\r
event Approval(address indexed owner, address indexed spender, uint256 value);\r
}\r
\r
interface AggregatorV3Interface {\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
abstract contract Context {\r
function _msgSender() internal view virtual returns (address) {\r
return msg.sender;\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
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\r
constructor() {\r
_owner = _msgSender();\r
emit OwnershipTransferred(address(0), _owner);\r
}\r
function owner() public view virtual returns (address) {\r
return _owner;\r
}\r
modifier onlyOwner() {\r
require(owner() == _msgSender(), "Ownable: caller is not the owner");\r
_;\r
}\r
function renounceOwnership() public virtual onlyOwner {\r
emit OwnershipTransferred(_owner, address(0));\r
_owner = address(0);\r
}\r
function transferOwnership(address newOwner) public virtual onlyOwner {\r
require(newOwner != address(0), "Ownable: new owner is zero address");\r
emit OwnershipTransferred(_owner, newOwner);\r
_owner = newOwner;\r
}\r
}\r
\r
library SafeMath {\r
function add(uint256 a, uint256 b) internal pure returns (uint256) {\r
uint256 c = a + b;\r
require(c >= a, "SafeMath: addition overflow");\r
return c;\r
}\r
function sub(uint256 a, uint256 b) internal pure returns (uint256) {\r
require(b <= a, "SafeMath: subtraction overflow");\r
return a - b;\r
}\r
function mul(uint256 a, uint256 b) internal pure returns (uint256) {\r
if (a == 0) return 0;\r
uint256 c = a * b;\r
require(c / a == b, "SafeMath: multiplication overflow");\r
return c;\r
}\r
function div(uint256 a, uint256 b) internal pure returns (uint256) {\r
require(b > 0, "SafeMath: division by zero");\r
return a / b;\r
}\r
}\r
\r
/* Minimal interface to interact with the staking contract */\r
interface IStaking {\r
function stakeFor(address user, uint256 amount) external;\r
}\r
\r
contract TokenPreSale is Ownable {\r
using SafeMath for uint256;\r
\r
IERC20 public token;\r
IERC20 public usdt;\r
AggregatorV3Interface public priceFeed;\r
\r
address public treasuryWallet;\r
address public stakingContract; // new\r
\r
// Hard cap and soft cap (both in USD value, 18 decimals)\r
uint256 public constant HARD_CAP = 7_560_000 * 1e18; // $7,560,000\r
uint256 public constant SOFT_CAP = HARD_CAP / 100; // $75,600\r
\r
uint256 public totalETHRaised;\r
uint256 public totalUSDTRaised;\r
uint256 public totalSold;\r
\r
// Token price set to $0.000005 per token\r
uint256 public tokenPriceInUSDT = 0.000005 ether;\r
\r
bool public saleActive = true;\r
bool public claimEnabled = false;\r
\r
mapping(address => uint256) public pendingTokens;\r
\r
event Sell(address indexed buyer, uint256 tokenAmount, uint256 value, string paymentMethod);\r
event SellAndStake(address indexed buyer, uint256 tokenAmount, uint256 value, string paymentMethod);\r
event Withdraw(address indexed owner, uint256 amount);\r
event ClaimStatusChanged(bool newStatus);\r
event TokenPriceUpdated(uint256 newPrice);\r
event TokensClaimed(address indexed user, uint256 amount);\r
\r
constructor(\r
address _token,\r
address _usdt,\r
address _priceFeed,\r
address _treasuryWallet,\r
address _stakingContract\r
) {\r
require(_token != address(0), "Invalid token address");\r
require(_usdt != address(0), "Invalid USDT address");\r
require(_priceFeed != address(0), "Invalid price feed address");\r
require(_treasuryWallet != address(0), "Invalid treasury address");\r
require(_stakingContract != address(0), "Invalid staking address");\r
\r
token = IERC20(_token);\r
usdt = IERC20(_usdt);\r
priceFeed = AggregatorV3Interface(_priceFeed);\r
treasuryWallet = _treasuryWallet;\r
stakingContract = _stakingContract;\r
}\r
\r
receive() external payable {\r
buyAndStakeWithETH();\r
}\r
\r
// ==================== PRICE HELPERS ====================\r
function getLatestETHPrice() public view returns (uint256) {\r
(, int256 price, , , ) = priceFeed.latestRoundData();\r
return uint256(price).mul(1e10); // convert from 8 to 18 decimals\r
}\r
\r
function getTokenPriceInETH() public view returns (uint256) {\r
uint256 ethPriceInUSD = getLatestETHPrice();\r
return tokenPriceInUSDT.mul(1e18).div(ethPriceInUSD);\r
}\r
\r
function getTotalRaisedInUSD() public view returns (uint256) {\r
uint256 ethUSD = getLatestETHPrice(); // 1 ETH = X USD (18 decimals)\r
uint256 totalETHinUSD = totalETHRaised.mul(ethUSD).div(1e18);\r
uint256 totalUSDTinUSD = totalUSDTRaised; // USDT already 1:1 USD\r
return totalETHinUSD.add(totalUSDTinUSD);\r
}\r
\r
// ==================== BUY WITH ETH ====================\r
function buyWithETH() public payable {\r
require(saleActive, "Sale not active");\r
require(msg.value > 0, "No ETH sent");\r
\r
uint256 ethAmount = msg.value;\r
uint256 newRaisedUSD = getTotalRaisedInUSD();\r
uint256 ethValueUSD = ethAmount.mul(getLatestETHPrice()).div(1e18);\r
require(newRaisedUSD.add(ethValueUSD) <= HARD_CAP, "Hard cap reached");\r
\r
uint256 tokenPriceInETH = getTokenPriceInETH();\r
uint256 tokenAmount = ethAmount.mul(1e18).div(tokenPriceInETH);\r
require(token.balanceOf(address(this)) >= tokenAmount, "Not enough tokens");\r
\r
totalETHRaised = totalETHRaised.add(ethAmount);\r
pendingTokens[msg.sender] = pendingTokens[msg.sender].add(tokenAmount);\r
\r
(bool success, ) = treasuryWallet.call{value: ethAmount}("");\r
require(success, "ETH transfer failed");\r
\r
emit Sell(msg.sender, tokenAmount, ethAmount, "ETH");\r
}\r
\r
// ==================== BUY WITH USDT ====================\r
function buyWithUSDT(uint256 usdtAmount) public {\r
require(saleActive, "Sale not active");\r
require(usdtAmount > 0, "Invalid USDT amount");\r
\r
uint256 newRaisedUSD = getTotalRaisedInUSD();\r
require(newRaisedUSD.add(usdtAmount) <= HARD_CAP, "Hard cap reached");\r
\r
uint256 tokenAmount = usdtAmount.mul(1e18).div(tokenPriceInUSDT);\r
require(token.balanceOf(address(this)) >= tokenAmount, "Not enough tokens");\r
\r
totalUSDTRaised = totalUSDTRaised.add(usdtAmount);\r
pendingTokens[msg.sender] = pendingTokens[msg.sender].add(tokenAmount);\r
\r
require(usdt.transferFrom(msg.sender, treasuryWallet, usdtAmount), "USDT transfer failed");\r
\r
emit Sell(msg.sender, tokenAmount, usdtAmount, "USDT");\r
}\r
\r
// ==================== NEW: BUY AND STAKE WITH ETH ====================\r
function buyAndStakeWithETH() public payable {\r
require(saleActive, "Sale not active");\r
require(msg.value > 0, "No ETH sent");\r
require(stakingContract != address(0), "Staking not set");\r
\r
uint256 ethAmount = msg.value;\r
uint256 newRaisedUSD = getTotalRaisedInUSD();\r
uint256 ethValueUSD = ethAmount.mul(getLatestETHPrice()).div(1e18);\r
require(newRaisedUSD.add(ethValueUSD) <= HARD_CAP, "Hard cap reached");\r
\r
uint256 tokenPriceInETH = getTokenPriceInETH();\r
uint256 tokenAmount = ethAmount.mul(1e18).div(tokenPriceInETH);\r
require(token.balanceOf(address(this)) >= tokenAmount, "Not enough tokens in presale");\r
\r
totalETHRaised = totalETHRaised.add(ethAmount);\r
\r
// Transfer ETH immediately to treasury\r
(bool success, ) = treasuryWallet.call{value: ethAmount}("");\r
require(success, "ETH transfer failed");\r
\r
// Transfer tokens from presale contract to staking contract\r
require(token.transfer(stakingContract, tokenAmount), "Token transfer to staking failed");\r
\r
// Call staking contract to record the stake on behalf of buyer\r
IStaking(stakingContract).stakeFor(msg.sender, tokenAmount);\r
\r
emit SellAndStake(msg.sender, tokenAmount, ethAmount, "ETH");\r
}\r
\r
// ==================== NEW: BUY AND STAKE WITH USDT ====================\r
function buyAndStakeWithUSDT(uint256 usdtAmount) public {\r
require(saleActive, "Sale not active");\r
require(usdtAmount > 0, "Invalid USDT amount");\r
require(stakingContract != address(0), "Staking not set");\r
\r
uint256 newRaisedUSD = getTotalRaisedInUSD();\r
require(newRaisedUSD.add(usdtAmount) <= HARD_CAP, "Hard cap reached");\r
\r
uint256 tokenAmount = usdtAmount.mul(1e18).div(tokenPriceInUSDT);\r
require(token.balanceOf(address(this)) >= tokenAmount, "Not enough tokens in presale");\r
\r
totalUSDTRaised = totalUSDTRaised.add(usdtAmount);\r
\r
// Transfer USDT to treasury\r
require(usdt.transferFrom(msg.sender, treasuryWallet, usdtAmount), "USDT transfer failed");\r
\r
// Transfer tokens from presale contract to staking contract\r
require(token.transfer(stakingContract, tokenAmount), "Token transfer to staking failed");\r
\r
// Call staking contract to record the stake on behalf of buyer\r
IStaking(stakingContract).stakeFor(msg.sender, tokenAmount);\r
\r
emit SellAndStake(msg.sender, tokenAmount, usdtAmount, "USDT");\r
}\r
\r
// ==================== CLAIM TOKENS ====================\r
function claimTokens() public {\r
require(claimEnabled, "Claim not enabled");\r
uint256 amount = pendingTokens[msg.sender];\r
require(amount > 0, "No tokens to claim");\r
\r
pendingTokens[msg.sender] = 0;\r
require(token.transfer(msg.sender, amount), "Token transfer failed");\r
\r
emit TokensClaimed(msg.sender, amount);\r
}\r
\r
// ==================== ADMIN FUNCTIONS ====================\r
function setClaimEnabled(bool _enabled) external onlyOwner {\r
claimEnabled = _enabled;\r
emit ClaimStatusChanged(_enabled);\r
}\r
\r
function withdraw() public onlyOwner {\r
uint256 balance = address(this).balance;\r
require(balance > 0, "No ETH to withdraw");\r
payable(msg.sender).transfer(balance);\r
emit Withdraw(msg.sender, balance);\r
}\r
\r
function setSaleStatus(bool _status) external onlyOwner {\r
saleActive = _status;\r
}\r
\r
function endSale() public onlyOwner {\r
uint256 remaining = token.balanceOf(address(this));\r
if (remaining > 0) token.transfer(msg.sender, remaining);\r
saleActive = false;\r
}\r
\r
function updateTokenPriceInUSDT(uint256 _newPrice) external onlyOwner {\r
require(_newPrice > 0, "Invalid price");\r
tokenPriceInUSDT = _newPrice;\r
emit TokenPriceUpdated(_newPrice);\r
}\r
\r
function emergencyWithdrawTokens() external onlyOwner {\r
uint256 remaining = token.balanceOf(address(this));\r
require(token.transfer(msg.sender, remaining), "Token transfer failed");\r
}\r
\r
function setStakingContract(address _staking) external onlyOwner {\r
require(_staking != address(0), "Invalid staking");\r
stakingContract = _staking;\r
}\r
}\r
"
}
},
"settings": {
"evmVersion": "shanghai",
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": [],
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}
}}
Submitted on: 2025-11-03 17:43:36
Comments
Log in to comment.
No comments yet.