Contracts for Erasure, a decentralized marketplace for data feeds and predictions
Last updated a year ago by mertcelebi .
Repository · Bugs · Original npm · Tarball · package.json
$ cnpm install erasure-contracts 
SYNC missed versions from official npm registry.

Erasure Smart Contracts

A decentralized marketplace for data feeds and predictions


This repo assumes you have truffle installed globally. If you don't have it make sure you have the most recent version installed.

yarn global add truffle
truffle version
Truffle v4.1.7 (core: 4.1.7)
Solidity v0.4.23 (solc-js)

Install packages using yarn


Start a local blockchain like Ganache. You can use Ganache CLI or the desktop client.

yarn run ganache

Compile and migrate your local smart contracts.

truffle migrate --reset


yarn run ganache
yarn run test

Rough Spec


There are 3 main contracts:

  1. Erasure - a simple contract that handles time-locked (or lagged) messages
  2. Marketplace - the contract that handles the creation and the purchase of the data prediction feeds. Under the hood, the marketplace contract uses the Erasure contract to create the prediction.
  3. ERASE - the token that powers the staking in the marketplace contract

ERASE Token Spec

The exact details of the token spec is TBD. But fundamentally, ERASE will be a burnable and mintable ERC20 contract.

Erasure Contract Spec


  • createMessage(uint256 nonce, string ipfsHash, uint256 revealedBy)
  • revealMessage(uint256 nonce, bytes32[] secret)


  • event MessageCreation(uint256 nonce, address creator);
  • event MessageReveal(uint256 nonce);

Marketplace Contract Spec


  • configureMinimumStake(uint256 minimumStake) => updates minimumStake during the configuration phase of the contract
  • configureGriefingRatio(uint256 stakeRatio) => updated griefingRatio (used for griefing) during the configuration phase of the contract
  • configureGriefingPeriod(uint256 griefingPeriodInWeeks)


  • createFeed(uint256 stakeToCreate, uint256 feePerPrediction)
  • cancelFeed(uint256 feedId) => can only be called if the feed doesn't have a buyer or if the feed is not in a griefing period. This also returns the seller stake.
  • endBuyerSellerRelationship(uint256 feedId) => can only be called by the seller or buyer. Unsets the buyer. 2 weeks following this, buyer or seller can slash stakes.
  • stakeToBuyFeed(uint256 feedId, uint256 stakeToBuy) => sets buyerAddress and escrows the stake, can only be called if buyerAddress of a given feed is unset
  • griefBuyer(uint256 feedId, address buyer, uint256 amount), can only be called by the seller for a specific feed within 2 weeks of ending relationship
  • griefSeller(uint256 feedId, uint256 amount), can only be called by the buyer for a specific feed within 2 weeks of ending relationship
  • updateFeePerPrediction(uint256 feedId, uint256 feePerPrediction) => only if feed doesn't have a buyer.
  • withdrawBuyerStake(uint256 feedId) => after the griefing period is over, the buyer can withdraw the leftover stake from the contract


  • createPrediction(uint256 feedId, uint256 nonce, string ipfsHash, uint256 revealedBy) => calls the Erasure contract to create the corresponding message object.
  • revealPredictionToBuyer(uint256 predictionId, bytes32[] buyerSecret)
  • revealPredictionToPublic(uint256 predictionId, bytes32[] publicSecret) => calls the Erasure contract to update the secret of the corresponding message object.
  • purchasePrediction(uint256 predictionId)


  • createUser(string publicKey) => Adds an address/publicKey pair to userAddressToPublicKey mapping, only for new Ethereum addresses.


  • event BuyerStakeWithdrawal(address buyer, uint256 buyerStake);
  • event FeedBuyerRemoval(uint256 feedId, address seller, address oldBuyer, address actor);
  • event FeedCancellation(uint256 feedId, address seller);
  • event FeedCreation(uint256 feedId, address seller);
  • event FeedFeePerPredictionUpdate(uint256 feedId, address seller, uint256 feePerPrediction);
  • event FeedPurchase(uint256 feedId, address seller, address buyer);
  • event GriefByBuyer(address buyer, address seller, uint256 buyerStake, uint256 sellerStake);
  • event GriefBySeller(address buyer, address seller, uint256 buyerStake, uint256 sellerStake);
  • event PredictionBuyerReveal(uint256 feedId, uint256 predictionId, address seller, address buyer);
  • event PredictionCreation(uint256 feedId, uint256 predictionId, address seller);
  • event PredictionPublicReveal(uint256 feedId, uint256 predictionId, address seller);
  • event PredictionPurchase(uint256 feedId, uint256 predictionId, address seller, address buyer);
  • event UserCreation(address userAddress, string publicKey);

ERASE Token Spec

Token Functionality

  • approveAll(address spender) => Sets the allowance from msg.sender to spender to 2 ^ 256 - 1
  • transferFrom(address from, address tto, uint value) => Modified version of the standard transferFrom. If the allowance is equal to 2 ^ 256 - 1, it doesn't adjust the allowance post transfer

Testing Functionality

  • buyTokensForTesting() => Current contract is set to give 1000 ERASE tokens for 1 ETH. This method receives ETH and mints tokens to the msg.sender.
  • distributeTokensForTesting(address[] accounts, uint256 amount) => This can only be called by the contract owner to mint tokens to an array of accounts
  • returnTokensForTesting(uint256 amount) => This is the reverse of buyTokensForTesting(). When the user sends ERASE tokens, they get ETH back (if they actually own the ERASE tokens). The ERASE tokens are in turn burned.


  • event ApproveAll(address sender, address spender);
  • event TestingBuyTokens(address account, uint256 amount);
  • event TestingDistributeTokens(address account, uint256 amount);
  • event TestingReturnTokens(address account, uint256 amount);



  • [ ] Add a CLI for easy interaction/manual testing
  • [ ] Add timestamps for creation, cancellation, griefing and reveal actions
  • [x] Optimize variable types and data structures to prevent unnecessary use of storage
  • [x] Make events useful for consumption by erasure-api


  • [x] If griefing period, buyer can't buy
  • [x] Switch away from modifier pattern
  • [x] Make sure token usage in Marketplace is in wei
  • [x] Write tests
  • [x] Add basic minting functionality to ERASE tokens
  • [x] Add burning token to ERASE for griefing
  • [x] Add approveAll call from the Marketplace contract
  • [x] Add comments to the smart contracts
  • [x] Add slashing functionality to work with the ability to slash stakes within 2 weeks of relationship termination.
  • [x] Add function to withdraw stakes
  • [x] Finish initial ERASE token logic with the ability to distribute tokens
  • [x] Add configuration method to adjust griefing ratio
  • [x] Add reasons to require statements
  • [x] Add getters for messages, feeds, predictions and users
  • [x] Call external contract at the end of functions to prevent potential reentrancy attacks
  • [x] Add ability to withdraw paid ETH upon revealing prediction


  • [x] Split Erasure message contract and marketplace contract login
  • [x] Add ability to stake ERASE tokens and buy predictions by sending ETH
  • [x] Switch from storing multiple IPFS hashes to storing IPFS hash + secret
  • [x] Add a mapping of Ethereum addresses to public keys for users


  • [x] Implement basic marketplace functionality
  • [x] Add ability to configure contract state variables (ie minimumStake)
  • [x] Build the bare-bones version of the ERASE token

Griefing Spec v0.1

  • 3 to 1 ratio in slashing.
  • You can only slash stakes of people you’ve been in a “buyer-seller” relationship with
  • Once you end a relationship, you have 2 weeks to slash stakes.

Simplifying assumptions

  • Staking factors are 1 to 3 and 3 to 1 per our discussion on Sunday (ie buyer can burn 1 token to burn 3 tokens of the seller and vice versa). Minimum stake is 10 tokens.
  • Stake is not only an indicator of confidence, but also an indicator of good business
  • One buyer per feed, no way to out-bid someone. The relationship needs to be explicitly terminated.
  • Structure of the file is formatted, with a nonce added to increase entropy
  • feePerFile is constant for a given feed if there is a buyer. Otherwise, the fee can be adjusted.


  • What type of upgradability options are available?
  • ERC20 tokens require an approve() call, before a transfer() is possible. That’s horrible UX. What is the best way to avoid this to make a single call? Current options, we’ve explored are:
    • Use a standard like ERC827. This has an approveAndCall() method that let’s us do what we want. However, according to OZ, there are some security issues.
    • Modify our ERC20 implementation to directly interface with the Erasure protocol.
    • Or this.
  • How much thought should we put in to designating state variables as public vs. private vs. internal?
  • What if a prediction is revealed first on the Erasure message? How should the marketplace contract behave?
  • Currently, we use uint64 for IDs, while most standard Ethereum apps seem to use uint256, is that a problem?

Deploying to Rinkeby, Mainnet

To deploy to rinkeby or mainnet, first configure your environment.

Generate a MNEMONIC using Metamask and get an API key from Infura

Make sure your account (the first address derived from your MNEMONIC) has at least 0.7 ETH, then run

MNEMONIC="your mnemonic" INFURA_API_KEY="your API key" yarn run migrate:rinkeby
# or
MNEMONIC="your mnemonic" INFURA_API_KEY="your API key" yarn run migrate:mainnet

Current Tags

  • 0.1.3                                ...           latest (a year ago)

4 Versions

  • 0.1.3                                ...           a year ago
  • 0.1.2                                ...           a year ago
  • 0.1.1                                ...           a year ago
  • 0.1.0                                ...           a year ago
Maintainers (1)
Today 0
This Week 0
This Month 0
Last Day 0
Last Week 0
Last Month 5
Dependencies (0)
Dev Dependencies (18)
Dependents (0)

Copyright 2014 - 2016 © |