npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

erasure-contracts

v0.1.3

Published

Contracts for Erasure, a decentralized marketplace for data feeds and predictions

Downloads

8

Readme

Erasure Smart Contracts

A decentralized marketplace for data feeds and predictions

Setup

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

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

Testing

yarn run ganache
yarn run test

Rough Spec

Contracts

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

Messages

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

Events

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

Marketplace Contract Spec

Configuration

  • 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)

Feeds

  • 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

Predictions

  • 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)

Users

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

Events

  • 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.

Events

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

TODOS

v0.0.4

  • [ ] 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

v0.0.3

  • [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

v0.0.2

  • [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

v0.0.1

  • [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.

Questions

  • 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