Skip to content

Instantly share code, notes, and snippets.

@superXdev
Created April 4, 2024 10:35
Show Gist options
  • Save superXdev/419e703946bec37bc48fa4f175796b7b to your computer and use it in GitHub Desktop.
Save superXdev/419e703946bec37bc48fa4f175796b7b to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// Interface for ERC20 token
interface ERC20 {
// Transfer tokens to a specified address
function transfer(address recipient, uint256 amount) external returns (bool);
// Get the balance of a specific address
function balanceOf(address account) external view returns (uint256);
// Get the number of decimals used by the token
function decimals() external view returns (uint8);
// Get the total supply of the token
function totalSupply() external view returns (uint256);
// Burn a specific amount of tokens
function burn(uint256 amount) external returns (bool);
}
contract TokenSale {
// Address of the owner of the contract
address public owner;
// Address of the ERC20 token contract
address public tokenAddress;
// Rate of token per ether
uint256 public rate;
// Time when the sale starts
uint public timeToStart;
// Minimum amount of tokens that can be purchased
uint256 public minAmount;
// Maximum amount of tokens that can be purchased
uint256 public maxAmount;
// Event emitted when tokens are purchased
event TokenPurchased(address buyer, uint256 amount);
// Event emitted when unsold tokens are withdrawn
event WithdrawUnsoldTokens(uint256 amount);
// Modifier to restrict access to only the owner of the contract
modifier onlyOwner() {
require(msg.sender == owner, "Caller is not the owner");
_;
}
constructor(address _tokenAddress, uint256 _rate, uint _timeToStart) {
owner = msg.sender;
tokenAddress = _tokenAddress;
rate = _rate;
timeToStart = _timeToStart;
}
// Check if the sale has started
function isTimeToStarted() external view returns (bool) {
return block.timestamp >= timeToStart;
}
// Set minimum and maximum purchase amounts
function setMinMaxAmount(uint256 _maxAmount, uint256 _minAmount) external onlyOwner {
ERC20 token = ERC20(tokenAddress);
uint256 tokenDecimals = uint256(token.decimals());
minAmount = _minAmount * (10**tokenDecimals);
maxAmount = _maxAmount * (10**tokenDecimals);
}
// Set the start time of the sale
function setTime(uint _timeToStart) external onlyOwner {
timeToStart = _timeToStart;
}
// Function to buy tokens
function buyToken() external payable {
require(block.timestamp >= timeToStart, "Not yet started");
ERC20 token = ERC20(tokenAddress);
uint256 tokenDecimals = uint256(token.decimals());
uint256 tokenAmount = msg.value * rate * (10**tokenDecimals) / (10**18);
require(token.balanceOf(address(this)) >= tokenAmount, "Not enough tokens in sale contract");
require(tokenAmount >= minAmount, "Minimum purchase not met");
require(tokenAmount <= maxAmount, "Exceed maximum purchase");
require(token.transfer(msg.sender, tokenAmount), "Token transfer failed");
emit TokenPurchased(msg.sender, tokenAmount);
}
// Withdraw Ether from the contract
function withdrawEther() external onlyOwner {
payable(owner).transfer(address(this).balance);
}
// Withdraw unsold tokens from the contract
function withdrawRestTokens() external onlyOwner {
ERC20 token = ERC20(tokenAddress);
uint256 unsoldTokens = token.balanceOf(address(this));
require(unsoldTokens > 0, "No unsold tokens");
require(token.transfer(owner, unsoldTokens), "Token transfer failed");
emit WithdrawUnsoldTokens(unsoldTokens);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment