Skip to content
Maximize your interest rates
TypeScript JavaScript Other
Branch: master
Clone or download
Latest commit ad7c55c Aug 13, 2019
Type Name Latest commit message Commit time
Failed to load latest commit information.
.circleci Run prettier-check in CI Jul 18, 2019
.github Update Jul 26, 2019
images Add instructions and explanations in readme (#21) Jul 6, 2019
public Updated images to low-res Aug 1, 2019
src Update Menu.tsx Aug 14, 2019
.editorconfig (add) linting files Jun 18, 2019
.env.example Get infura URL from env Jul 18, 2019
.eslintrc.json (add) linting files Jun 18, 2019
.gitignore Show tokens when user is not connected and show tokens prices Jul 16, 2019
.nvmrc (add) .nvmrc Jun 18, 2019
.prettierignore Run prettier-check in CI Jul 18, 2019
.prettierrc (add) linting files Jun 18, 2019
LICENSE (add) some necessary files Jun 18, 2019
MetaMoneyMarket_ A Protocol for Maximizing Yield v0.1.pdf Add files via upload Aug 1, 2019 Update Jul 29, 2019
package.json Add twitter and github links in footer Jul 25, 2019
tsconfig.json (add) react project Jun 18, 2019
tslint.json Manage token amounts with decimals Jul 19, 2019
yarn.lock Add twitter and github links in footer Jul 25, 2019


An open source ethereum protocol that sits on top of multiple money markets, depositing funds into the highest rate, and rebalancing when it makes sense, to help you earn max interest

CircleCI Netlify Status


Clone the repository and install its dependencies:

git clone
cd metamoneymarket

Then create a .env file. You can copy the .env.example file and replace the example values with proper ones. The environment variables are:

  • REACT_APP_NOMICS_API_KEY: An API key for Nomics
  • REACT_APP_RPC_URL: A RPC URL that will be used to show some information until the user connects its wallet.

Test locally

Start a ganache instance with network id 50:

ganache-cli -d -i 50

Then in another terminal deploy the contracts:

yarn deploy:local

and then start the app:

yarn start

Connect MetaMask to localhost:8545 and import the first account from ganache.

Test in Rinkeby/Kovan

Using the private key for an account with Rinkeby ether and a URL for a Rinkeby RPC endpoint, deploy the contracts:

RINKEBY_PRIVATE_KEY=abcdef... RINKEBY_RPC_URL= yarn deploy:rinkeby

Then start the app and connect MetaMask to Rinkeby:

yarn start

To deploy in kovan, follow the same steps but replacing everything for "Kovan" (KOVAN_PRIVATE_KEY, KOVAN_RPC_URL, yarn deploy:kovan, etc.)

Deploy in Mainnet

Using the private key for an account with Mainnet ether and a URL for a Mainnet RPC endpoint, deploy the contracts:

MAINNET_PRIVATE_KEY=abcdef... MAINNET_RPC_URL= yarn deploy:mainnet

Then start the app and connect MetaMask to the Mainnet:

yarn start

Adding new tokens

The blockchain/migrations/2_deploy_meta_money_market.js file has some configuration objects that specify the tokens that will be supported by the deployed MetaMoneyMarket contract. To add new supported tokens at deploy time, modify the tokens property of the corresponding object. For example, for adding support for USDC when deploying in the mainnet, you should modify the mainnetConfig.tokens array, adding this object:

  name: 'usdc',
  tokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
  cTokenAddress: '0x39aa39c021dfbae8fac545936693ac917d5e7563',
  marketId: 2

name is only used for logging. tokenAddress is the address of the token. cTokenAddress is the cUSDC token in the Compound protocol. marketId is the market id for USDC in the dYdX protocol.

The MetaMoneyMarket contract

The code for the MetaMoneyMarket (MMM) contract can be found in blockchain/contracts/MetaMoneyMarket.sol.

Initially, the MMM doesn't support any tokens. Anybody can add support for any ERC20 token by using the addMarket(address) method. This method will enable that token and it will mint a new token that represents shares in the total deposited amount for that token.

Adding a market

When a user deposits tokens, some amount of those token shares will be minted for them. The tokens will then be deposited in the best underlying market.


If later a user burns some of those token shares, it will receive an amount of tokens according to the exchange rate at that moment. These tokens will be taken from the market with the lowest rate. If that market doesn't have enough tokens, the next lowest market will be used, and so on.


You can’t perform that action at this time.