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

Name
Type
Description

_deployer

address

Address of the deployer of the token.

_name

string

Name of the token being deployed.

_symbol

string

Symbol of the token being deployed.

_totalSupply

uint256

Total supply to be minted during deployment.

_treasuryWallet

address

Address that will receive deployer buy and sell fees.

_penaltyTaxReceiver

address

Address that will receive penalty taxes.

_buyFee

uint16

Buy fee in BPS.

_sellFee

uint16

Sell fee in BPS.

_g8keepFee

uint16

Fee assessed by g8keep for trades in BPS.

_uniswapV2Router

address

Address of the Uniswap V2 Router.

_pairedToken

address

Address of the token to pair with in the LP.

_deployReserve

uint256

Amount of total supply in BPS to allocate to deployer.

_deployVestTime

uint256

Time in seconds to vest the deployer's allocation.

_snipeProtectionSeconds

uint256

Amount of time in seconds that snipe protection will be enabled.

_heavySnipeSeconds

uint256

Amount of time in seconds that heavy snipe penalty is enabled.

_heavySnipeExponent

uint256

Starting exponent for heavy snipe penalty.

maxSnipeProtectionBuyWithoutPenalty

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

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

Returns

Name
Type
Description

_amount

uint256

The amount of tokens that may be purchased without a snipe penalty.

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

Name
Type
Description

amount0In

uint256

The amount of paired token that will be input to the pool.

Returns

Name
Type
Description

amount1Out

uint256

The amount the buyer will receive.

penaltyAmount1Out

uint256

The amount that will be sent to the penalty receiver.

feesAmount1Out

uint256

The total fees to g8keep and deployer treasury.

balanceOf

Returns the token balance of account.

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

Parameters

Name
Type
Description

account

address

Address to retrieve the balance of.

Returns

Name
Type
Description

_balance

uint256

The token balance of account.

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

Name
Type
Description

owner

address

The owner of the tokens spender is allowed to transfer.

spender

address

The account authorized by owner to spend tokens on behalf of.

Returns

Name
Type
Description

_allowance

uint256

The amount of tokens of owner that spender is allowed to transfer.

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

Name
Type
Description

spender

address

Address of the account that the caller is authorizing.

amount

uint256

Amount of tokens the caller is authorizing spender to transfer.

transfer

Transfers amount of tokens from the caller to recipient.

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

Parameters

Name
Type
Description

recipient

address

Address that will receive the tokens from the caller.

amount

uint256

Amount of tokens to transfer to recipient.

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

Name
Type
Description

sender

address

Account to send the tokens from.

recipient

address

Address that will receive the tokens from sender.

amount

uint256

Amount of tokens to transfer to recipient from sender.

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

Name
Type
Description

newAddress

address

Address to set as the treasury wallet.

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

Name
Type
Description

_buyFee

uint16

Fee in BPS to assess on token buys.

_sellFee

uint16

Fee in BPS to assess on token sells.

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

Name
Type
Description

tokenAddress

address

Address of the token to withdraw.

to

address

Address to withdraw the token to.

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

Name
Type
Description

tokenAddress

address

Address of the token to withdraw.

to

address

Address to withdraw the token to.

amount

uint256

Amount of the token to withdraw.

_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

Name
Type
Description

owner

address

Account that owns the tokens being authorized. This will always be the caller.

spender

address

Address of the account that the caller is authorizing.

amount

uint256

Amount of tokens the caller is authorizing spender to transfer.

_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

Name
Type
Description

from

address

Address of the account to transfer tokens from.

to

address

Address of the account to transfer tokens to.

amount

uint256

Amount of tokens to transfer from from to to.

_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

Name
Type
Description

from

address

Address of the account to transfer tokens from.

amount

uint256

Amount of tokens to transfer from from.

deployerFee

uint256

Fee in BPS being assessed by the deployer.

Returns

Name
Type
Description

toAmount

uint256

Amount of tokens to transfer to the recipient after fees are applied.

_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

Name
Type
Description

from

address

Address of the account to transfer tokens from.

to

address

Address of the account to transfer tokens to.

amount1Out

uint256

Amount of tokens to transfer from from to to.

_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

Name
Type
Description

reserve0

uint256

The reserve of token0 in the LP when the token transfer is called.

reserve1

uint256

The reserve of token1 in the LP when the token transfer is called.

cachedThirdPartyLPAmount

uint256

Amount of tokens added to the LP by a third party.

_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

Name
Type
Description

reserve0

uint256

The reserve of token0 in the LP when the view function is called.

reserve1

uint256

The reserve of token1 in the LP when the view function is called.

cachedThirdPartyLPAmount

uint256

Amount of tokens added to the LP by a third party.

_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

Name
Type
Description

amount1Out

uint256

Amount of the token being purchased through the Uniswap V2 Pair.

cachedThirdPartyLPAmount

uint256

Amount of tokens added to the LP by a third party.

cachedLPBalanceBaseline

uint256

The baseline balance of the LP for snipe protection.

Returns

Name
Type
Description

adjustedAmount1Out

uint256

The amount out after adjusting for snipe protection.

penaltyAmount1Out

uint256

The amount out to the penalty receiver.

_getTokenReserves

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

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

Returns

Name
Type
Description

reserve0

uint256

The reserve of token0 in the LP.

reserve1

uint256

The reserve of token1 in the LP.

_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

Name
Type
Description

amountIn

uint256

The amount of tokens input to the pair.

reserveIn

uint256

The LP reserve of the input token.

reserveOut

uint256

The LP reserve of the token being purchased.

Returns

Name
Type
Description

amountOut

uint256

The calculated amount of output tokens.

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