Skip to content

Instantly share code, notes, and snippets.

@coderwithsense
Last active January 10, 2024 13:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save coderwithsense/781f82b6f5129cc969a25079ac3ebadb to your computer and use it in GitHub Desktop.
Save coderwithsense/781f82b6f5129cc969a25079ac3ebadb to your computer and use it in GitHub Desktop.
CryptoGrad PreSale Smart Contract (Editing required for production ready)

TokenPresale Smart Contract

Overview

The TokenPresale smart contract facilitates the sale of a specific ERC-20 token at a predetermined rate in exchange for Ether (ETH). It includes features such as pausing, ownership control, and a cap on the total ETH that can be raised during the presale.

Important Variables

  • token: The ERC-20 token being sold.
  • rate: The rate at which tokens are exchanged for ETH, denominated in wei.
  • cap: The maximum amount of ETH that can be raised during the presale.
  • weiRaised: Total amount of ETH raised so far.
  • tokenAddress: The address of the ERC-20 token contract.
  • tokensPurchased: Mapping to keep track of the amount of tokens purchased by each beneficiary.
  • claimedAmount: Mapping to track the amount of tokens claimed by each beneficiary.

Functions

Constructor

Description: Constructor to initialize the smart contract with the token rate and cap. Parameters:

  • _rate: Token rate per ETH (wei).
  • _cap: Cap in ETH (wei).

buyToken

Description: Allows users to purchase tokens by sending ETH to the contract. Parameters:

  • beneficiary: The address that will receive the purchased tokens.

estimateTokenBuy

Description: Provides an estimate of the number of tokens a user can buy with a specific amount of ETH. Parameters:

  • _weiAmount: The amount of ETH in wei.

claim

Description: Allows users to claim their purchased tokens.

withdraw

Description: Allows the owner to withdraw the ETH balance from the contract.

pausePresale

Description: Allows the owner to pause the presale.

unPausePresale

Description: Allows the owner to unpause the presale.

tokensAvailableForSale

Description: Returns the number of tokens available for sale in the contract.

receive

Description: Fallback function to allow users to send ETH and purchase tokens.

Events

TokenPurchased

Parameters:

  • purchaser: The address that initiated the token purchase.
  • beneficiary: The address that will receive the purchased tokens.
  • value: The amount of ETH sent.
  • amount: The amount of tokens purchased.

TokenClaimed

Parameters:

  • beneficiary: The address that claimed the tokens.
  • amount: The amount of tokens claimed.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
contract TokenPresale is Ownable, Pausable {
using SafeMath for uint256;
IERC20 public token; // The token being sold
uint256 public rate; // Token rate per ETH (wei)
uint256 public cap; // Cap in ETH (wei)
uint256 public weiRaised;
address public tokenAddress = 0x032ACfAFb4Ffa8acb556e4b7535Ee542bc152726;
mapping(address => uint256) private tokensPurchased;
mapping(address => uint256) public claimedAmount;
event TokenPurchased(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);
event TokenClaimed(address indexed beneficiary, uint256 amount);
constructor(uint256 _rate, uint256 _cap) Ownable(msg.sender) {
require(_rate > 0, "Token rate must be greater than zero");
require(_cap > 0, "Cap must be greter than zero");
token = IERC20(tokenAddress);
rate = _rate;
cap = _cap;
_pause();
}
function buyToken(address beneficiary) public payable whenNotPaused {
uint256 weiAmount = msg.value;
require(weiAmount > 0, "Wei amount must be greater than zero");
require(weiRaised.add(weiAmount) <= cap, "Cap exceeded");
uint256 tokenAmount = getTokenAmount(weiAmount);
require(tokenAmount > 0, "Token amount must be greater than zero");
require(tokensAvailableForSale() >= tokenAmount, "Not enough tokens available");
token.transfer(beneficiary, tokenAmount);
tokensPurchased[beneficiary] = tokensPurchased[beneficiary].add(tokenAmount);
weiRaised = weiRaised.add(weiAmount);
emit TokenPurchased(msg.sender, beneficiary, weiAmount, tokenAmount);
}
function estimateTokenBuy(uint256 _weiAmount) public view returns (uint256) {
return getTokenAmount(_weiAmount);
}
function getTokenAmount(uint256 _weiAmount) private view returns (uint256){
return _weiAmount.mul(rate);
}
function getClaimableAmount(address _userAddress) public view returns (uint256) {
uint256 purchasedTokens = tokensPurchased[_userAddress];
uint256 claimed = claimedAmount[_userAddress];
if(purchasedTokens > claimed){
return purchasedTokens.sub(claimed);
} else {
return 0;
}
}
function claim() public whenNotPaused {
uint256 claimable = getClaimableAmount(msg.sender);
require(claimable > 0, "No tokens to claim");
claimedAmount[msg.sender] = claimedAmount[msg.sender].add(claimable);
token.transfer(msg.sender, claimable);
emit TokenClaimed(msg.sender, claimable);
}
function withdraw() external onlyOwner {
payable(owner()).transfer(address(this).balance);
}
function pausePresale() public onlyOwner{
_pause();
}
function unPausePresale() public onlyOwner{
_unpause();
}
function tokensAvailableForSale() public view returns(uint256){
return token.balanceOf(address(this));
}
receive() external payable whenNotPaused {
buyToken(msg.sender);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment