Skip to content

Instantly share code, notes, and snippets.

@Bryanmankind
Created June 13, 2024 22:49
Show Gist options
  • Save Bryanmankind/2c959d78a6c8cf973f04adaf4555d2d3 to your computer and use it in GitHub Desktop.
Save Bryanmankind/2c959d78a6c8cf973f04adaf4555d2d3 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.23+commit.f704f362.js&optimize=false&runs=200&gist=
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IUniswapV3Pool} from "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol";
contract PreSaleToken is ERC20 {
constructor() ERC20("PreSaleToken", "PST") {
// Mint initial supply to contract creator
_mint(msg.sender, 1_000_000_000 * 10**18);
}
}
contract GuildTestPreSale {
using SafeERC20 for IERC20;
IERC20 public preSaleToken;
IUniswapV3Pool public uniswapRouter;
error moreThanAvailableTokens();
error notRegisteredAccount();
error tokensAlreadyClaimed();
error tokensAlreadyLocked();
error youAreNotTheOwner();
error failedToSendMoney();
error tokensStillLocked();
error preSaleOver();
error lowAmount();
address public owner;
address[] public registeredTeam;
uint256 public startPresale;
uint256 public endPreSale = block.timestamp + 10 days;
uint256 public fundsRaised;
uint256 public contractChargeFee;
uint256 public tokenFee = 0.0006 ether;
uint256 public soldTokens;
uint256 public cliffperiod = 5 days;
uint256 public vestingPeriod = block.timestamp + 100 days;
uint256 public vestedTokens;
uint256 public unvestedTokens;
uint256 public constant SCALE = 100000;
uint256 public preSaleTokens = 200_000_000;
uint256 public reserveRatio = 500;
bool public locked = false;
bool public claimed = false;
event dateUpdated(uint256 date);
event getToken(address indexed user, uint256 indexed amount);
constructor(address _preSaleToken) {
owner = payable(msg.sender);
preSaleToken = IERC20(_preSaleToken);
startPresale = block.timestamp;
}
mapping(address => uint256) public tokenBalance;
mapping(address => uint256) public liquidityBalances;
modifier onlyOwner() {
if (msg.sender != owner) {
revert youAreNotTheOwner();
}
_;
}
function getRegister() public {
registeredTeam.push(address(msg.sender));
}
function updateEndPresale(uint256 _time) public onlyOwner returns (bool) {
endPreSale = _time;
emit dateUpdated(_time);
return (true);
}
function availableTokens() public view returns (uint256) {
return preSaleTokens - soldTokens;
}
function contractFee() public view returns (uint256) {
return (fundsRaised * 15) / 100;
}
// call lock function if they are vesting
function vesting () public {
getTokensDuringPreSale();
}
function cliffPeriod () public onlyOwner {
require(block.timestamp < cliffperiod, "");
if (!vesting()) {
terminateTheLiquidity();
}else if (!addLiquidity) {
} else {
vesting();
}
}
// important to receive ETH
receive() external payable {
getTokensDuringPreSale();
}
function getTokensDuringPreSale() public payable returns (bool) {
if (block.timestamp > endPreSale) {
revert preSaleOver();
}
for (uint256 i; i < registeredTeam.length; i++) {
if (msg.sender != registeredTeam[i]) {
revert notRegisteredAccount();
}
}
if (msg.value < tokenFee) {
revert lowAmount();
}
uint256 token = msg.value / tokenFee;
if (token + soldTokens > preSaleTokens) {
revert moreThanAvailableTokens();
}
// Update contract state variables
soldTokens += token;
fundsRaised += msg.value;
tokenBalance += token;
// vest Tokens
preSaleToken.safeTransfer(address(this), token);
emit getToken(msg.sender, token);
return true;
}
function withDrawContractFee() public onlyOwner {
uint256 amountFee = contractFee();
(bool success, ) = owner.call{value: amountFee}("");
if (!success) {
revert failedToSendMoney();
}
}
function withdrawEth() public onlyOwner {
uint256 balance = address(this).balance;
(bool success,) = owner.call{value: balance}("");
if (!success) {
revert failedToSendMoney();
}
}
function claimTokens() public returns (bool) {
if (block.timestamp < vestingPeriod) {
revert tokensStillLocked();
}
if (claimed) {
revert tokensAlreadyClaimed();
}
claimed = true;
preSaleToken.safeTransfer.tokenBalance(msg.sender, tokens);
return (true);
}
function addLiquidity(uint256 _tokens, uint256 _ethAmount) public {
require(_tokens > 0 && _ethAmount > 0, "Insufficient funds");
uint256 totalLiquidity = _tokens + _ethAmount;
liquidityBalances[msg.sender] += totalLiquidity;
reserveRatio =
(reserveRatio * totalLiquidity) /
(totalLiquidity + reserveRatio);
}
function terminateTheLiquidity() public {
uint256 userLiquidity = liquidityBalances[msg.sender];
require(userLiquidity > 0, "No liquidity to withdraw");
// Calculate the amount of tokens and ETH to withdraw
uint256 tokensToWithdraw = (userLiquidity * reserveRatio) / SCALE;
uint256 ethToWithdraw = userLiquidity - tokensToWithdraw;
// Update liquidity balances
liquidityBalances[msg.sender] = 0;
// Transfer the corresponding amounts of tokens and ETH back to the user
require(preSaleToken.transfer(msg.sender, tokensToWithdraw), "Token transfer failed");
payable(msg.sender).transfer(ethToWithdraw);
// Update total liquidity and reserve ratio if needed
// You might want to update these variables based on your specific logic
}
function revShear() public onlyOwner {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment