A lightweight voting system for MCDEX


With the development of the MCDEX community, we need a voting system to make governance decisions. MCB holders, as described in the white paper, has the right to vote.

However, we have a big challenge on the voting system:

We will incentivize the MCB holders to add liquidity to the Uniswap MCB/ETH pool. As a result, some MCB will be deposited into the Uniswap pool. To enable the Uniswap LPs to still have voting rights, we have to allow use the Unsiwap share tokens as the voting tokens. If so, there will be two voting tokens: MCB and the Uniswap MCB/ETH pool’s share token. These existing well-audited on-chain voting smart contracts, such as Compound’s voting smart contract, do not support use multi voting tokens. We could just use a simple wrapper ERC20 contract to wrap the two token into another voting token. But, it is hard to determine the voting weight/conversion rate, because the portion of MCB in the Uniswap pool changes always. Besides, it costs a lot of time to develop and audit a complicated new voting contract which will be granted the admin key.

Considering the voting system is used for determining the liquidity mining rules and the team executes those rules off-chain, I propose a light-weight voting system for the early days. And we can upgrade to a fully on-chain governance step by step.

Use Case

  • People give their governance proposals on the forum
  • The team review the proposal and add it to the voting smart contracts
  • Anyone could vote for/against a proposal during the active time
  • The backend watcher calculates the voting result on the end block.
  • The team executes the proposal 3 days after the voting

System Design

This light-weight voting system consists of the following components:

  • A simple smart contract which only records everyone’s voting on each proposal
  • An off-chain watcher system calculating the voting result
  • A frontend system to show the voting process/result and for users to write the voting contract

Smart Contract

This voting smart contract has no admin privilege. It is only used to record the vote(for/against) of the community members on the blockchain. Because the voting smart contract is simple enough and can not change anything of MCDEX directly, we could audit it by the community only.

A proposal has the following on-chain metadata:

  • id: auto-increment unique id
  • proposal link: the forum link of the proposal
  • active time: [begin block, end block] for voting

The smart contract has the following public functions:

  • propose(link, begin, end): create a new proposal, need a proposal privilege
  • vote(id, for/against): vote for/against the proposal with id

The smart contract has the following events:

  • proposal(id, link, begin, end): the new proposal is created.
  • vote(address, id, for): someone changes his vote on the proposal.

The backend system can use the events to trace the voting.

However, anyone can verify the voting result by reading this contract’s data from block-chain. Nobody can cheat on voting.


The backend runs a watcher to trace and record the voting data from the block-chain.

This module calculates the final voting result based on the block state of the proposal’s end block.

\Omega: the set of addresses who vote for the proposal
\Theta: the set of addresses who vote against the proposal
\Phi: the set of the voting tokens
W_j: the voting weight of the voting token j
B_{ij}: the address i's balance of token $j
Q: the quorum of the voting

Then, the effective for votes F is:

F=\sum_{i\subset \Omega }\sum_{j\subset \Phi } W_j \cdot B_{ij}

Then, the effective against votes A is:

A=\sum_{i\subset \Theta }\sum_{j\subset \Phi } W_j \cdot B_{ij}

If F > A and F > Q, the proposal is adopted, otherwise the proposal is denied.

In the next mining round, there will be two ERC20 tokens that can be used for voting: MCB and the Uniswap MCB/ETH pool share token.

Vote Token Voting Weight
Uniswap MCB/ETH Share W_u=\frac{M}{T} M: number of MCB deposited in the MCB/ETH liquidity pool; T: The total supply of MCB/ETH pool share token

We MUST use the balances of tokens in the end block of the proposal rather than the latest values. We need the same tech to trace the ERC20 balance in every block in liquidity mining system.

The backend should also provide the API for query the real-time voting results of each proposal.


The frontend has the following features:

  • Show the metadata and voting status of each proposal
  • UI for the user to vote on the proposal during the active time by calling the smart contract

In short, this version of the vote system uses an on-chain recording of user votes, and an off-chain counting of user votes.This solution is lighter and reflects the user’s will. :love_you_gesture: