In this tutorial, you'll learn how to create a permissionless ERC20 memecoin using Solidity and deploy it with a Uniswap v3 liquidity pool, enabling users to trade it on decentralized exchanges.
Disclaimer: This guide is for educational purposes only. Avoid speculative investments in memecoins.
Solidity Memecoin Code Overview
Prerequisites
To follow along, ensure you have:
- Git
- Node.js
- Basic understanding of Ethereum smart contracts
Setup Instructions
Clone the repository and install dependencies:
git clone https://github.com/jamesbachini/Memecoin.git
npm install hardhat
npm install --save-dev "hardhat@^2.12.2" "@nomicfoundation/hardhat-toolbox@^2.0.0"
npm install --save-dev dotenv
npm install --save-dev @openzeppelin/contracts
npx hardhat test Code Breakdown
The Meme contract combines ERC20 token functionality with Uniswap v3 liquidity pool deployment:
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.18;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
interface INonfungiblePositionManager {
struct MintParams {
address token0;
address token1;
uint24 fee;
int24 tickLower;
int24 tickUpper;
uint256 amount0Desired;
uint256 amount1Desired;
uint256 amount0Min;
uint256 amount1Min;
address recipient;
uint256 deadline;
}
function mint(MintParams calldata params) external payable returns (
uint256 tokenId,
uint128 liquidity,
uint256 amount0,
uint256 amount1
);
function createAndInitializePoolIfNecessary(
address token0,
address token1,
uint24 fee,
uint160 sqrtPriceX96
) external payable returns (address pool);
}
contract Meme is ERC20 {
INonfungiblePositionManager posMan = INonfungiblePositionManager(0xC36442b4a4522E871399CD717aBDD847Ab11FE88);
address constant weth = 0x9c3C9283D3e44854697Cd22D3Faa240Cfb032889; // Polygon Mumbai testnet
uint supply = 1_000_000 * 10 ** decimals();
uint24 constant fee = 500;
uint160 constant sqrtPriceX96 = 79228162514264337593543950336; // ~1:1 price ratio
int24 minTick;
int24 maxTick;
address public pool;
address token0;
address token1;
uint amount0Desired;
uint amount1Desired;
constructor() ERC20("Meme Token", "MEME") {
_mint(address(this), supply);
fixOrdering();
pool = posMan.createAndInitializePoolIfNecessary(token0, token1, fee, sqrtPriceX96);
}
function addLiquidity() public {
IERC20(address(this)).approve(address(posMan), supply);
posMan.mint(INonfungiblePositionManager.MintParams({
token0: token0,
token1: token1,
fee: fee,
tickLower: minTick,
tickUpper: maxTick,
amount0Desired: amount0Desired,
amount1Desired: amount1Desired,
amount0Min: 0,
amount1Min: 0,
recipient: address(this),
deadline: block.timestamp + 1200
}));
}
function fixOrdering() private {
if (address(this) < weth) {
token0 = address(this);
token1 = weth;
amount0Desired = supply;
amount1Desired = 0;
minTick = 0;
maxTick = 887270;
} else {
token0 = weth;
token1 = address(this);
amount0Desired = 0;
amount1Desired = supply;
minTick = -887270;
maxTick = 0;
}
}
} Key Features
- Token Creation: Mints 1 million
MEMEtokens. - Liquidity Pool: Initializes a Uniswap v3 pool with a 1:1 price ratio.
- Fair Launch: Tokens are locked in the contract, ensuring no pre-sale advantages.
Deployment Steps
Configure Environment
- Update
.env-samplewith your Alchemy API key and wallet details. - Verify
wethaddress for your target network (e.g., Uniswap’s deployment docs).
- Update
Deploy the Contract
Run the following command (replacemumbaiwith your network):npx hardhat run ./scripts/deploy.js --network mumbai- Add Liquidity
CalladdLiquidity()after deployment to finalize the pool. - Trade on Uniswap
Users can swap tokens by entering the contract address in Uniswap’s interface.
👉 Explore Uniswap v3 liquidity strategies
FAQ
Q1: Can I deploy this on mainnet?
Yes, but use testnets like Mumbai or Goerli for practice first.
Q2: Why is addLiquidity() separate from the constructor?
Pool initialization and liquidity addition require sequential transactions due to contract interdependencies.
Q3: How do I update token metadata?
Modify the ERC20("Meme Token", "MEME") constructor arguments before deploying.
Q4: What’s the role of sqrtPriceX96?
It sets the initial token price (1:1 with ETH/MATIC in this case).
Q5: Is the liquidity pool permanent?
Yes—the LP NFT is held by the contract, preventing liquidity removal.
Final Notes
Creating a memecoin is technically simple, but success hinges on community engagement and meme culture. Always prioritize security and transparency.
👉 Learn advanced DeFi tokenomics
For further reading, refer to Uniswap’s official documentation.