Skip to content

Instantly share code, notes, and snippets.

@Bryanmankind
Created May 16, 2024 12:03
Show Gist options
  • Save Bryanmankind/2b44cc83710c1b6e70c4ed092a30cb33 to your computer and use it in GitHub Desktop.
Save Bryanmankind/2b44cc83710c1b6e70c4ed092a30cb33 to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.8.24+commit.e11b9ed9.js&optimize=false&runs=200&gist=
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;
import {IERC20} from "@openzeppelin/contracts/interfaces/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
contract PMT is ERC20 {
constructor() ERC20("PERMIT", "PMT") {
// Mint initial supply to contract creator
_mint(msg.sender, 1_000_000_000 * 10**18);
}
}
contract StarterPreSale {
using SafeERC20 for IERC20;
// Error handeling
error invalidAccount();
error invalidPrice();
error fundsTooLow();
error tokensSoldOut();
error invalidPayment();
error preSaleIsOver();
error tokenNotSent();
error failedToSendMoney();
error preSaleNotOver();
// address of owner to deploy contract;
address payable public owner;
// payment token to contract
IERC20 public USDC;
// contract native token
IERC20 public PMT;
uint256 public preSaleStartTime;
uint256 public endpreSale;
uint256 public soldTokens;
uint256 public amountRaisedUSDC;
uint256 public amountRaisedEth;
uint256 public PMTSupply = 1_000_000_000;
uint256 public preSaleSupply = 800_000 * 10 ** 18; // PMT presale tokens
uint256 public costOfToken = 0.000050059 ether; // 1 PMT cost for one token in ether
uint256 public tokenPerUSDC = 0.006 * 10** 6; // 1 token per $1 current price of eth
uint256 public minimumUSDC = 2 * 10** 6; // minimum amount to get to tokens in ustd
uint256 public minimumEth = 0.000691 ether; // minimum amount to get to tokens in eth
modifier onlyOwner() {
require (msg.sender == owner, "You are not the owner");
_;
}
modifier checkPrice (uint256 _price) {
if (_price == 0) {
revert invalidPrice();
}
_;
}
event BuyToken (address indexed user, uint256 indexed amount);
event received (address indexed user, uint256 value);
event PriceUpdated(uint256 newPrice);
constructor (address _tokenAddress, address paymentAdd) {
owner = payable (msg.sender);
PMT = IERC20(_tokenAddress);
USDC = IERC20(paymentAdd);
preSaleStartTime = block.timestamp;
endpreSale = preSaleStartTime + 60 days;
}
function getTokenCost() external view returns (uint256) {
return costOfToken;
}
function extendPreSaleTime (uint256 _newDate) external onlyOwner {
endpreSale = block.timestamp + _newDate;
}
// change the cost of the token
function tokenCost (uint256 _price) external checkPrice(_price) onlyOwner {
costOfToken = _price;
emit PriceUpdated(_price);
}
// Change the cost per USDC
function tokenPriceUSDC (uint256 _price) external checkPrice(_price) onlyOwner {
tokenPerUSDC = _price;
emit PriceUpdated(_price);
}
// Change the minimum dollar
function tokenPriceminimumUSDC (uint256 _price) external checkPrice(_price) onlyOwner {
minimumUSDC = _price;
emit PriceUpdated(_price);
}
// Change the minimum Eth
function tokenPriceminimumEth (uint256 _price) external checkPrice(_price) onlyOwner {
minimumEth = _price;
emit PriceUpdated(_price);
}
// function deposit PMT to contract
function depositPMT (uint256 _tokens) external onlyOwner {
PMT.safeTransferFrom(msg.sender, address(this), _tokens);
}
function withdrawPMTtoken () public onlyOwner {
uint256 PMTamount = PMT.balanceOf(address(this));
PMT.transfer(msg.sender, PMTamount);
}
// function but PMT with Eth
function buyTokenInEth() external payable returns (bool) {
// Calculate the amount of tokens to be purchased
uint256 token = msg.value / costOfToken;
if (block.timestamp > endpreSale) {
revert preSaleIsOver();
}
if (msg.value < minimumEth) {
revert fundsTooLow();
}
if (soldTokens + token > preSaleSupply) {
revert tokensSoldOut();
}
// Update contract state variables
soldTokens += token;
amountRaisedEth += msg.value;
// Transfer PMT tokens to the buyer's address
PMT.safeTransfer(msg.sender, token);
emit BuyToken(msg.sender, token);
return true;
}
// function buy PMT after presale
function buyTokenInEthAfterPreSale() external payable returns (bool) {
// Calculate the amount of tokens to be purchased
uint256 token = msg.value / costOfToken;
if (block.timestamp < endpreSale) {
revert preSaleNotOver();
}
if (soldTokens + token > PMTSupply) {
revert tokensSoldOut();
}
// Update contract state variables
soldTokens += token;
amountRaisedEth += msg.value;
// Transfer PMT tokens to the buyer's address
PMT.safeTransfer(msg.sender, token);
emit BuyToken(msg.sender, token);
return true;
}
function buyTokenWithUSDC (uint256 _usdcAmount) public returns (bool) {
uint256 token = _usdcAmount / tokenPerUSDC;
if (block.timestamp > endpreSale) {
revert preSaleIsOver();
}
if (soldTokens + token > preSaleSupply) {
revert tokensSoldOut();
}
if (_usdcAmount < minimumUSDC) {
revert fundsTooLow();
}
// Update contract state variables
soldTokens += token;
amountRaisedUSDC += _usdcAmount;
// transfer USDC tokens from the sender to the contract
USDC.safeTransferFrom(msg.sender, address(this), _usdcAmount);
// Transfer PMT tokens to the buyer's address
PMT.safeTransfer(msg.sender, token);
emit BuyToken(msg.sender, token);
return true;
}
function buyTokenWithUSDCAfterPreSale (uint256 _usdcAmount) public returns (bool) {
uint256 token = _usdcAmount / tokenPerUSDC;
if (block.timestamp < endpreSale) {
revert preSaleNotOver();
}
if (soldTokens + token > preSaleSupply) {
revert tokensSoldOut();
}
// Update contract state variables
soldTokens += token;
amountRaisedUSDC += _usdcAmount;
// transfer USDC tokens from the sender to the contract
USDC.safeTransferFrom(msg.sender, address(this), _usdcAmount);
// Transfer PMT tokens to the buyer's address
PMT.safeTransfer(msg.sender, token);
emit BuyToken(msg.sender, token);
return true;
}
function withdrawEth() public onlyOwner {
uint256 balance = address(this).balance;
amountRaisedEth = 0;
(bool success,) = owner.call{value: balance}("");
if (!success) {
revert failedToSendMoney();
}
}
function withdrawUSDC() public onlyOwner {
uint256 amount = USDC.balanceOf(address(this));
amountRaisedUSDC = 0;
(bool success,) = owner.call{value: amount}("");
if (!success) {
revert failedToSendMoney();
}
}
receive() external payable {
emit received (msg.sender, msg.value);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment