// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
abstract contract BaseERC20 {
string public name;
string public symbol;
uint8 public constant decimals = 18;
uint256 public totalSupply;
mapping(address => uint256) internal balances;
mapping(address => mapping(address => uint256)) internal allowances;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
constructor(string memory _name, string memory _symbol) {
name = _name;
symbol = _symbol;
}
function balanceOf(address account) public view returns (uint256) {
return balances[account];
}
function allowance(
address owner,
address spender
) public view returns (uint256) {
return allowances[owner][spender];
}
function transfer(
address recipient,
uint256 amount
) public virtual returns (bool) {
_transfer(msg.sender, recipient, amount);
return true;
}
function approve(
address spender,
uint256 amount
) public virtual returns (bool) {
_approve(msg.sender, spender, amount);
return true;
}
function transferFrom(
address sender,
address recipient,
uint256 amount
) public virtual returns (bool) {
uint256 currentAllowance = allowances[sender][msg.sender];
require(
currentAllowance >= amount,
"ERC20: transfer amount exceeds allowance"
);
_transfer(sender, recipient, amount);
_approve(sender, msg.sender, currentAllowance - amount);
return true;
}
function _transfer(
address sender,
address recipient,
uint256 amount
) internal virtual {
require(sender != address(0), "ERC20: transfer from zero");
require(recipient != address(0), "ERC20: transfer to zero");
require(balances[sender] >= amount, "ERC20: insufficient balance");
balances[sender] -= amount;
balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
}
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), "ERC20: approve from zero");
require(spender != address(0), "ERC20: approve to zero");
allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
}
interface IUniswapV2Router02 {
function addLiquidityETH(
address token,
uint256 amountTokenDesired,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline
)
external
payable
returns (uint256 amountToken, uint256 amountETH, uint256 liquidity);
function factory() external pure returns (address);
}
interface IUniswapV2Factory {
function getPair(
address tokenA,
address tokenB
) external view returns (address pair);
}
// Lightweight interface for Uniswap V2 Pair
interface IUniswapV2Pair {
function getReserves() external view returns (uint112, uint112, uint32);
function token0() external view returns (address);
function token1() external view returns (address);
}
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
* consider using {ReentrancyGuardTransient} instead.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be NOT_ENTERED
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
_status = ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}
contract Flaunt is BaseERC20, ReentrancyGuard {
address private UNISWAP_V2_ROUTER =
0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
address public WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address public uniswapV2Pair;
bool public liquidityAdded;
uint256 public constant TOTAL_SUPPLY = 1_000_000_000 * 1e18;
uint256 public constant LIQUIDITY_AMOUNT = 800_000_000 * 1e18;
uint256 public constant REWARDS_AMOUNT = 200_000_000 * 1e18;
uint256 public constant MAX_WALLET_AMOUNT = 1_000_000 * 1e18;
bool public limitsActive = true;
uint256 public currentPrice;
uint256 public highestPrice;
uint256 public lastPrice;
uint256 public sellFeeBasisPoints;
uint256 public stageStartTime;
uint256 public stageStartPrice;
bool public isInFeeStage;
uint256 public currentStageId;
uint8 public shutdownStep = 0;
mapping(uint256 => uint256) public feeCollectedPerStage;
mapping(uint256 => uint256) public buyersInStage;
mapping(address => uint256) public lastPurchaseTimestamp;
mapping(address => uint256) public userLastStage;
uint256 public lastRecoveryBasisPoints;
// track if an address already bought in this stage (for buyer count)
mapping(uint256 => mapping(address => bool)) public hasBoughtInStage;
// NEW: per‐stage total bought & per‐user per‐stage records
mapping(uint256 => uint256) public totalBoughtPerStage;
mapping(uint256 => uint256) public rewardPerTokenPerStage;
mapping(address => mapping(uint256 => uint256)) public userBoughtInStage;
mapping(address => mapping(uint256 => bool)) public rewardClaimedInStage;
event StageFinalized(
uint256 indexed stageId,
uint256 startTime,
uint256 endTime,
uint256 feesCollected,
uint256 buyersCount
);
event PriceUpdate(
uint256 currentPrice,
uint256 highestPrice,
uint256 lastPrice,
uint256 sellFeeBasisPoints,
bool newStageStarted,
uint256 feesCollectedThisStage,
uint256 amountTraded
);
event StageStarted(uint256 indexed stageId, uint256 startTime);
event FeeTaken(address indexed from, uint256 amount);
modifier onlyOwner() {
require(msg.sender == OWNER(), "Not owner");
_;
}
constructor() BaseERC20("Flaunt", "Flaunt") {
totalSupply = TOTAL_SUPPLY;
balances[address(this)] = LIQUIDITY_AMOUNT;
emit Transfer(address(0), address(this), LIQUIDITY_AMOUNT);
address platformRewards = REFERAL_REWARDS_CONTRACT();
require(
platformRewards != address(0),
"Platform rewards address is zero"
);
balances[platformRewards] = REWARDS_AMOUNT;
emit Transfer(address(0), platformRewards, REWARDS_AMOUNT);
_approve(address(this), UNISWAP_V2_ROUTER, LIQUIDITY_AMOUNT);
}
/// @notice Update the Uniswap V2 Router address
function setUniswapV2Router(address _router) external onlyOwner {
require(_router != address(0), "Router cannot be zero");
UNISWAP_V2_ROUTER = _router;
}
/// @notice Update the WETH token address
function setWETH(address _weth) external onlyOwner {
require(_weth != address(0), "WETH cannot be zero");
WETH = _weth;
}
function protcolAddress() private pure returns (IProtcolAddress) {
return IProtcolAddress(0xC6B021DE4C4d0D2C07f847AdeEFC1dBc1B31f661);
}
function LIQ_MANAGER_CONTRACT() public view returns (address) {
return protcolAddress().getAddress(1);
}
function PLATFORM_REWARDS_CONTRACT() public view returns (address) {
return protcolAddress().getAddress(6);
}
function STAKING_CONTRACT() public view returns (address) {
return protcolAddress().getAddress(9);
}
function REFERAL_REWARDS_CONTRACT() public view returns (address) {
return protcolAddress().getAddress(5);
}
function FLAUNT_ROUTER_CONTRACT() public view returns (address) {
return protcolAddress().getAddress(11);
}
function OWNER() public view returns (address) {
return protcolAddress().getAddress(7);
}
function FLAUNT_WALLET() public view returns (address) {
return protcolAddress().getAddress(16);
}
function addInitialLiquidity() external payable {
require(msg.sender == FLAUNT_WALLET(), "not allowed");
require(!liquidityAdded, "Liquidity already added");
require(FLAUNT_WALLET() != address(0), "FLAUNT_WALLET address is zero");
IUniswapV2Router02(UNISWAP_V2_ROUTER).addLiquidityETH{value: msg.value}(
address(this),
LIQUIDITY_AMOUNT,
0,
0,
FLAUNT_WALLET(),
block.timestamp + 20 minutes
);
address factory = IUniswapV2Router02(UNISWAP_V2_ROUTER).factory();
uniswapV2Pair = IUniswapV2Factory(factory).getPair(address(this), WETH);
liquidityAdded = true;
_updatePrice(0);
highestPrice = currentPrice;
lastPrice = currentPrice;
sellFeeBasisPoints = 0;
}
function _transfer(
address sender,
address recipient,
uint256 amount
) internal override nonReentrant {
// 1. Prevent zero‐address transfers
require(
sender != address(0) && recipient != address(0),
"Zero address"
);
// 2. Enforce max‐wallet limit on non‐excluded recipients
if (limitsActive) {
if (
liquidityAdded &&
recipient != uniswapV2Pair &&
recipient != address(this) &&
recipient != PLATFORM_REWARDS_CONTRACT() &&
recipient != STAKING_CONTRACT() &&
recipient != REFERAL_REWARDS_CONTRACT() &&
recipient != LIQ_MANAGER_CONTRACT() &&
recipient != FLAUNT_ROUTER_CONTRACT() &&
recipient != FLAUNT_WALLET() &&
recipient != OWNER()
) {
require(
balanceOf(recipient) + amount <= MAX_WALLET_AMOUNT,
"Exceeds max wallet"
);
}
}
// 3. If shutdown has begun, skip all special logic
if (shutdownStep >= 1) {
super._transfer(sender, recipient, amount);
return;
}
// 4. Calculate sell‐fee if this is a sell (to the pair)
uint256 fee = 0;
uint256 finalAmount = amount;
if (recipient == uniswapV2Pair) {
require(amount >= 1e12, "Amount too small to sell");
if (sellFeeBasisPoints > 0) {
// fee = amount * feeBP / 10000
fee = (amount * sellFeeBasisPoints) / 10000;
finalAmount = amount - fee;
}
}
// === Forfeiture Logic ===
// 5. On any non‐buy transfer (i.e. sender != pair), sweep ALL
// unclaimed stage rewards into the Flaunt wallet
if (sender != uniswapV2Pair) {
uint256 forfeited = 0;
for (uint256 i = 1; i <= userLastStage[sender]; i++) {
// skip if already claimed
if (rewardClaimedInStage[sender][i]) continue;
uint256 bought = userBoughtInStage[sender][i];
uint256 rpt = rewardPerTokenPerStage[i];
// skip if no buys or no reward-per-token
if (bought == 0 || rpt == 0) continue;
// pending = bought * rpt / 1e18
uint256 pending = (bought * rpt) / 1e18;
if (pending > 0) {
forfeited += pending;
rewardClaimedInStage[sender][i] = true;
}
}
if (forfeited > 0) {
uint256 balance = balanceOf(address(this));
uint256 toSend = forfeited > balance ? balance : forfeited;
if (toSend > 0) {
super._transfer(address(this), FLAUNT_WALLET(), toSend);
}
}
}
// 6. Execute the actual token transfer (minus fee if sell)
super._transfer(sender, recipient, finalAmount);
// 7. Collect the sell fee into this contract for the current stage
if (fee > 0) {
feeCollectedPerStage[currentStageId] += fee;
super._transfer(sender, address(this), fee);
emit FeeTaken(sender, fee);
}
// === Buy‐tracking Logic ===
// 8. If this is a buy during a fee stage, record it
if (sender == uniswapV2Pair && sellFeeBasisPoints > 0) {
userBoughtInStage[recipient][currentStageId] += finalAmount;
totalBoughtPerStage[currentStageId] += finalAmount;
lastPurchaseTimestamp[recipient] = block.timestamp;
// ✅ update user last stage
if (currentStageId > userLastStage[recipient]) {
userLastStage[recipient] = currentStageId;
}
if (!hasBoughtInStage[currentStageId][recipient]) {
hasBoughtInStage[currentStageId][recipient] = true;
buyersInStage[currentStageId]++;
}
}
// 9. Update price & potentially finalize/start stages
if (sender == uniswapV2Pair || recipient == uniswapV2Pair) {
_updatePrice(amount);
}
// 10. Remove limits once enough liquidity is sold
checkAndRemoveLimits();
}
function _getNewPrice() internal view returns (uint256) {
if (uniswapV2Pair == address(0)) return 0;
(uint112 r0, uint112 r1, ) = IUniswapV2Pair(uniswapV2Pair)
.getReserves();
address t0 = IUniswapV2Pair(uniswapV2Pair).token0();
if (t0 == address(this) && r0 > 0) return (uint256(r1) * 1e18) / r0;
if (r1 > 0) return (uint256(r0) * 1e18) / r1;
return 0;
}
function _updatePrice(uint256 amountTraded) internal {
bool newStageStarted = false;
uint256 newPrice = _getNewPrice();
if (newPrice == 0 || shutdownStep >= 1) return;
currentPrice = newPrice;
if (newPrice > highestPrice) {
if (isInFeeStage) _finalizeStage();
highestPrice = newPrice;
lastPrice = newPrice;
sellFeeBasisPoints = 0;
isInFeeStage = false;
lastRecoveryBasisPoints = 0;
} else if (
isInFeeStage && block.timestamp > stageStartTime + 30 minutes
) {
_finalizeStage();
highestPrice = currentPrice;
lastPrice = currentPrice;
sellFeeBasisPoints = 0;
isInFeeStage = false;
lastRecoveryBasisPoints = 0;
} else if (newPrice < highestPrice) {
uint256 drop = ((highestPrice - newPrice) * 10000) / highestPrice;
if (drop >= 500) {
if (!isInFeeStage) {
stageStartTime = block.timestamp;
stageStartPrice = newPrice;
lastRecoveryBasisPoints = 0;
isInFeeStage = true;
currentStageId++;
emit StageStarted(currentStageId, stageStartTime);
newStageStarted = true;
}
sellFeeBasisPoints = drop > 1500 ? 1500 : drop;
}
} else if (isInFeeStage && newPrice > stageStartPrice) {
uint256 recovery = ((newPrice - stageStartPrice) * 10000) /
stageStartPrice;
if (recovery > lastRecoveryBasisPoints) {
uint256 delta = recovery - lastRecoveryBasisPoints;
sellFeeBasisPoints = sellFeeBasisPoints > delta
? sellFeeBasisPoints - delta
: 0;
lastRecoveryBasisPoints = recovery;
}
lastPrice = newPrice;
if (sellFeeBasisPoints == 0 || newPrice >= highestPrice) {
_finalizeStage();
highestPrice = newPrice;
lastPrice = newPrice;
isInFeeStage = false;
lastRecoveryBasisPoints = 0;
}
} else if (isInFeeStage && sellFeeBasisPoints == 0) {
_finalizeStage();
highestPrice = currentPrice;
lastPrice = currentPrice;
isInFeeStage = false;
lastRecoveryBasisPoints = 0;
}
emit PriceUpdate(
currentPrice,
highestPrice,
lastPrice,
sellFeeBasisPoints,
newStageStarted,
isInFeeStage ? feeCollectedPerStage[currentStageId] : 0,
amountTraded
);
}
function _finalizeStage() internal {
uint256 fees = feeCollectedPerStage[currentStageId];
uint256 bought = totalBoughtPerStage[currentStageId];
if (fees > 0 && bought > 0) {
rewardPerTokenPerStage[currentStageId] = (fees * 1e18) / bought;
}
emit StageFinalized(
currentStageId,
stageStartTime,
block.timestamp,
fees,
buyersInStage[currentStageId]
);
isInFeeStage = false;
sellFeeBasisPoints = 0;
}
function claimRewards() external nonReentrant {
require(
block.timestamp >= lastPurchaseTimestamp[msg.sender] + 1440 minutes,
"Wait 1440m"
);
uint256 totalClaim = 0;
for (uint256 i = 1; i <= userLastStage[msg.sender]; i++) {
if (rewardClaimedInStage[msg.sender][i]) continue;
uint256 bought = userBoughtInStage[msg.sender][i];
uint256 rpt = rewardPerTokenPerStage[i];
if (bought == 0 || rpt == 0) continue;
totalClaim += (bought * rpt) / 1e18;
rewardClaimedInStage[msg.sender][i] = true;
}
require(totalClaim > 0, "Nothing to claim");
super._transfer(address(this), msg.sender, totalClaim);
}
/// @notice Total pending (unclaimed) rewards across all stages
function pendingRewards(address user) public view returns (uint256) {
uint256 total;
// sum rewards from stage 1 up to currentStageId
for (uint256 i = 1; i <= userLastStage[user]; i++) {
if (rewardClaimedInStage[user][i]) continue;
uint256 bought = userBoughtInStage[user][i];
uint256 rpt = rewardPerTokenPerStage[i];
if (bought == 0 || rpt == 0) continue;
total += (bought * rpt) / 1e18;
}
return total;
}
/// @notice Pending reward for a specific stage
function pendingRewardByStage(
address user,
uint256 stageId
) external view returns (uint256) {
if (stageId == 0 || stageId > currentStageId) return 0;
if (rewardClaimedInStage[user][stageId]) return 0;
uint256 bought = userBoughtInStage[user][stageId];
uint256 rpt = rewardPerTokenPerStage[stageId];
if (bought == 0 || rpt == 0) return 0;
return (bought * rpt) / 1e18;
}
function getTotalFeesCollected() external view returns (uint256 totalFees) {
for (uint256 i = 0; i <= currentStageId; i++) {
totalFees += feeCollectedPerStage[i];
}
}
function shutdownFees() external onlyOwner {
require(shutdownStep < 2, "Already finalized");
if (shutdownStep == 0) {
shutdownStep = 1;
limitsActive = false;
} else {
uint256 bal = balanceOf(address(this));
if (bal > 0) {
super._transfer(address(this), FLAUNT_WALLET(), bal);
}
shutdownStep = 2;
}
}
function removeLimit() public onlyOwner {
limitsActive = false;
}
function checkAndRemoveLimits() internal {
if (!limitsActive || uniswapV2Pair == address(0)) return;
uint256 poolBal = balanceOf(uniswapV2Pair);
uint256 sold = LIQUIDITY_AMOUNT > poolBal
? LIQUIDITY_AMOUNT - poolBal
: 0;
if ((sold * 100) / LIQUIDITY_AMOUNT >= 40) {
limitsActive = false;
}
}
receive() external payable {}
fallback() external payable {
revert("Function does not exist");
}
}
interface IProtcolAddress {
function getAddress(uint8 index) external view returns (address addr);
}
{
"compilationTarget": {
"FlauntMeme.sol": "Flaunt"
},
"evmVersion": "shanghai",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 2000
},
"remappings": []
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FeeTaken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"currentPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"highestPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sellFeeBasisPoints","type":"uint256"},{"indexed":false,"internalType":"bool","name":"newStageStarted","type":"bool"},{"indexed":false,"internalType":"uint256","name":"feesCollectedThisStage","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountTraded","type":"uint256"}],"name":"PriceUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stageId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feesCollected","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"buyersCount","type":"uint256"}],"name":"StageFinalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stageId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startTime","type":"uint256"}],"name":"StageStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"FLAUNT_ROUTER_CONTRACT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FLAUNT_WALLET","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LIQUIDITY_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LIQ_MANAGER_CONTRACT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_WALLET_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OWNER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PLATFORM_REWARDS_CONTRACT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REFERAL_REWARDS_CONTRACT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARDS_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKING_CONTRACT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOTAL_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"addInitialLiquidity","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"buyersInStage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentStageId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"feeCollectedPerStage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalFeesCollected","outputs":[{"internalType":"uint256","name":"totalFees","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"hasBoughtInStage","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"highestPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isInFeeStage","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastPurchaseTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRecoveryBasisPoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"limitsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidityAdded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"stageId","type":"uint256"}],"name":"pendingRewardByStage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"pendingRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"removeLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardClaimedInStage","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardPerTokenPerStage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sellFeeBasisPoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_router","type":"address"}],"name":"setUniswapV2Router","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_weth","type":"address"}],"name":"setWETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shutdownFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shutdownStep","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stageStartPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stageStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"totalBoughtPerStage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniswapV2Pair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userBoughtInStage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userLastStage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]