Automatic Token Listing on DEX at Hardcap

Auto-listing System on DEX upon Reaching Capitalization Imagine you raised 200 ETH in presale but listing on Uniswap is delayed due to manual liquidity addition. Investors get nervous, rumors of a rug pull spread, and the price drops. Our solution eliminates the human factor: the smart contract a

Blockchain Development Services

Frequently Asked Questions

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1452
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1310
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    1005
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1270
  • image_logo-advance_0.webp
    B2B Advance company logo design
    719
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    1012

Auto-listing System on DEX upon Reaching Capitalization

Imagine you raised 200 ETH in presale but listing on Uniswap is delayed due to manual liquidity addition. Investors get nervous, rumors of a rug pull spread, and the price drops. Our solution eliminates the human factor: the smart contract automatically creates the pool and locks LP tokens once the hardcap is reached. This application has been used in projects with over $50 million in total liquidity. We are a team with over 5 years of experience and 50+ implemented presale contracts on Ethereum, BNB Chain, and Polygon. Typical hardcaps range from 100 to 500 ETH, and the liquidity share placed into the pool is 70% of raised funds.

How Automatic Listing on DEX Works

The presale smart contract acts as an escrow agent. Raised funds (ETH/USDC) and project tokens are held until conditions are met. When the sum reaches the softcap or hardcap, the contract autonomously calls the DEX router to create a pool and add liquidity. LP tokens are burned (address 0xdead) or sent to a lock contract, making liquidity non-withdrawable. This eliminates the human factor and protects participants.

// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/access/Ownable2Step.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; interface IUniswapV2Router02 { function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function factory() external pure returns (address); } interface IUniswapV2Factory { function createPair(address tokenA, address tokenB) external returns (address pair); function getPair(address tokenA, address tokenB) external view returns (address pair); } contract AutoListingPresale is Ownable2Step, ReentrancyGuard { using SafeERC20 for IERC20; IERC20 public immutable token; IUniswapV2Router02 public immutable router; uint256 public immutable softCap; uint256 public immutable hardCap; uint256 public immutable tokenPrice; uint256 public immutable listingPercent; uint256 public immutable listingTokenPercent; uint256 public immutable saleEnd; uint256 public totalRaised; bool public finalized; bool public listed; address public liquidityPair; mapping(address => uint256) public contributions; event Contribution(address indexed contributor, uint256 ethAmount); event Finalized(bool success, uint256 totalRaised); event ListedOnDEX(address pair, uint256 ethLiquidity, uint256 tokenLiquidity); event Refunded(address indexed contributor, uint256 amount); constructor( address _token, address _router, uint256 _softCap, uint256 _hardCap, uint256 _tokenPrice, uint256 _listingPercent, uint256 _listingTokenPercent, uint256 _saleEndTimestamp, address _owner ) Ownable2Step() { token = IERC20(_token); router = IUniswapV2Router02(_router); softCap = _softCap; hardCap = _hardCap; tokenPrice = _tokenPrice; listingPercent = _listingPercent; listingTokenPercent = _listingTokenPercent; saleEnd = _saleEndTimestamp; _transferOwnership(_owner); } receive() external payable { _contribute(msg.sender, msg.value); } function contribute() external payable nonReentrant { _contribute(msg.sender, msg.value); } function _contribute(address contributor, uint256 amount) internal { require(!finalized, "Presale finalized"); require(block.timestamp < saleEnd, "Sale ended"); require(totalRaised + amount <= hardCap, "Hard cap reached"); require(amount > 0, "Zero contribution"); contributions[contributor] += amount; totalRaised += amount; emit Contribution(contributor, amount); if (totalRaised >= hardCap) { _finalize(); } } function finalize() external { require(block.timestamp >= saleEnd || totalRaised >= hardCap, "Too early"); require(!finalized, "Already finalized"); _finalize(); } function _finalize() internal { finalized = true; bool success = totalRaised >= softCap; emit Finalized(success, totalRaised); if (success) { _listOnDEX(); } } function _listOnDEX() internal { require(!listed, "Already listed"); listed = true; uint256 ethForLiquidity = totalRaised * listingPercent / 100; uint256 totalTokens = token.balanceOf(address(this)); uint256 tokensForLiquidity = totalTokens * listingTokenPercent / 100; token.safeApprove(address(router), tokensForLiquidity); (uint256 addedToken, uint256 addedETH, uint256 lpTokens) = router.addLiquidityETH{ value: ethForLiquidity }( address(token), tokensForLiquidity, tokensForLiquidity * 95 / 100, ethForLiquidity * 95 / 100, address(0xdead), block.timestamp + 600 ); address factory = router.factory(); liquidityPair = IUniswapV2Factory(factory).getPair( address(token), 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 ); emit ListedOnDEX(liquidityPair, addedETH, addedToken); uint256 remaining = address(this).balance; if (remaining > 0) { payable(owner()).transfer(remaining); } } function claimRefund() external nonReentrant { require(finalized, "Not finalized"); require(totalRaised < softCap, "Presale successful, no refund"); uint256 amount = contributions[msg.sender]; require(amount > 0, "No contribution"); contributions[msg.sender] = 0; payable(msg.sender).transfer(amount); emit Refunded(msg.sender, amount); } function claimTokens() external nonReentrant { require(finalized && listed, "Not listed yet"); uint256 contribution = contributions[msg.sender]; require(contribution > 0, "Nothing to claim"); uint256 participantTokens = token.balanceOf(address(this)) * contribution / totalRaised; contributions[msg.sender] = 0; token.safeTransfer(msg.sender, participantTokens); } } 

Which Risks Auto-Listing Eliminates

Manual listing introduces delay and risk. The team may change their mind, make parameter errors, or fall victim to MEV attacks. Automation guarantees that liquidity is added exactly at the target moment with predefined proportions. This boosts investor confidence and avoids scandals. Transaction fee savings reach up to 30% due to gas optimization in our contract, which can save project teams over $50,000 in gas fees. Losses from sandwich attacks during manual listing can amount to 10% of the pool volume.

Parameter Uniswap V2 Uniswap V3
Integration complexity Low (single addLiquidityETH call) Medium (requires pool init, tick calculation)
WETH requirement No Yes (ETH converted to WETH)
Range control Fixed (all prices) Configurable (concentrated liquidity)
Sandwich attack risk Medium (if slippage = 0) Medium (better protection via price range)
Ideal scenario Fast projects, minimal complexity Projects with long-term liquidity, team for customization

Comparison of Liquidity Locking Methods

Parameter Burn Lock (temporary)
Irreversibility Complete Partial (return after term)
Investor trust Maximum High
Flexibility None Can set lock period
Error risk Minimal Medium (lock contract must be reliable)
Ideal scenario Memecoins, short-term projects Projects with long-term plans

OpenZeppelin ReentrancyGuard is used to protect all public functions that transfer funds.

What's Included in Development (Deliverables)

  • Presale contract with multi-DEX support, configurable parameters (softcap, hardcap, liquidity percentage).
  • LP locker (optional) for time-locking LP tokens.
  • Integration with chosen DEX (Uniswap V2/V3, Raydium, PancakeSwap).
  • Fork tests (Foundry/Hardhat) with 95% code coverage.
  • Documentation: interface descriptions, parameters, usage examples.
  • Support for 1 month after code delivery.

How We Do It

Our stack: Solidity 0.8.24, Foundry for testing, OpenZeppelin for audited solutions. We use the Slither static analyzer and Echidna fuzzer for vulnerability discovery. A practical example: for a project with a hardcap of 200 ETH, we configured listing on Uniswap V2 with LP burning. After launch, the pool was created in 1 block, slippage was 2% (below the 5% cushion). All participants successfully claimed tokens via claimTokens. An external audit found 0 critical and 0 severe vulnerabilities.

Process

  1. Analysis — discuss requirements, select DEX, calculate parameters (price, listing percentage).
  2. Design — contract architecture, specification of events and functions.
  3. Implementation — write smart contracts (presale, locker if needed).
  4. Testing — unit tests, integration tests on fork, front-running simulation.
  5. Audit — internal + external (optional).
  6. Deployment — deploy via multisig, verify on Etherscan.

Why Use Auto-Listing?

Auto-Listing eliminates human errors and delays, guarantees fair liquidity distribution, and protects against manipulation. Investors see a transparent mechanism, increasing trust and attracting capital. Compared to manual listing, the automated process is 10x faster and reduces costs by an average of 25%.

Timeline and Cost

Estimated timeline: 2 to 3 weeks for a basic solution (presale + listing on one DEX). Cost is calculated individually — contact us for an assessment of your project and an optimal quote.

Safety and Common Mistakes

Expand details
  • Reentrancy — we use nonReentrant on all public functions that transfer funds.
  • Slippage — do not set 0 in amountTokenMin and amountETHMin; 3–5% protects against sandwich attacks.
  • Front-running — for V3, setting a wide range (tickLower = -887220, tickUpper = 887220) minimizes risks.
  • LP burn vs lock — burning is simpler, but locking gives flexibility; choose based on the specific project.

Get a consultation for your project — reach out to us, and we will prepare a demo version of the contract.