MERC20 -- Port of Ethereum ERC20 to Midnight
Features a port of the ERC-20 standard written in Compact (Midnight's smart contract language) and a frontend to utilize MERC20 to create memecoins.
Created on 1st March 2025
•
MERC20 -- Port of Ethereum ERC20 to Midnight
Features a port of the ERC-20 standard written in Compact (Midnight's smart contract language) and a frontend to utilize MERC20 to create memecoins.
The problem MERC20 -- Port of Ethereum ERC20 to Midnight solves
Midnight enables data protection for dApps through zero knowledge. With Midnight, it's possible to write contracts / create proofs that attest to something being true, without revealing the specific information. By porting the ERC-20 standard to Midnight (calling it MERC-20), this project showcases how we can have private balances that are de-coupled from a regular wallet, while still remaining compatible with industry standards.
Furthermore, this project shows how unit tests, a CLI application and an UI application can be written to work with Compact, a specialized language based off Typescript made for Midnight.
To demonstrate the functionality, the UI and CLI allow anyone to launch memecoins or tokens using the MERC-20 contract written in this project. This project is also built off of the examples package by the Midnight team.
Feedback: One of the most important things for this project is to provide feedback to the Midnight team on how they can improve testnet / developer experience. Here are my observations:
- This page says Compact version 0.14 and compiler 0.21 at the top, but still discusses the
Cell<value_type>type, which was removed. I struggled with this for a while before finding an announcement in the Discord thatCellwas removed. - If a function calls a witness, subtractions and comparisons of Uints become problematic. Specifically, the compiler has a Rust panic, and says "Cannot bound an element with a bound 256 > 222 = MAX_BOUND". The backtrace shows that it arises from an internal equality checking thing. A minimum reproduceable example has been sent to the team over Telegram.
- When I wanted to make the CLI and UI for my contract, I had to copy the bulletin board example and change all the references by hand. I wish there was something like
create-next-appthat would automatically setup a skeleton project based off a template that has the minimum code to start.
User Interaction and Data Flow
A user can use the included CLI program or the included UI to interact with MERC-20 contracts. The frontend is also deployed here: https://midnight-ui-2.vercel.app/
The project architecture and development process
The project is split into 4 components:
- Core contract and tests: The MERC-20 contract is written in Compact, and unit tests are written in Typescript using Jest, and check for deterministic initialization, transfer, and approval correctness.
- API: This API provides a Typescript wrapper around the MERC-20 contract and enables deploying, calling specific circuits, and otherwise interacting with the MERC-20 contract in Typescript.
- Command line interface: This CLI tool uses the Typescript API to actually take in a user's wallet, deploy a MERC-20 contract using their tDUST, send tokens, check balances, and more.
- Online UI: This UI is aimed at showcasing how MERC-20 can be used for memecoins and other ERC-20-like applications. The UI can do the same things as the CLI but requires users to connect their wallet via the Midnight Lace chrome extension.
Product Integrations
Built on Midnight Testnet, and frontend is deployed on Vercel, and source code is hosted on Github.
Key differentiators and uniqueness of the project
This project especially showcases how Midnight's features enable privacy for DeFi-like transactions. With MERC-20, a token holding cannot be traced back to the actual wallet, or other token holdings (if they are deployed with a different merc-20 salt). Furthermore, this project includes a CLI and UI and serves as a good example for the ecosystem of how to integrate.
Trade-offs and shortcuts while building
- I ran into a compiler bug (I think) where if a witness is used in a circuit, subtraction between two Uint<256>s throws a compile-time error. This took several hours to find, and was validated with a minimal reproduceable example. To get around this, the compiler message indicates the max width it could handle was 222 bits, so I used Uint<222> everywhere instead. After this bug is fixed, Uint<256> should be possible to use.
- The UI code is forked off of the UI code for the bulletin board example. If I had more time, I would rewrite it from scratch because there are still a lot of references to the bulletin board. Plus, it would be helpful to have a Nextjs app to serve as a demonstration of another framework in addition to Vite.
Additional Features
Not started before the buidlathon.
Tracks Applied (2)
Create the first meme token on Midnight
Midnight Network
Port an existing token standard from Ethereum to Midnight
Midnight Network
Technologies used
Cheer Project
Cheering for a project means supporting a project you like with as little as 0.0025 ETH. Right now, you can Cheer using ETH on Arbitrum, Optimism and Base.