Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
LABS
Guides

Setting Up a Token Sale with Dynamic Pricing Mechanisms

A developer guide for implementing advanced sale models like Dutch auctions and bonding curves. Covers smart contract logic, sale state management, and frontend integration for a DEX launchpad.
Chainscore © 2026
introduction
TUTORIAL

Introduction to Dynamic Pricing for Token Sales

This guide explains how to implement dynamic pricing mechanisms for token sales, moving beyond fixed-price models to optimize capital efficiency and market alignment.

Dynamic pricing for token sales refers to mechanisms where the price of a token changes based on predefined rules, typically in response to demand, time, or the amount of capital raised. Unlike a simple fixed-price Initial DEX Offering (IDO), dynamic models like bonding curves and Dutch auctions allow the market to discover a fair price. This approach can help projects avoid significant post-listing price volatility and more accurately match token supply with investor demand. Key protocols that have popularized these models include Balancer Liquidity Bootstrapping Pools (LBPs) and Gnosis Auction.

The most common implementation is a liquidity bootstrapping pool (LBP). In an LBP, a project deposits its sale tokens and a base currency (like ETH or USDC) into a Balancer pool with heavily skewed weights (e.g., 98% token / 2% USDC). As buyers purchase tokens, the pool's weights automatically rebalance, causing the token price to gradually decrease if demand is low. This creates a descending price curve that incentivizes early participation while protecting against front-running and whale dominance. The sale concludes when the weights reach 50/50 or after a set duration.

To set up a basic LBP, you'll interact with Balancer's LiquidityBootstrappingPool factory. The core parameters you must define are the initial weights, swap fees, and sale duration. Here's a simplified example of the initialization data structure:

code
struct LBPParams {
    string name;
    string symbol;
    IERC20[] tokens; // [saleToken, baseToken]
    uint256[] initialWeights; // e.g., [980000, 20000] for 98%/2%
    uint256 swapFeePercentage;
    address owner;
    bool swapEnabledOnStart;
}

The pool is created via BALANCER_VAULT.createPool(poolId) using this configuration.

An alternative model is the Dutch auction, where the token price starts high and decreases over time until buyers step in. Platforms like Gnosis Auction facilitate this. A smart contract holds the sale tokens, and a clearing price is determined where total bids meet the total token supply. This ensures all successful bidders pay the same final price. This method is highly effective for price discovery in environments with uncertain demand, as it rewards participants for their price sensitivity rather than their transaction speed.

When designing your sale, critical security considerations include: using a timelock or multisig for admin functions, setting a reasonable maximum purchase cap per wallet to prevent sybil attacks, and ensuring adequate liquidity for the token post-sale to support trading. Always audit your sale contract or use thoroughly battle-tested platforms. Dynamic pricing is a powerful tool for fair launches, but its parameters must be carefully calibrated to your project's tokenomics and goals.

prerequisites
TOKEN SALE IMPLEMENTATION

Prerequisites and Setup

This guide covers the technical prerequisites for building a token sale with dynamic pricing, focusing on smart contract development and environment setup.

Before writing any code, you need a foundational development environment. This includes Node.js (v18+ recommended) and a package manager like npm or yarn. You will also need a code editor such as VS Code. The core tool for smart contract development is the Hardhat framework, which provides a local Ethereum network, testing suite, and deployment scripts. Install it globally via npm install --global hardhat. For an alternative, Foundry is a popular choice for its speed and direct Solidity testing.

A dynamic pricing mechanism requires on-chain price feeds and mathematical logic. You will need to understand and import key libraries. The OpenZeppelin Contracts library provides secure, audited base contracts for ERC-20 tokens and ownership models like Ownable. Install it with npm install @openzeppelin/contracts. For complex calculations, consider using PRBMath for fixed-point arithmetic or ABDK Libraries for precise decimal math, which are crucial for avoiding rounding errors in price curves.

You must configure your hardhat.config.js file to connect to networks and set up environment variables. Use the dotenv package to manage sensitive data like private keys and RPC URLs. A typical configuration includes networks for Hardhat Network (local), Sepolia (testnet), and Ethereum Mainnet. You will also need test ETH on a testnet; use a faucet like Alchemy's Sepolia Faucet to fund your deployment account. Set up ETHERSCAN_API_KEY for contract verification.

Dynamic pricing logic is often implemented via bonding curves or Dutch auctions. A bonding curve contract, such as a linear y = mx + b formula, mints tokens based on the total supply. A Dutch auction starts at a high price that decreases over time until a buyer accepts it. Your setup should include mock or real price oracles if your mechanism depends on external data, like using a Chainlink Data Feed for a USD-denominated floor price.

Finally, establish a testing strategy. Write comprehensive tests in Hardhat using Chai for assertions or in Foundry using Solidity. Test critical scenarios: the price calculation accuracy at different supply levels, purchase and refund functionality, contract pausing (using OpenZeppelin's Pausable), and access control. Use console.log in Solidity (via Hardhat) or Foundry's vm.recordLogs() for debugging. A proper setup ensures your pricing mechanism is secure and functions as intended before mainnet deployment.

key-concepts-text
CORE CONCEPTS

Dutch Auctions vs. Bonding Curves for Token Sales

A technical comparison of two dynamic pricing mechanisms for launching tokens, covering their mechanics, use cases, and implementation considerations.

Dutch auctions and bonding curves are two primary mechanisms for conducting token sales with dynamic pricing. A Dutch auction, or descending price auction, starts with a high initial price that decreases over time until a buyer accepts it. This model, popularized by projects like Gnosis (GNO) on the Ethereum mainnet, is designed to discover a market-clearing price efficiently. In contrast, a bonding curve is a smart contract that mints and burns tokens based on a predefined mathematical price function, typically increasing as the total token supply grows. This creates a continuous, automated market maker for the token from inception.

The core difference lies in price discovery versus price automation. A Dutch auction is an event-based price discovery tool. It answers the question: "What will the market pay for this fixed supply of tokens right now?" The entire sale concludes at a single price point for all participants. Bonding curves automate liquidity provision. The price is a function of the circulating supply, often following a formula like price = k * (supply)^n. Early buyers get a lower price but provide the liquidity for later buyers, creating a built-in, if simplistic, automated market.

From an implementation perspective, a basic Dutch auction contract needs a starting price, a price decay function (e.g., linear decrease per block), and a mechanism to finalize the sale. Bonding curve contracts are more complex, as they must handle continuous minting/burning and manage a reserve of the base currency (like ETH or a stablecoin). Key security considerations for bonding curves include ensuring the reserve math is non-exploitable and implementing circuit breakers for extreme volatility. The Bancor Protocol pioneered early bonding curve implementations.

Choosing between them depends on the project's goals. Use a Dutch auction for a one-time, fair launch of a fixed token supply where community price discovery is the priority. It mitigates gas wars common in fixed-price sales. Opt for a bonding curve if you need continuous, algorithmic liquidity and a token model where price is intrinsically linked to adoption (e.g., a community token or a collateral type). However, bonding curves can be capital inefficient and vulnerable to front-running or manipulation in their pure form.

For developers, several audit battle-tested templates exist. The OpenZeppelin Crowdsale library formerly offered a DutchAuction contract. For bonding curves, the Bancor Formula smart contracts provide a foundational library for curve math. When implementing, always use a pull-over-push pattern for withdrawals to prevent reentrancy attacks, and consider integrating with a DEX like Uniswap V3 post-launch for more sophisticated liquidity management beyond a simple curve.

AUCTION DESIGN

Dynamic Pricing Mechanism Comparison

A comparison of common mechanisms for structuring token sales with variable pricing based on demand.

MechanismDutch AuctionBatch AuctionBonding Curve

Primary Use Case

Fair price discovery for large allocations

Single clearing price for a fixed supply

Continuous liquidity for project treasuries

Price Direction

Descends from high to low

Set by market-clearing bid

Increases with buy pressure, decreases with sells

Complexity for Users

Medium (timing strategy)

Low (simple bid)

Low (instant swap)

Gas Efficiency

Low (multiple transactions common)

Medium (one bid, one claim)

High (single swap transaction)

Capital Lockup

High (funds locked until sale ends)

Medium (funds locked until clearing)

None (instant settlement)

Price Volatility During Sale

High (price changes per block)

None (single price at end)

Continuous (changes with each trade)

Common Implementation

Gnosis Auction, Mirror's mGNO

CoinList, Balancer LBPs

Uniswap v3, Curve, Bancor

Typical Fee Range

0.5-2% platform fee

1-3% platform fee

0.01-0.3% swap fee + protocol fee

dutch-auction-implementation
TUTORIAL

Implementing a Dutch Auction Smart Contract

A step-by-step guide to building a descending-price auction for token sales using Solidity, covering core logic, security considerations, and integration patterns.

A Dutch auction, or descending-price auction, is a mechanism where an asset's price starts high and decreases over time until a buyer accepts it. In token sales, this model helps discover a fair market price by allowing demand to set the clearing price, rather than a fixed valuation. This contrasts with traditional fixed-price sales or bonding curves. The key variables are the starting price, reserve price, auction duration, and price decay function. Implementing this on-chain requires precise time-based calculations to ensure the price updates predictably with each new block.

The core smart contract logic revolves around calculating the current price. A common approach uses a linear decay formula: currentPrice = startPrice - ((startPrice - reservePrice) * elapsedTime / totalDuration). This must be computed in a view function, like getCurrentPrice(), to allow participants to check the price without executing a transaction. The contract must track the auction's start time and enforce that bids can only be placed while the auction is active and the sent msg.value is at least the current price. Upon a successful bid, the auction concludes, the bidder receives the tokens, and any excess ether is refunded.

Critical security considerations include protecting against front-running and ensuring fairness. Using a commit-reveal scheme can mitigate sniping bots, but adds complexity. For simplicity, our example uses a transparent, first-come-first-served model. The contract must also guard against reentrancy when refunding excess ether and use the Checks-Effects-Interactions pattern. Here's a basic skeleton in Solidity 0.8.x:

solidity
function bid() external payable auctionActive nonReentrant {
    uint256 currentPrice = getCurrentPrice();
    require(msg.value >= currentPrice, "Bid below current price");
    
    uint256 excess = msg.value - currentPrice;
    winningBidder = msg.sender;
    auctionEndTime = block.timestamp; // End auction
    
    _safeTransferTokens(winningBidder, tokensForSale);
    if (excess > 0) {
        (bool sent, ) = payable(msg.sender).call{value: excess}("");
        require(sent, "Refund failed");
    }
}

Integrating the auction contract with an ERC-20 token is essential. The contract must be approved to spend the sale tokens from the deployer's address or hold them in its treasury. After the auction, unsold tokens should be reclaimable by the owner. For a production system, consider adding an optional minimum price threshold (reserve price) that, if not met, allows the auction to conclude with no sale. Events like AuctionStarted, PriceUpdated, and AuctionWon should be emitted for off-chain monitoring and front-end integration. Testing with tools like Foundry or Hardhat is crucial to simulate time passage and verify price decay across blocks.

Beyond the basic implementation, several enhancements can optimize gas efficiency and user experience. Using a fixed-point math library (like PRBMath) prevents precision loss in price calculations. For longer auctions, a non-linear decay curve (exponential or logarithmic) can be implemented for different economic effects. To support multiple winners or batch sales, the contract can be modified to become a batch Dutch auction, selling tokens in lots. Always conduct a thorough audit, as the interaction of time, price, and user funds creates a complex attack surface. Reference implementations can be found in projects like Uniswap's Governance NFT auction for real-world patterns.

bonding-curve-implementation
TUTORIAL

Implementing a Bonding Curve Smart Contract

This guide walks through building a smart contract for a token sale powered by a bonding curve, enabling dynamic pricing based on token supply.

A bonding curve is a mathematical function that defines a direct relationship between a token's price and its circulating supply. Unlike fixed-price ICOs, the price adjusts automatically: it increases as tokens are purchased (minted) and decreases when they are sold back (burned). This creates a continuous, automated market maker within the contract itself. Common curve types include linear (price = slope * supply) and exponential (price = basePrice ^ supply), each offering different liquidity and price volatility characteristics.

To implement this, you'll need a smart contract with key state variables: tokenSupply, reserveBalance (the pool of reserve currency like ETH), and a curveFactor that determines the slope of the price function. The core logic resides in two functions: buyTokens and sellTokens. When a user sends ETH to buyTokens, the contract calculates the mint price based on the current supply, mints new tokens to the buyer, and adds the ETH to the reserveBalance. The price for the next buyer will be slightly higher.

Here's a simplified snippet for a linear bonding curve's purchase function in Solidity:

solidity
function buyTokens() public payable {
    uint256 tokensToMint = getTokensForEth(msg.value);
    totalSupply += tokensToMint;
    reserveBalance += msg.value;
    _mint(msg.sender, tokensToMint);
}

function getTokensForEth(uint256 ethAmount) public view returns (uint256) {
    // Integrate the price function: tokens = sqrt(2*eth/slope) for linear
    return sqrt((2 * ethAmount) / curveSlope);
}

The sellTokens function performs the inverse operation, burning tokens and releasing a corresponding amount of ETH from the reserve.

Critical considerations include security and economic design. You must guard against rounding errors in price calculations, which can be exploited. Use a library like OpenZeppelin's SafeMath or Solidity 0.8+'s built-in checks. The choice of curveFactor dramatically impacts the project's economics: a steeper curve raises funds faster but may discourage later buyers, while a flatter curve encourages broader distribution but raises capital more slowly. Always simulate the curve's behavior extensively before deployment.

Bonding curves are used for continuous token models (like Curve Finance's CRV) and community-owned liquidity pools. They automate market making but introduce unique risks: the contract must hold the entire reserve, creating a high-value target, and the "buy" side is inherently infinite, requiring careful supply caps or curve halts. Testing with tools like Foundry or Hardhat, and conducting audits, is non-negotiable for any production deployment.

To extend this basic implementation, consider adding features like a fee mechanism (e.g., taking a 1% fee on buys/sells for a treasury), allowlist functionality for initial phases, or a circuit breaker to pause buys if the price climbs too rapidly. The bonding curve contract can then be integrated with a frontend DApp using ethers.js or web3.js, allowing users to visualize the price curve in real-time as the supply changes.

sale-state-management
IMPLEMENTATION GUIDE

Managing Sale State and Timeline

A token sale's lifecycle is governed by its state machine and timeline parameters. This guide explains how to configure and manage these critical components for a sale with dynamic pricing.

The core of any token sale contract is its state machine. A typical flow progresses through sequential phases: Setup, Active, Finalized, and Cancelled. The Active state is often the only period where users can commit funds. Transitions between states are triggered by specific conditions, such as the block timestamp reaching a startTime, the hardCap being met, or an admin calling a function to manually advance or cancel the sale. Enforcing these state checks with require() statements is essential for security and predictable behavior.

For a dynamic pricing mechanism, the timeline directly influences the price calculation. You must define key parameters as immutable or configurable variables: startTime (sale opens), endTime (sale closes), and potentially a vestingStartTime for token distribution. During the Active phase, the current price can be determined by a function that reads block.timestamp. Common models include a linear price decrease (Dutch auction) or increase (bonding curve) over time. The formula currentPrice = startPrice - ((block.timestamp - startTime) * priceDecreasePerSecond) is a simple example of a linear Dutch auction.

Managing state transitions requires careful smart contract design. The startSale() function should move the state from Setup to Active, often restricted to an admin role. The primary purchase function, e.g., buyTokens(), must include require(state == State.Active, "Sale not active") and require(block.timestamp >= startTime && block.timestamp <= endTime, "Outside sale period"). An internal _finalize() function can be called automatically when block.timestamp > endTime or the hardCap is reached, moving the state to Finalized and locking further purchases.

Beyond basic timing, consider edge cases and user experience. Implement a withdraw() function allowing users to reclaim funds if the sale is Cancelled or if they participate in a refundable model. For sales with a minimum raise (softCap), the _finalize() logic should check if it was met; if not, the sale may allow refunds. Always emit clear events (SaleStarted, SaleFinalized, TokensPurchased) for off-chain monitoring. Testing with tools like Foundry or Hardhat across different timestamp scenarios is non-negotiable for ensuring robustness.

In practice, you can integrate with oracles or keepers for automated state management. For instance, a Chainlink Keepers-compatible checkUpkeep() function could monitor if block.timestamp > endTime and return true to trigger an automated performUpkeep() that calls finalize(). This removes admin dependency for time-based conclusions. Remember that all time values should use a consistent unit (e.g., Unix timestamp) and be set carefully, considering block time variability across different networks like Ethereum, Arbitrum, or Polygon.

frontend-integration
TECHNICAL TUTORIAL

Integrating Pricing Data with the Launchpad UI

A guide to implementing dynamic pricing mechanisms for token sales, connecting smart contract data to a responsive frontend.

Dynamic pricing mechanisms, such as bonding curves or Dutch auctions, are essential for managing token distribution efficiently. Unlike fixed-price sales, these models adjust the token price in real-time based on predefined rules, such as the amount of capital raised or elapsed time. To integrate this into a launchpad, you must establish a reliable data pipeline between your smart contract's on-chain pricing logic and the user interface. This requires listening for contract events, polling for state changes, and updating the UI components accordingly to reflect the current price and available supply.

The core integration involves your frontend querying the pricing contract. For a bonding curve sale, you would call a view function like getCurrentPrice() or tokensReceivedForPayment(amount). Use a library like ethers.js or viem to interact with the contract. Implement a polling interval or, preferably, subscribe to contract events such as TokensPurchased to trigger UI updates without constant polling. This ensures users see the most accurate price, which is critical as it may change with every transaction. Caching strategies can help manage rate limits from RPC providers.

Here is a basic React hook example using ethers to fetch a dynamic price:

javascript
import { ethers } from 'ethers';
import { useEffect, useState } from 'react';

const useTokenPrice = (contractAddress, abi, providerUrl) => {
  const [currentPrice, setCurrentPrice] = useState('0');

  useEffect(() => {
    const provider = new ethers.providers.JsonRpcProvider(providerUrl);
    const contract = new ethers.Contract(contractAddress, abi, provider);

    const fetchPrice = async () => {
      try {
        // Assuming the contract has a getCurrentPrice function
        const price = await contract.getCurrentPrice();
        setCurrentPrice(ethers.utils.formatEther(price));
      } catch (error) {
        console.error('Error fetching price:', error);
      }
    };

    fetchPrice();
    const interval = setInterval(fetchPrice, 15000); // Poll every 15 seconds
    return () => clearInterval(interval);
  }, [contractAddress, abi, providerUrl]);

  return currentPrice;
};

This hook periodically fetches the price, but for production, consider using an event listener for greater efficiency.

For a superior user experience, the UI must communicate pricing dynamics clearly. Visualize the bonding curve or auction timeline with a chart library like D3.js or Recharts. Display key metrics: - Current price per token - Total funds raised - Remaining token supply - Time until next price tier or auction end. Input fields for purchase amount should calculate the cost in real-time using the fetched price, and vice-versa. Always show the user's expected token allocation before they confirm the transaction, and provide clear warnings if the price is likely to change before their transaction is mined.

Security and validation are paramount. Always perform price calculations on the client-side for UX, but the final, authoritative check must happen in the smart contract's buy function to prevent front-running or stale data exploits. Use the Chainlink Oracle or a similar decentralized solution if your pricing depends on external data like ETH/USD. Thoroughly test the integration on a testnet (e.g., Sepolia) using different wallet states and network conditions. Monitor gas fees, as dynamic pricing contracts can have variable complexity, and inform users accordingly.

DYNAMIC PRICING MECHANICS

Frequently Asked Questions

Common technical questions and solutions for developers implementing token sales with dynamic pricing, such as bonding curves and Dutch auctions.

A bonding curve is a smart contract that algorithmically sets a token's price based on its current supply. The most common implementation is a continuous token model where price increases as more tokens are minted (bought) and decreases as tokens are burned (sold).

Key Mechanics:

  • Price Function: Typically uses a formula like price = reserve ratio ^ (1 / slope). A linear curve might use price = k * supply.
  • Reserve Pool: Buyer's ETH/USDC is deposited into a reserve, backing the token's value.
  • Continuous Liquidity: The contract itself acts as an automated market maker, providing instant liquidity.

For example, a linear bonding curve on Ethereum might implement a buy() function where the cost to mint the next token is currentPrice = basePrice + (tokensMinted * increment). This creates predictable, transparent price discovery without an order book.

security-considerations
DYNAMIC PRICING IMPLEMENTATION

Security and Audit Considerations

Implementing a dynamic pricing mechanism for a token sale introduces unique security vectors that require rigorous testing and auditing to protect user funds and ensure contract integrity.

Dynamic pricing mechanisms, such as bonding curves or Dutch auctions, are inherently complex state machines. The primary security risk is mathematical precision. Operations involving division, exponentiation, and progressive state updates must be implemented with fixed-point math libraries like ABDKMath or PRBMath to prevent rounding errors that can be exploited for free tokens or locked funds. For example, a miscalculation in a bonding curve's buyPrice function could allow an attacker to drain the reserve pool by purchasing tokens for less than their true value.

A critical consideration is front-running protection. In a live, on-chain sale, transaction ordering is public. Without safeguards, bots can monitor the mempool and place transactions that benefit from price changes caused by pending user purchases. Mitigations include using commit-reveal schemes, implementing minimum time delays between price updates, or utilizing a Vickrey auction model where the final clearing price is determined after the bidding period ends, as seen in protocols like Uniswap's initial v3 NFT auction.

Smart contract pausability and emergency stops are non-negotiable. A dynamic sale contract must include a secure, multi-signature or time-locked admin function to halt sales if a critical bug is discovered. However, this function must be carefully designed to prevent malicious admin takeover. Best practice is to use a timelock controller, like OpenZeppelin's, which delays execution of privileged functions, giving the community time to react. The contract should also include a secure withdrawal mechanism for the project treasury that cannot be triggered before the sale concludes.

Comprehensive auditing is essential. Beyond standard smart contract checks, auditors must specifically review the price function logic, reserve accounting, and edge cases at sale start and end. Use property-based testing frameworks like Foundry's fuzzing to simulate thousands of random purchase sequences and validate invariants, such as "the sum of all user balances plus the reserve equals the total deposited ETH." Engage specialized auditors with experience in DeFi math, such as Trail of Bits or Spearbit, for a final review before mainnet deployment.

Finally, implement transparent and verifiable post-sale logic. The contract should clearly define how unsold tokens are handled (e.g., burned, returned to treasury) and how the final price is calculated and logged. All critical parameters—like the pricing curve formula, duration, and reserve ratios—should be immutable after initialization to prevent rug-pulls. Providing a verified, public script to recalculate the final price from on-chain events builds trust and allows for independent verification by participants.

conclusion
IMPLEMENTATION SUMMARY

Conclusion and Next Steps

You have successfully configured a smart contract for a token sale with dynamic pricing. This guide covered the core mechanisms, from bonding curves to Dutch auctions.

Your implementation now includes a dynamic pricing engine that adjusts the token cost based on real-time supply and demand. For a bonding curve, this means the price increases predictably as the total supply sold grows, often using a formula like price = basePrice * (totalSupply^curveFactor). For a Dutch auction, the price starts high and decreases over time or until a purchase is made. The key takeaway is that these mechanisms automate price discovery, removing the need for a centralized market maker and creating a transparent, on-chain launchpad.

The next critical step is security and testing. Before deploying to a mainnet like Ethereum or Arbitrum, you must rigorously audit your contract. Use a development framework like Foundry or Hardhat to write comprehensive tests that simulate various scenarios: a user buying tokens at different price points, the sale reaching its cap, and edge cases like front-running. Consider engaging a professional auditing firm or using automated tools like Slither or MythX. Remember, a single vulnerability in your pricing math or access control can lead to significant financial loss.

Finally, plan your go-live strategy and monitoring. Decide on your launch parameters: the initial price, curve slope, auction duration, and total sale cap. Use a service like Tenderly or OpenZeppelin Defender to monitor the contract post-deployment for unusual activity. You should also prepare front-end interfaces for users, potentially integrating wallet connection via libraries like Wagmi or Web3Modal. For further learning, explore related mechanisms like batch auctions (used by Gnosis Auction) or hybrid models, and review successful sale contracts on platforms like Mirror Protocol or Juicebox.

How to Set Up a Token Sale with Dynamic Pricing | ChainScore Guides