g8keepToken

g8keepToken

Inherits: Ownable

An ERC20 implementation for the g8keep platform.

Key features of g8keepToken include:

  • Fee collection for deployers and guardrails for traders.

  • Fees may only be lowered by the deployer, never raised.

  • Automated snipe protection with a linear release of tokens without snipe penalties and exponential increase of penalty based on the purchase amount.

State Variables

name

Name of the token.

string public name;

symbol

Symbol of the token.

string public symbol;

decimals

Token decimals.

uint8 public constant decimals = 18;

totalSupply

Total supply of the token.

uint256 public immutable totalSupply;

G8KEEP

g8keep factory address to deposit g8keep fees.

address private immutable G8KEEP;

PENALTY_TAX_RECEIVER

Address that will receive penalty taxes.

address private immutable PENALTY_TAX_RECEIVER;

UNISWAP_V2_PAIR

Address of the Uniswap V2 pair.

address public immutable UNISWAP_V2_PAIR;

PAIRED_TOKEN

Address of the paired token.

address public immutable PAIRED_TOKEN;

BPS

Constant value for BPS.

uint16 private constant BPS = 10_000;

MAX_DEPLOYER_RESERVE

Constant value for the maximum deployer reserve of total supply in BPS.

uint16 private constant MAX_DEPLOYER_RESERVE = 300;

GENESIS_TIME

Timestamp of the token deployment - used for calculating snipe protection.

uint40 private immutable GENESIS_TIME;

SNIPE_PENALTY_BASE_EXPONENT

The base penalty exponent for snipe protection.

uint8 private constant SNIPE_PENALTY_BASE_EXPONENT = 2;

SNIPE_PROTECTION_SECONDS

Amount of time in seconds that snipe protection is enabled for.

uint40 public immutable SNIPE_PROTECTION_SECONDS;

SNIPE_PROTECTION_END

Timestamp of when snipe protection for the token ends.

uint40 public immutable SNIPE_PROTECTION_END;

SNIPE_PROTECTION_HEAVY_EXPONENT_START

Starting exponent for heavy snipe penalties.

uint8 public immutable SNIPE_PROTECTION_HEAVY_EXPONENT_START;

SNIPE_PROTECTION_HEAVY_PENALTY_SECONDS

Amount of time in seconds that heavy snipe penalties are enabled for.

uint40 public immutable SNIPE_PROTECTION_HEAVY_PENALTY_SECONDS;

G8KEEP_FEE

Fee in BPS assessed by g8keep for trades.

uint16 public immutable G8KEEP_FEE;

buyFee

Fee in BPS assessed by the deployer for buys.

uint16 public buyFee;

sellFee

Fee in BPS assessed by the deployer for sells.

uint16 public sellFee;

treasuryWallet

Address that will receive deployer trading fees.

address public treasuryWallet;

_balances

Mapping of token balances for token owners.

mapping(address => uint256) private _balances;

_allowances

Mapping of spender approvals.

mapping(address => mapping(address => uint256)) private _allowances;

lpBalanceBaseline

Baseline balance of the LP - used for calculating snipe protection.

uint256 private lpBalanceBaseline;

lastLPTotalSupply

Amount of LP token total supply last recorded - used for calculating thirdPartyLPAmount.

uint256 private lastLPTotalSupply;

thirdPartyLPAmount

Amount of token added to the LP by third parties.

uint112 private thirdPartyLPAmount;

cachedLPReserve1

Cached value of the LP token reserve - used for calculating thirdPartyLPAmount.

uint112 private cachedLPReserve1;

Functions

constructor

Constructs the g8keep token.

constructor(
    address _deployer,
    string memory _name,
    string memory _symbol,
    uint256 _totalSupply,
    address _treasuryWallet,
    address _penaltyTaxReceiver,
    uint16 _buyFee,
    uint16 _sellFee,
    uint16 _g8keepFee,
    address _uniswapV2Router,
    address _pairedToken,
    uint256 _deployReserve,
    uint256 _deployVestTime,
    uint256 _snipeProtectionSeconds,
    uint256 _heavySnipeSeconds,
    uint256 _heavySnipeExponent
);

Parameters

maxSnipeProtectionBuyWithoutPenalty

Calculates the amount of tokens that may be purchased without a snipe protection penalty.

function maxSnipeProtectionBuyWithoutPenalty() external view returns (uint256 _amount);

Returns

expectedAmount1Out

Calculates the expected output amounts to buyer, penalty and fees for the amount0In, accounts for snipe protection penalties and current fee settings.

function expectedAmount1Out(uint256 amount0In)
    external
    view
    returns (uint256 amount1Out, uint256 penaltyAmount1Out, uint256 feesAmount1Out);

Parameters

Returns

balanceOf

Returns the token balance of account.

function balanceOf(address account) public view returns (uint256 _balance);

Parameters

Returns

allowance

Returns the amount owner has authorized spender to transfer.

An allowance of type(uint256).max is considered an unlimited allowance.

function allowance(address owner, address spender) public view returns (uint256 _allowance);

Parameters

Returns

approve

Sets the allowed amount that spender may transfer on behalf of the caller.

An amount of type(uint256).max is considered an unlimited allowance.

function approve(address spender, uint256 amount) external returns (bool);

Parameters

transfer

Transfers amount of tokens from the caller to recipient.

function transfer(address recipient, uint256 amount) external returns (bool);

Parameters

transferFrom

Transfers amount of tokens from sender to recipient if the caller has a sufficient allowance set by sender.

function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

Parameters

updateTreasuryWallet

Admin function for the token owner to set a new treasury wallet to receive fees.

The address may not be set to the zero address or the Uniswap V2 Pair.

function updateTreasuryWallet(address newAddress) external onlyOwner;

Parameters

updateFees

Admin function for the token owner to set new buy and sell fees.

The buy and sell fees may not be set higher than the current fees.

function updateFees(uint16 _buyFee, uint16 _sellFee) external onlyOwner;

Parameters

withdrawToken

Admin function for the token owner to recover tokens mistakenly sent to the token contract.

Will withdraw the entire balance of the token.

function withdrawToken(address tokenAddress, address to) external onlyOwner;

Parameters

withdrawToken

Admin function for the token owner to recover tokens mistakenly sent to the token contract.

Will withdraw the specified amount of token.

function withdrawToken(address tokenAddress, address to, uint256 amount) external onlyOwner;

Parameters

_approve

Internal function to handle approvals.

Updates the _allowances mapping and emits an Approval event.

function _approve(address owner, address spender, uint256 amount) private;

Parameters

_transfer

Internal function to handle transfers.

Adjusts amount based on snipe protection calculations while enabled.

Applies fees when the transfer is going to or coming from the Uniswap V2 Pair.

Updates the _balances mapping for from and to and emits a Transfer event.

function _transfer(address from, address to, uint256 amount) private;

Parameters

_applyFees

Internal function to apply buy and sell fees.

Updates the _balances mapping for _treasuryWallet and G8KEEP and emits Transfer events if their calculated fees are greater than zero.

function _applyFees(address from, uint256 amount, uint256 deployerFee) internal returns (uint256 toAmount);

Parameters

Returns

_applySnipeProtection

Internal function to check if snipe protection is enabled and adjust the output amount if it is and the amount exceeds the maximum buy without a snipe penalty.

function _applySnipeProtection(address from, address to, uint256 amount1Out)
    internal
    returns (uint256 adjustedAmount1Out);

Parameters

_checkLPForIncrease

Internal function used during snipe protection to determine if tokens have been added to the LP by a third party so that snipe protection can be applied appropriately.

Returns the LP reserves for use in _adjustAmountOut for efficiency.

Returns the third party LP amount for use in _adjustAmountOut for efficiency.

function _checkLPForIncrease()
    internal
    returns (uint256 reserve0, uint256 reserve1, uint256 cachedThirdPartyLPAmount);

Returns

_checkLPForIncreaseView

Internal function used in view functions to determine if tokens have been added to the LP by a third party so that snipe protection calculations can be applied appropriately.

Returns the LP reserves for use in _adjustAmountOut for efficiency.

Returns the third party LP amount for use in _adjustAmountOut for efficiency.

function _checkLPForIncreaseView()
    internal
    view
    returns (uint256 reserve0, uint256 reserve1, uint256 cachedThirdPartyLPAmount);

Returns

_adjustAmountOut

Internal function to adjust the amount of tokens being purchased from the Uniswap V2 Pair during snipe protection when the purchase amount exceeds the maximum amount that can be purchased without a penalty.

Tokens are released for purchase without snipe protection penalty linearly during the snipe protection window and penalties increase exponentially when exceeding the expected balance of the Uniswap V2 Pair.

For example:

A token with 100,000 tokens in the initial LP and snipe protection timeof 60 minutes will have 25,000 tokens available to purchase without penalty after the token has been deployed for 15 minutes for an expected LP balance of 75,000 tokens.

A buyer that attempts to purchase 62,500 tokens would result in a 37,500 token balance in the LP which is 50% of expected balance.

Their adjustedAmount1Out would equal 62,500 * 0.5^2 = 15,625 tokens (75% penalty).

Instead of attempting to buy 62,500 tokens, the user should buy the 25,000 tokens that are available without snipe protection to avoid penalty.

Within the regular snipe protection window there is also a heavy penalty window. During the heavy penalty window the exponent for applying the penalty starts at a higher value and decreases linearly until it reaches the base exponent of 2.

For example:

Using the example from above with a heavy snipe window of 10 minutes and a starting penalty exponent of 12. After 6 minutes, there will be 10,000 tokens available to purchase, expected balance 90,000 tokens, and the snipe penalty exponent will be 6.

A buyer that attempts to purchase 55,000 tokens would result in a 45,000 token balance in the LP which is 50% of the expected balance.

Their adjustedAmount1Out would equal 55,000 * 0.5^6 = 859.375 tokens (98.5% penalty).

Instead of attempting to purchase 55,0000 tokens, the user should buy the 10,000 tokens that are available without snipe protection to avoid penalty.

function _adjustAmountOut(uint256 amount1Out, uint256 cachedThirdPartyLPAmount, uint256 cachedLPBalanceBaseline)
    internal
    view
    returns (uint256 adjustedAmount1Out, uint256 penaltyAmount1Out);

Parameters

Returns

_getTokenReserves

Internal function to get the token reserve balances from the Uniswap V2 Pair.

function _getTokenReserves() internal view returns (uint256 reserve0, uint256 reserve1);

Returns

_getAmountOut

Internal function to calculate the amount of tokens expected to be received from a purchase with amountIn. This is the same formula used by the Uniswap V2 Router when calculating output amount.

function _getAmountOut(uint256 amountIn, uint256 reserveIn, uint256 reserveOut)
    internal
    pure
    returns (uint256 amountOut);

Parameters

Returns

Events

Approval

Emitted when an approval is updated.

event Approval(address indexed owner, address indexed spender, uint256 value);

DeployerFeesUpdated

Emitted when deployer fees are updated.

event DeployerFeesUpdated(uint16 buyFee, uint16 sellFee);

Transfer

Emitted when a token balance is transfered.

event Transfer(address indexed from, address indexed to, uint256 value);

TreasuryWalletUpdated

Emitted when the treasury wallet is updated.

event TreasuryWalletUpdated(address treasuryWallet);

Errors

CannotBurnLiquidityDuringSnipeProtection

Thrown when attempting to burn an LP position during snipe protection.

error CannotBurnLiquidityDuringSnipeProtection();

CannotIncreaseFees

Thrown when deployer attempts to set fees higher than the current settings.

error CannotIncreaseFees();

CannotTransferFromAndToUniswapV2Pair

Thrown when attempting to transfer tokens from and to the Uniswap V2 Pair.

error CannotTransferFromAndToUniswapV2Pair();

ExcessiveAmountOut

Thrown when the transfer amount on a buy exceeds the value the Uniswap V2 Router calculates.

error ExcessiveAmountOut();

InsufficientAllowance

Thrown when the spender does not have a sufficient allowance for the transfer being made.

error InsufficientAllowance();

InsufficientBalance

Thrown when a transfer amount exceeds the sender's balance.

error InsufficientBalance();

InsufficientPoolInput

Thrown during snipe protection when purchasing tokens and the paired token balance decreases.

error InsufficientPoolInput();

InvalidHeavySnipeParameters

Thrown during deployment if the heavy snipe exponent exceeds type(uint8).max or is less than the base snipe exponent.

error InvalidHeavySnipeParameters();

InvalidReserves

Thrown when calculating maximum amount out and the reserve balances are zero.

error InvalidReserves();

InvalidTokenAddress

Thrown during deployment if the token address is not greater than the paired token address.

error InvalidTokenAddress();

ReserveExceedsMax

Thrown during deployment if the deployer requests a deployer reserve greater than the maximum setting.

error ReserveExceedsMax();

SnipeProtectionTimeOverflow

Thrown during deployment if the snipe protection time will overflow a uint40 value.

error SnipeProtectionTimeOverflow();

InvalidTreasuryAddress

Thrown when attempting to set the treasury wallet address to the zero address or the Uniswap V2 pair.

error InvalidTreasuryAddress();

SupplyExceedsMax

Thrown during deployment if the supply exceeds the maximum allowed by Uniswap V2.

error SupplyExceedsMax();

ZeroAddress

Thrown when setting an approval or attempting to transfer tokens to the zero address.

error ZeroAddress();

Last updated