DeeprTemplate.sol
Smart Contract Reference
This document provides a detailed breakdown of the DeeprTemplate.sol
smart contract, which is the core engine for launching tokens on the Deepr.fun platform. The native $DEEPR
token, deployed at on Base, was the first token launched using this template.
Overview
The DeeprTemplate
contract is an ERC20 token contract that includes a comprehensive suite of features for managing a token launch through a progressive, multi-tranche system. It integrates with Uniswap V2 for liquidity provision and incorporates anti-manipulation mechanisms.
Inherits from:
ERC20.sol
(OpenZeppelin): Standard ERC20 token implementation.ReentrancyGuard.sol
(OpenZeppelin): Protects against reentrancy attacks.
State Variables
Core Addresses & Configuration
uniswapV2Router
:IUniswapV2Router02
- The Uniswap V2 router interface used for adding liquidity.uniswapV2Pair
:IUniswapV2Pair
- The Uniswap V2 pair interface for this token and WETH.deployer
:address immutable
- The address of the account that deployed this contract instance. This address receives a portion of the ETH fees.DEEPR_VAULT
:address immutable
- The fixed address of the Deepr platform’s vault, which receives a portion of ETH fees from all launches. (Constant:0x4F8411a4Ff4E9Ad6905612009CDcB8367602b4Fc
)DEEPR_AIRDROP
:address immutable
- The fixed address for Deepr platform airdrops, which receives all token fees from all launches. (Constant:0xF08B1fE0Cf1210F83a5f8C026c0Fd4f717D195FE
)trancheFee
:uint256
- The fee percentage applied to both ETH and tokens during liquidity events (tranche purchases). Set to1000
(representing 10.00%).maxPriorityFee
:uint256
- The maximum allowed priority fee (tip) for transactions interacting with the contract’s core functions or the LP, designed to deter MEV bots. Set to3 * 1e9
(3 gwei).
Tranche System Variables
initialPricePerToken
:uint256
- The price per token in ETH (scaled by 1e18) for the initial tranche (Tranche 0). Calculated in the constructor based onethRaiseinWei_
andtrancheSupply[0]
.priceMultiples
:uint256[14]
- An array defining the price multiplier for each of the 14 tranches relative toinitialPricePerToken
. Tranchei
unlocks when the market price reachesinitialPricePerToken * priceMultiples[i]
.trancheRelease
:uint256[14]
- An array defining the percentage of the total supply allocated to each of the 14 tranches (scaled by 100, e.g., 2200 means 22.00%).trancheMaxPurchase
:uint256[14]
- An array storing the maximum amount of tokens a single wallet can purchase from each respective tranche. Calculated in the constructor based ontrancheSupply
and predefined percentages.trancheSupply
:uint256[14]
- An array storing the total number of tokens available in each respective tranche. Calculated in the constructor based ontotalSupply_
andtrancheRelease
percentages.trancheSold
:uint256[14]
- An array tracking the number of tokens sold in each respective tranche.
Launch State
initialLiquidityDeployed
:bool
- A flag indicating whether the initial liquidity (from Tranche 0 sales) has been deployed to Uniswap. Startsfalse
.
Contributor Tracking
initialContributors
:address[]
- An array storing the addresses of users who have participated in thebuyInitialTranche
function.isInitialContributor
:mapping(address => bool)
- Maps an address to a boolean indicating if they have participated in thebuyInitialTranche
function.userTranchePurchases
:mapping(address => uint256[14])
- Maps a user’s address to an array tracking the total amount of tokens they have purchased from each tranche.userTrancheETHPaid
:mapping(address => uint256[14])
- Maps a user’s address to an array tracking the total amount of ETH they have paid for tokens in each tranche.
Events
-
InitialTranchePurchase(address indexed buyer, uint256 amount)
- Emitted when a user successfully purchases tokens from Tranche 0.
buyer
: The address of the purchaser.amount
: The number of tokens purchased.
-
TrancheTokensPurchased(address indexed buyer, uint256 trancheIndex, uint256 amount)
- Emitted when a user successfully purchases tokens from Tranches 1-13.
buyer
: The address of the purchaser.trancheIndex
: The index of the tranche from which tokens were purchased.amount
: The number of tokens purchased.
-
InitialTrancheRefunded(address indexed buyer, uint256 amount)
- Emitted when a user successfully refunds their Tranche 0 purchase.
buyer
: The address of the user receiving the refund.amount
: The number of tokens for which the contribution was refunded.
-
TrancheCompleted(uint256 indexed trancheIndex, uint256 totalSold, uint256 blockNumber)
- Emitted when a tranche (0-13) becomes fully sold out.
trancheIndex
: The index of the completed tranche.totalSold
: The total amount of tokens sold in that tranche.blockNumber
: The block number at which the tranche was completed.
Custom Errors
These errors provide specific reasons for transaction reversions.
LiquidityDeployed()
: Reverts if an action is attempted that is only allowed before initial liquidity is deployed (e.g.,buyInitialTranche
,refundInitialTranche
), butinitialLiquidityDeployed
is true.LiquidityNotDeployed()
: Reverts if an action is attempted that requires initial liquidity to be deployed (e.g.,buyTranche
), butinitialLiquidityDeployed
is false.ZeroETHSent()
: Reverts if a payable function (e.g.,buyInitialTranche
,buyTranche
) is called withmsg.value
of 0.InvalidTrancheIndex()
: Reverts ifbuyTranche
is called with atrancheIndex
that is 0 or out of the valid range (1-13).InvalidPriceDifference()
: Reverts inbuyTranche
ifmaxPriceDifferencePercent
is less than 100 (i.e., less than 0% actual difference, which is illogical as it should be at least the tranche price).TranchePriceExceedsMarket()
: Reverts inbuyTranche
if the calculatedtranchePrice
for the target tranche is greater than the currentcurrentPrice
fetched from the DEX.PriceOutsideRange()
: Reverts inbuyTranche
if thecurrentPrice
from the DEX is higher than the maximum acceptable price (tranchePrice
+tranchePrice * maxPriceDifferencePercent / 10000
).TrancheSoldOut()
: Reverts if a purchase is attempted from a tranche that is already fully sold (trancheSold[i] >= trancheSupply[i]
).InsufficientTokenBalance()
: Reverts if the contract itself does not have enough tokens to fulfill a purchase or liquidity operation (e.g., inbuyTranche
before transferring tokens to the buyer or adding to LP).InsufficientETHBalance()
: Reverts in_deployInitialLiquidity
if the contract’s ETH balance is zero when trying to deploy initial liquidity.WalletLimitReached()
: Reverts if a user tries to purchase more tokens from a tranche than theirtrancheMaxPurchase[i]
limit for that tranche allows.NoRefundAvailable()
: Reverts inrefundInitialTranche
if the user has not made any purchase in Tranche 0 or has already refunded.InitialSaleEnded()
: (Note: This error is defined but not explicitly used in the provided code. It might be intended for future use or was removed.)MaxPriorityFeeExceeded()
: Reverts if the transaction’s priority fee (tx.gasprice - block.basefee
) is greater thanmaxPriorityFee
. This is checked by thecheckPriorityFee
modifier.
Modifiers
checkPriorityFee
- This modifier checks if the priority fee of the current transaction exceeds the
maxPriorityFee
state variable. - If
(tx.gasprice - block.basefee) > maxPriorityFee
, the transaction reverts withMaxPriorityFeeExceeded()
. - Applied to
buyInitialTranche
andbuyTranche
functions, and implicitly to DEX interactions via the overridden_update
function.
- This modifier checks if the priority fee of the current transaction exceeds the
Functions
constructor
constructor(
address uniswapV2Router_,
uint256 totalSupply_,
uint256 ethRaiseinWei_,
string memory name_,
string memory symbol_
) ERC20(name_, symbol_)
- Purpose: Initializes the contract, sets up ERC20 properties, tranche parameters, Uniswap integration, and mints the total supply.
- Parameters:
uniswapV2Router_
: Address of the Uniswap V2 Router.totalSupply_
: The total supply of the token to be created.ethRaiseinWei_
: The target amount of ETH (in wei) to be raised from the sale of Tranche 0. This is used to calculateinitialPricePerToken
.name_
: The name of the ERC20 token (e.g., “My Token”).symbol_
: The symbol of the ERC20 token (e.g., “MTK”).
- Dev Notes:
- Sets
deployer
tomsg.sender
. - Calculates
trancheSupply
for all 14 tranches based ontotalSupply_
and the predefinedtrancheRelease
percentages. - Calculates
trancheMaxPurchase
limits for all 14 tranches based on their respectivetrancheSupply
and predefined percentage limits (5% for tranches 0-2, 10% for 3-5, 20% for 6-8, and 100% for 9-13). - Initializes
uniswapV2Router
with the provided address. - Creates a new Uniswap V2 pair for this token and WETH using the factory from the router, and stores its address in
uniswapV2Pair
. - Calculates
initialPricePerToken = (ethRaiseinWei_ * 1e18) / trancheSupply[0]
. - Mints the
totalSupply_
to the contract itself (address(this)
).
- Sets
receive
receive() external payable {}
- Purpose: Fallback function to allow the contract to receive ETH directly (e.g., via a simple transfer without function call data).
buyInitialTranche
function buyInitialTranche() external payable nonReentrant checkPriorityFee
- Purpose: Allows users to purchase tokens from Tranche 0 (the initial sale phase) before liquidity is deployed.
- Visibility:
external payable
- Modifiers:
nonReentrant
,checkPriorityFee
- Logic:
- Pre-conditions:
- Reverts with
LiquidityDeployed()
ifinitialLiquidityDeployed
is true. - Reverts with
ZeroETHSent()
ifmsg.value
is 0. - Reverts with
TrancheSoldOut()
iftrancheSold[0]
is already equal to or greater thantrancheSupply[0]
. - Reverts with
WalletLimitReached()
ifuserTranchePurchases[msg.sender][0]
is already equal to or greater thantrancheMaxPurchase[0]
.
- Reverts with
- Calculate Purchase:
- Calls
_calculatePurchaseAmount(0, msg.value, initialPricePerToken)
to determinetokensToBuy
based on ETH sent, remaining supply in Tranche 0, and the user’s remaining purchase limit for Tranche 0. - Calculates
cost = (tokensToBuy * initialPricePerToken) / 1e18
.
- Calls
- Track Contribution:
- Adds
cost
touserTrancheETHPaid[msg.sender][0]
. - If
!isInitialContributor[msg.sender]
, addsmsg.sender
toinitialContributors
array and setsisInitialContributor[msg.sender]
to true.
- Adds
- Update State:
- Increases
trancheSold[0]
bytokensToBuy
. - Increases
userTranchePurchases[msg.sender][0]
bytokensToBuy
. (Note: Tokens are not transferred yet, only accounted for).
- Increases
- Refund Excess ETH: If
msg.value > cost
, refundsmsg.value - cost
tomsg.sender
immediately. - Handle Tranche 0 Completion:
- If
trancheSold[0] >= trancheSupply[0]
(Tranche 0 is now fully sold):- Calls
_distributeInitialTokens()
to transfer the purchased tokens from the contract to all contributors of Tranche 0. - Calls
_deployInitialLiquidity()
to take the ETH collected in the contract and pair it with an equivalent value of tokens (specificallytrancheSupply[0]
tokens, effectively the other 22% for LP) to add to the Uniswap pool. This also handles fees. - Emits
TrancheCompleted(0, trancheSold[0], block.number)
.
- Calls
- If
- Emits
InitialTranchePurchase(msg.sender, tokensToBuy)
.
- Pre-conditions:
_distributeInitialTokens
function _distributeInitialTokens() internal
- Purpose: Internal function called when Tranche 0 is fully sold to transfer the purchased tokens to all contributors.
- Logic:
- Iterates through the
initialContributors
array. - For each
contributor
, retrieves theamount = userTranchePurchases[contributor][0]
. - If
amount > 0
:- Transfers
amount
tokens fromaddress(this)
(the contract) tocontributor
. - Resets
userTranchePurchases[contributor][0]
to 0 (as tokens are now distributed).
- Transfers
- Iterates through the
_deployInitialLiquidity
function _deployInitialLiquidity() internal
- Purpose: Internal function called after Tranche 0 is sold out and tokens are distributed, to deploy the initial liquidity to Uniswap.
- Logic:
- Pre-condition: Reverts with
InsufficientETHBalance()
ifaddress(this).balance == 0
. - Determine Amounts:
ethForLiquidity
is set to the contract’s current ETH balance (which should be the total ETH raised from Tranche 0 sales).tokensForLiquidity
is set totrancheSupply[0]
(this is the 22% of total supply specifically allocated for pairing with the raised ETH for initial LP).
- Add Liquidity & Handle Fees: Calls
_handleFeesAndLiquidity(tokensForLiquidity, ethForLiquidity)
. This internal function will:- Calculate and deduct fees (10% of
tokensForLiquidity
and 10% ofethForLiquidity
). - Distribute these fees (ETH to deployer & Deepr Vault, tokens to Deepr Airdrop).
- Add the remaining tokens and ETH to the Uniswap V2 liquidity pool.
- Calculate and deduct fees (10% of
- Update State: Sets
initialLiquidityDeployed
totrue
.
- Pre-condition: Reverts with
refundInitialTranche
function refundInitialTranche() external nonReentrant
- Purpose: Allows users to get a refund for their contribution to Tranche 0, only before initial liquidity has been deployed.
- Visibility:
external
- Modifiers:
nonReentrant
- Logic:
- Pre-conditions:
- Reverts with
LiquidityDeployed()
ifinitialLiquidityDeployed
is true. refundAmount = userTranchePurchases[msg.sender][0]
. Reverts withNoRefundAvailable()
ifrefundAmount == 0
.
- Reverts with
- Process Refund:
ethToRefund = userTrancheETHPaid[msg.sender][0]
.- Resets
userTranchePurchases[msg.sender][0]
to 0. - Resets
userTrancheETHPaid[msg.sender][0]
to 0. - Decreases
trancheSold[0]
byrefundAmount
.
- Update Contributor List:
- If
isInitialContributor[msg.sender]
is true:- Sets
isInitialContributor[msg.sender]
tofalse
. - Removes
msg.sender
from theinitialContributors
array (using the swap-and-pop technique for efficiency).
- Sets
- If
- Send ETH: Transfers
ethToRefund
tomsg.sender
. - Emits
InitialTrancheRefunded(msg.sender, refundAmount)
.
- Pre-conditions:
buyTranche
function buyTranche(uint256 trancheIndex, uint256 maxPriceDifferencePercent) external payable nonReentrant checkPriorityFee
- Purpose: Allows users to purchase tokens from active subsequent tranches (1-13) after initial liquidity is deployed. The ETH paid and corresponding tokens (after fees) are immediately added to the Uniswap liquidity pool.
- Parameters:
trancheIndex
: The index of the tranche to buy from (must be 1-13).maxPriceDifferencePercent
: The maximum acceptable positive deviation of the current DEX price from the target tranche price, in basis points (e.g., 100 means 1% slippage above the tranche price is acceptable, 10000 means 100% above).
- Visibility:
external payable
- Modifiers:
nonReentrant
,checkPriorityFee
- Logic:
- Pre-conditions:
- Reverts with
LiquidityNotDeployed()
ifinitialLiquidityDeployed
is false. - Reverts with
ZeroETHSent()
ifmsg.value
is 0. - Reverts with
InvalidTrancheIndex()
iftrancheIndex
is 0 or >=priceMultiples.length
(i.e., not 1-13). - Reverts with
InvalidPriceDifference()
ifmaxPriceDifferencePercent < 100
(less than 0% actual difference). - Reverts with
TrancheSoldOut()
iftrancheSold[trancheIndex]
is already >=trancheSupply[trancheIndex]
. - Reverts with
WalletLimitReached()
ifuserTranchePurchases[msg.sender][trancheIndex]
is already >=trancheMaxPurchase[trancheIndex]
.
- Reverts with
- Price Validation:
currentPrice = getTokenPriceInETH()
(fetches current price from Uniswap pair).tranchePrice = initialPricePerToken * priceMultiples[trancheIndex]
.- Reverts with
TranchePriceExceedsMarket()
ifcurrentPrice < tranchePrice
(tranche not yet unlocked by market price). - Reverts with
PriceOutsideRange()
ifcurrentPrice > (tranchePrice + (tranchePrice * maxPriceDifferencePercent / 10000))
.
- Calculate Purchase Amount:
tokensToBuy = _calculatePurchaseAmount(trancheIndex, msg.value, currentPrice)
. This considers ETH sent, remaining tranche supply, and user’s wallet limit for that tranche, all based oncurrentPrice
.ethToUse = (tokensToBuy * currentPrice) / 1e18
.- Reverts with
InsufficientTokenBalance()
ifbalanceOf(address(this)) < tokensToBuy
(contract must hold enough tokens to sell and for LP).
- Handle Fees & Liquidity:
- Calls
_handleFeesAndLiquidity(tokensToBuy, ethToUse)
. This internal function:- Calculates and deducts 10% fees from
tokensToBuy
andethToUse
. - Distributes ETH fees (75% to deployer, 25% to
DEEPR_VAULT
). - Distributes token fees (100% to
DEEPR_AIRDROP
). - Adds the remaining tokens and ETH to the Uniswap liquidity pool.
- Calculates and deducts 10% fees from
- Calls
- Update State:
- Increases
trancheSold[trancheIndex]
bytokensToBuy
. - Increases
userTranchePurchases[msg.sender][trancheIndex]
bytokensToBuy
. - Increases
userTrancheETHPaid[msg.sender][trancheIndex]
byethToUse
.
- Increases
- Refund Excess ETH: If
msg.value > ethToUse
, refundsmsg.value - ethToUse
tomsg.sender
. - Transfer Tokens: Transfers
tokensToBuy
fromaddress(this)
tomsg.sender
. - Handle Tranche Completion: If
trancheSold[trancheIndex] >= trancheSupply[trancheIndex]
, emitsTrancheCompleted(trancheIndex, trancheSold[trancheIndex], block.number)
. - Emits
TrancheTokensPurchased(msg.sender, trancheIndex, tokensToBuy)
.
- Pre-conditions:
_calculatePurchaseAmount
function _calculatePurchaseAmount(
uint256 trancheIndex,
uint256 ethSent,
uint256 price
) private view returns (uint256)
- Purpose: Internal view function to calculate the maximum number of tokens a user can purchase from a given tranche based on several constraints.
- Parameters:
trancheIndex
: The index of the tranche.ethSent
: The amount of ETH the user sent with the transaction.price
: The price per token (in ETH, scaled by 1e18) to use for the calculation (eitherinitialPricePerToken
for Tranche 0 orcurrentPrice
for others).
- Returns:
uint256
- The number of tokens the user can actually purchase. - Logic:
- Returns 0 if
price == 0
to prevent division by zero. maxTokensForEth = (ethSent * 1e18) / price
: Max tokens user can afford withethSent
.remainingWalletLimit = trancheMaxPurchase[trancheIndex] - userTranchePurchases[msg.sender][trancheIndex]
: Max tokens user can still buy from this tranche due to their personal limit.remainingTokens = trancheSupply[trancheIndex] - trancheSold[trancheIndex]
: Tokens still available in this tranche.- Returns the minimum of these three values:
Math.min(Math.min(maxTokensForEth, remainingTokens), remainingWalletLimit)
.
- Returns 0 if
_handleFeesAndLiquidity
function _handleFeesAndLiquidity(uint256 tokensForLiquidity, uint256 ethForLiquidity) private
- Purpose: Internal function to manage fee distribution and add the remaining amounts to Uniswap liquidity. This is called by
_deployInitialLiquidity
(for Tranche 0) andbuyTranche
(for Tranches 1-13). - Parameters:
tokensForLiquidity
: The gross amount of tokens intended for liquidity (before fees).ethForLiquidity
: The gross amount of ETH intended for liquidity (before fees).
- Logic:
- Calculate Fees:
feeTokens = tokensForLiquidity * trancheFee / 10000
(10% of tokens).feeEth = ethForLiquidity * trancheFee / 10000
(10% of ETH).
- Calculate ETH Fee Distribution:
deployerEthShare = feeEth * 75 / 100
(75% offeeEth
todeployer
).vaultEthShare = feeEth - deployerEthShare
(remaining 25% offeeEth
toDEEPR_VAULT
).
- Calculate Net Amounts for Liquidity:
tokensToAdd = tokensForLiquidity - feeTokens
.ethToAdd = ethForLiquidity - feeEth
.
- Calculate Minimum Amounts (Slippage Protection for LP add):
minTokens = (tokensToAdd * 95) / 100
(95% oftokensToAdd
, i.e., 5% slippage tolerance).minETH = (ethToAdd * 95) / 100
(95% ofethToAdd
).
- Approve Router:
_approve(address(this), address(uniswapV2Router), tokensToAdd)
to allow the router to pulltokensToAdd
from the contract. - Transfer Fees:
- If
deployerEthShare > 0
, transfersdeployerEthShare
todeployer
. - If
vaultEthShare > 0
, transfersvaultEthShare
toDEEPR_VAULT
. - If
feeTokens > 0
, transfersfeeTokens
(100% of token fee) fromaddress(this)
toDEEPR_AIRDROP
.
- If
- Add Liquidity:
- If
tokensToAdd > 0
andethToAdd > 0
:- Calls
uniswapV2Router.addLiquidityETH{value: ethToAdd}
with:token
:address(this)
amountTokenDesired
:tokensToAdd
amountTokenMin
:minTokens
amountETHMin
:minETH
to
:address(0x0)
(Liquidity tokens can be sent to address(0) which often means they are effectively burned or managed by the router for the LP provider, which in this context is the contract itself initially, though the LP tokens effectively go to the0x0
address which is typical foraddLiquidityETH
when theto
recipient is not the contract ormsg.sender
. For Deepr’s direct LP add, this means the LP tokens are not held by the contract but by the pair itself, managed by Uniswap.)deadline
:block.timestamp
(immediate execution).
- Calls
- If
- Calculate Fees:
getAvailableTranches
function getAvailableTranches() public view returns (bool[14] memory)
- Purpose: View function to get a list of all tranches (0-13) that are generally available for purchase.
- Returns:
bool[14] memory
- An array whereavailableTranches[i]
is true if tranchei
is available. - Logic:
currentPrice = getTokenPriceInETH()
.- Iterates from
i = 0
topriceMultiples.length - 1
:tranchePrice = initialPricePerToken * priceMultiples[i]
.- Tranche
i
is available if:trancheSold[i] < trancheSupply[i]
(not sold out) AND- (
currentPrice >= tranchePrice
(market price meets or exceeds tranche unlock price) ORi == 0
(Tranche 0 is always available if not sold out and before LP deployed, this check ensures it shows as available initially)).
- Sets
availableTranches[i]
accordingly.
getUserAvailableTranches
function getUserAvailableTranches(address user) public view returns (bool[14] memory)
- Purpose: View function to get a list of tranches available for a specific user, considering both general availability and the user’s purchase limits.
- Parameters:
user
: The address of the user to check.
- Returns:
bool[14] memory
- An array whereuserAvailable[i]
is true if tranchei
is available for this specificuser
. - Logic:
availableTranches = getAvailableTranches()
(gets general availability).- Iterates from
i = 0
topriceMultiples.length - 1
:- Tranche
i
is available foruser
if:availableTranches[i]
is true (it’s generally available) ANDuserTranchePurchases[user][i] < trancheMaxPurchase[i]
(user has not hit their personal purchase limit for this tranche).
- Sets
userAvailable[i]
accordingly.
- Tranche
getTokenPriceInETH
function getTokenPriceInETH() public view returns (uint256)
- Purpose: View function to get the current price of one token in ETH from the Uniswap V2 pair.
- Returns:
uint256
- The price of 1 full token in wei. ReturnsinitialPricePerToken
if liquidity is not yet deployed or reserves are zero. - Logic:
- Fetches
reserve0
,reserve1
fromIUniswapV2Pair(uniswapV2Pair).getReserves()
. - If
reserve0 == 0
orreserve1 == 0
(no liquidity or invalid pair state), returnsinitialPricePerToken
. - Determines which reserve belongs to this token (
address(this)
) and which to WETH by comparing withIUniswapV2Pair(uniswapV2Pair).token0()
. - Calculates price:
(ETH_reserve * 1e18) / Token_reserve
.
- Fetches
getFDV
function getFDV() public view returns (uint256 fdv)
- Purpose: View function to get the current Fully Diluted Valuation (FDV) of the token in ETH.
- Returns:
uint256 fdv
- The FDV in wei. Returns 0 if initial liquidity is not deployed. - Logic:
- If
!initialLiquidityDeployed
, returns 0. currentPrice = getTokenPriceInETH()
.fdv = (totalSupply() * currentPrice) / 1e18
.
- If
getMarketCap
function getMarketCap() public view returns (uint256 marketCap)
- Purpose: View function to get the current Market Cap of the token in ETH based on circulating supply.
- Returns:
uint256 marketCap
- The Market Cap in wei. Returns 0 if initial liquidity is not deployed. - Logic:
- If
!initialLiquidityDeployed
, returns 0. currentPrice = getTokenPriceInETH()
.circulatingSupply = totalSupply() - balanceOf(address(this))
(total supply minus tokens held by the contract).marketCap = (circulatingSupply * currentPrice) / 1e18
.
- If
getLiquidity
function getLiquidity() public view returns (uint256 liquidity)
- Purpose: View function to get the current total value of liquidity in the Uniswap pair, expressed in ETH.
- Returns:
uint256 liquidity
- Total liquidity value in wei (effectively 2 * ETH balance of the pair). Returns 0 if initial liquidity is not deployed. - Logic:
- If
!initialLiquidityDeployed
, returns 0. weth = uniswapV2Router.WETH()
.liquidity = IERC20(weth).balanceOf(address(uniswapV2Pair)) * 2
.
- If
getStaticContractData
function getStaticContractData() public view returns (
string memory _name,
string memory _symbol,
uint256 _totalSupply,
uint256 _initialPricePerToken,
address _uniswapV2Pair,
uint256[14] memory _priceMultiples,
uint256[14] memory _trancheMaxPurchase,
uint256[14] memory _trancheSupply
)
- Purpose: View function to retrieve a bundle of static configuration data set at contract deployment.
- Returns:
_name
: Token name._symbol
: Token symbol._totalSupply
: Total token supply._initialPricePerToken
: Initial price for Tranche 0._uniswapV2Pair
: Address of the Uniswap pair._priceMultiples
: Array of price multipliers for tranches._trancheMaxPurchase
: Array of max purchase limits per tranche per wallet._trancheSupply
: Array of token supply per tranche.
getDynamicContractData
function getDynamicContractData() public view returns (
bool _initialLiquidityDeployed,
uint256[14] memory _trancheSold,
bool[14] memory _availableTranches,
uint256 _currentPriceETH,
uint256 _marketCap,
uint256 _fdv,
uint256 _liquidity
)
- Purpose: View function to retrieve a bundle of dynamic data reflecting the current state of the launch and market.
- Returns:
_initialLiquidityDeployed
: Boolean, true if initial LP is deployed._trancheSold
: Array showing tokens sold per tranche._availableTranches
: Boolean array of generally available tranches._currentPriceETH
: Current token price in ETH from DEX._marketCap
: Current market cap in ETH._fdv
: Current FDV in ETH._liquidity
: Current total liquidity value in ETH in the Uniswap pool.
getUserData
function getUserData(address user) public view returns (
uint256 _balance,
bool _isInitialContributor,
uint256[14] memory _tranchePurchases,
uint256[14] memory _trancheETHPaid,
bool[14] memory _userAvailableTranches
)
- Purpose: View function to retrieve a bundle of data specific to a given user.
- Parameters:
user
: The address of the user to query.
- Returns:
_balance
: User’s current token balance._isInitialContributor
: True if the user participated in Tranche 0._tranchePurchases
: Array of tokens purchased by the user in each tranche._trancheETHPaid
: Array of ETH paid by the user for each tranche._userAvailableTranches
: Boolean array of tranches available for this specific user.
_update
(Override)
function _update(address from, address to, uint256 value) internal virtual override
- Purpose: Overrides the standard OpenZeppelin ERC20
_update
internal function (which is called by_transfer
,_mint
,_burn
). - Logic:
- Sniper Protection: If the token transfer involves the Uniswap pair (i.e.,
from == address(uniswapV2Pair)
ORto == address(uniswapV2Pair)
), it enforces the priority fee check:- If
(tx.gasprice - block.basefee) > maxPriorityFee
, reverts withMaxPriorityFeeExceeded()
.
- If
- Calls
super._update(from, to, value)
to perform the standard ERC20 update logic.
- Sniper Protection: If the token transfer involves the Uniswap pair (i.e.,
- Significance: This is a key part of the anti-MEV mechanism, applying the priority fee cap to all DEX swaps involving this token.
transferFrom
(Override)
function transferFrom(address from, address to, uint256 value) public virtual override returns (bool)
- Purpose: Overrides the standard OpenZeppelin ERC20
transferFrom
function. - Logic:
spender = _msgSender()
._spendAllowance(from, spender, value)
: Checks and reduces the allowancefrom
gave tospender
._transfer(from, to, value)
: Performs the actual transfer (which will call the overridden_update
function, thereby inheriting its priority fee check ifto
orfrom
is the pair).- Returns
true
.
- Note: While it says “No functional change beyond standard OZ implementation”, the fact that it calls
_transfer
which in turn calls the custom_update
means it indirectly incorporates the priority fee check for transfers involving the LP that originate fromtransferFrom
.