The Ocean Data Farmer’s Guide to Maximizing Yield

A primer on maximizing rewards via publishing & wash consuming

Idiom
Ocean Protocol

--

0.1 Introduction

The latest release of ocean.py makes it very easy for us to interact with datatokens, the marketplace, veOCEAN, and Data Farming(DF). With it we’re able to easily play with the Ocean Protocol stack, use veOCEAN, and maybe even turn a profit (for now) by wash consuming and gaining reward from DF.

DF runs weekly, starting & ending on Thursdays @ midnight GMT. During this period the market is sampled, and all data assets are measured for `Data Consume Volume (DCV)` & `veOCEAN Allocated`. For each week, this is sampled 50 times to obtain an average, and to distribute Active Rewards for this period of participation.

“Wash Consuming” is when the publisher fake-consumes data to drive DCV to get more rewards. Not healthy for the ecosystem long-term. Good news: if consume fee > weekly rewards, then wash consume becomes unprofitable. DF is set up to make this happen by DF29 (if not sooner).

This blog post is technical in nature but tries to offer context to the reader so they can understand the intuitions behind Data Farming. If you are passionate and don’t give up easily, then you should be able to follow along and achieve positive results.

A happy data farm.

This blog post also delegates the responsibility of onboarding you, to existing documentation that helps you initialize your environment.

Finally, this code should not be used on a live network. By reading and following any of these actions, you absolve others of any injury and are solely responsible for your actions.

0.2 Project overview

Ocean is a complex project with many different pieces.

Do not worry, we’re making it extremely simple, only needing a few lines of code that you can follow step-by-step.

To get you excited, here are some of the things we’ll be using.

  • Github repositories.
  • A mixture of python and docker.
  • Ganache to test on a local network.
  • Brownie to connect our wallets.
  • Ocean to create a data asset.
  • Ocean to buy and consume data assets.

Whenever possible, I will point you to existing documentation and resources to avoid repeating them. Much of it is already explained in a way that is easy to understand.

This blog post tries to provide a bit more context and intuitions regards Data Farming, veOCEAN, and what you need to consider to farm successfully.

This blog post mirrors the “df.md” README. If you want to skip this post and get straight to work, df.md offers the best developer experience. Over time, this post’s code details may go out of date, but df.md will stay updated.

If you run into any problems and are stuck, you can join our community on discord to get help.

If you find any problems please submit an issue, but if you fix them, we love receiving PRs.

0.3 Post Outline

The rest of this blog post is organized into the following sections. They’re numbered the same as the df.md README.

  1. Setup, in Ganache
  2. Lock OCEAN for veOCEAN
  3. Publish dataset & exchange
  4. Allocate veOCEAN to dataset
  5. Fake-Consume data
  6. Collect OCEAN rewards
  7. Repeat steps 1–6, for Eth mainnet

Let’s go through each step.

1. Setup, in Ganache

Before we dive deeper, you will need to have docker and python installed in your system. Further, you will likely need a MacOS/Linux system to get through it.

1.1 Setup from console

This section is best handled with patience. The best way to complete it is to follow the install.md README. You will need to complete all steps there:

  • Prerequisites
  • Installing the Ocean library
  • Configuring brownie
  • Running Barge and services
  • Setting up test keys

Once you complete all of the steps above, you will have:

Terminal 1: An Ocean environment configured. Barge and Ganache running together.

Terminal 2: A local python project with some private keys for us to farm with.

You also need to set the factory envvar. In the console:

export FACTORY_DEPLOYER_PRIVATE_KEY=0xc594c6e5def4bab63ac29eed19a134c130388f74f019bc74b8f4389df2837a58
Barge running. Give yourself a pat on the back. Squeee!

2.2 Setup in Python

This section mirrors the simple-flow README “Setup in Python” section.

You should have two terminals open now. We’re going to resume from inside Terminal 2 where you entered the python virtual environment (venv).

Here, begin by typing `python` inside terminal, and entering the python console:

Entering the python console. Our happy place.

Key Point: For the rest of this blog post and exercise, we’re going to remain in the Python console. Every line of code entered for the remainder of this blog post should just work.

We’re going to start by making sure that the Ocean library is available, and wallets are accessible via Brownie.

In the Python console, enter the following:

# Create Ocean instance
from ocean_lib.web3_internal.utils import connect_to_network
connect_to_network("development")

from ocean_lib.example_config import get_config_dict
from ocean_lib.ocean.ocean import Ocean
config = get_config_dict("development")
ocean = Ocean(config)

# Create Alice's wallet
import os
from brownie.network import accounts
accounts.clear()
alice_private_key = os.getenv("TEST_PRIVATE_KEY1")
alice_wallet = accounts.add(alice_private_key)

Let’s review what this code does:

  1. Initializes the ocean library to use our local development network (Barge & Ganache).
  2. Obtains the configuration and initializes the Ocean library.
  3. Retrieves our private key and gives us a wallet to play with.

Great, after we run these commands inside the python console we have a wallet that we can start using.

2.3 Fake OCEAN

In order for us to use the Ocean marketplace and to play with Data Farming, we’re going to need some OCEAN and veOCEAN. Because we’re working in a development environment we start by minting OCEAN.

In the same Python console:

# mint OCEAN. Alice will get some
from ocean_lib.ocean.mint_fake_ocean import mint_fake_OCEAN
mint_fake_OCEAN(config)

# simpler variable names
OCEAN = ocean.OCEAN_token
veOCEAN = ocean.ve_ocean
alice = alice_wallet

Let’s review what this code does:

  • mints fake OCEAN, with some going to Alice
  • makes some convenient variable names

2. Lock OCEAN for veOCEAN

OCEAN is used to buy/sell datatokens, reward participants, and obtain veOCEAN.

veOCEAN is used to determine how rewards are distributed across the protocol, including via Data Farming. veOCEAN has a learning curve. But once you get the basics of it, it becomes intuitive. This is a great blog post to learn more about it.

First, let’s set some key parameters for veOCEAN and DF. On Ganache, you can use these values as-is. But on Eth mainnet, you must choose your own. In the same Python console:

# On your asset, your DCV = DT_price * num_consumes
# Your asset gets rewards pro-rata for its DCV compared to other assets' DCVs.
DT_price = 100.0 # number of OCEAN needed to buy one datatoken
num_consumes = 3

# This is how much OCEAN to lock into veOCEAN. It can be small if you're
# the only staker on your asset. If others stake on your asset, your
# rewards are pro-rate compared to others' stake in your asset.
amt_OCEAN_lock = 10.0

Now, let’s lock OCEAN for veOCEAN. In the same Python console:

#simulate passage of time, until next Thursday, the start of DF(X)
from brownie.network import chain
WEEK = 7 * 86400 # seconds in a week
t0 = chain.time()
t1 = t0 // WEEK * WEEK + WEEK #this is a Thursday, because Jan 1 1970 was
t2 = t1 + WEEK
chain.sleep(t1 - t0)
chain.mine()

#we're now at the beginning of the week. So, lock
from ocean_lib.ocean.util import to_wei, from_wei
OCEAN.approve(veOCEAN.address, to_wei(amt_OCEAN_lock), {"from" : alice})
veOCEAN.withdraw({"from": alice}) #withdraw old tokens first
veOCEAN.create_lock(to_wei(amt_OCEAN_lock), t2, {"from": alice})

Let’s review what this code does:

  1. Manipulates the clock so we are on a Thursday. Data Farming rounds Begin + End each Thursday at midnight GMT.
  2. We configure the amount of OCEAN we’re going to lock.
  3. We approve the veOCEAN contract, to take OCEAN from Alice’s wallet.
  4. We prepare to create the lock by withdrawing, making sure there are no old tokens.
  5. We create the lock using t2, which is configured to be 1 week from today.
  6. Alice now carries a veOCEAN balance.
  7. At the end of this, the clock is adjusted to start Data Farming, and we have defined some helper parameters to create a lock, and obtain veOCEAN.

Alice then creates a lock for 1 week using 10.0 OCEAN, receiving veOCEAN.

3. Publish Dataset & Exchange

If you have followed other READMEs, you might already be familiar with posting a dataset for sale on an exchange. We’re going to follow this pattern here in order to explain DF.

DF Key Concept #1: Data Consume Volume (DCV).

Every week, you can earn Active Rewards for the following actions:

  1. Locking Ocean to receive veOCEAN.
  2. Allocating veOCEAN to a DataNFT.
  3. Having datatokens associated with that DataNFT consumed.

So, if we can create our own dataset, point veOCEAN to it, and then consume from it, we can game DF. There are two things to know:

  1. Your asset DCV = datatoken_price_OCEAN * num_consumes.
  2. Your assets rewards are pro-rata = your_asset_DCV / other_assets_DCV.

DF Intuition #1: The more the item costs, and the more it’s consumed, the better it is for us. In the real world, Alice still needs to pay for fees.

DF Intuition #2: In the real world, Alice still needs to pay for fees.

Knowing all of this, create Alice’s data asset that will be consumed, then put 3 of it on the market with a cost of 100.0 OCEAN each.

Let’s put this into practice via code! In the same Python console:

#data info
name = "Branin dataset"
url = "https://raw.githubusercontent.com/trentmc/branin/main/branin.arff"

#create data asset
(data_NFT, DT, ddo) = ocean.assets.create_url_asset(name, url, alice, wait_for_aqua=False)
print(f"Just published asset, with data_NFT.address={data_NFT.address}")

#create exchange
exchange, _ = DT.create_exchange(
to_wei(DT_price), OCEAN.address, {"from": alice}
)

#make datatokens available on the exchange
DT.mint(alice, to_wei(num_consumes), {"from": alice})
DT.approve(exchange.address, to_wei(num_consumes), {"from": alice})

Let’s review what this code does:

  1. Defines all information required for the data asset.
  2. We have to consider that datatoken_price_OCEAN and the num_consumes to determine our DCV.
  3. If we want to make money from data farming, by wash consuming, we can improve performance by playing with these.
  4. Creates the data asset.
  5. Asset is configured to cost 100 OCEAN, with 3 available to be consumed.
  6. We obtain the data_NFT, datatoken, and asset.
  7. Creates an exchange object
  8. Takes the datatoken from Alice’s dataset and adds it to the public marketplace. By doing this, Alice receives revenue whenever the token is purchased.
  9. The token is configured to cost 100 OCEAN and to have 3 available.

We now have our data token launched and ready to be sold. If Alice is smart about it, maybe she can farm rewards too.

4. Stake on dataset, by allocating veOCEAN

Now that we have our asset available to be purchased, we can try to game DF a little.

DF Key Concept #2: veOCEAN Allocated (Round Allocation).

To keep it simple we’re going to allocate 100% of Alice’s veOCEAN to the data_NFT from the Branin dataset that we’re going to wash trade.

DF Intuition #3: DCV is multiplied by all veOCEAN allocated to it. So the more users are allocating veOCEAN to the same asset, the more dilluted the rewards will be.

In the same Python console:

amt_allocate = 100 #total allocation must be <= 10000 (wei)
ocean.ve_allocate.setAllocation(amt_allocate, data_NFT.address, chain.id, {"from": alice})

Let’s review what this code does:

  1. Allocates 100% of Alice’s Voting Power to the data_NFT.
  2. 100% allocation equals 10,000 because it uses integers to express decimal places. If you wanted to allocate 6.9%, you would allocate 690 points.

5. Fake-Consume Data

This step shows how to fake-consume.

Alice is going to consume her own data and receive most of her money back. In the real world, Alice still needs to pay for fees.

In the same Python console:

# Alice buys datatokens from herself
OCEAN_pay = DT_price * num_consumes
OCEAN_alice = from_wei(OCEAN.balanceOf(alice))
assert OCEAN_alice >= OCEAN_pay, f"Have just {OCEAN_alice} OCEAN"

OCEAN.approve(exchange.address, to_wei(OCEAN_alice), {"from": alice})
exchange.buy_DT(to_wei(num_consumes), {"from": alice})

DT_bal = from_wei(DT.balanceOf(alice))
assert DT_bal >= num_consumes, \
f"Have {DT_bal} datatokens, too few for {num_consumes} consumes"

# Alice sends datatokens to the service, to get access. This is the "consume".
for i in range(num_consumes):
print(f"Consume #{i+1}/{num_consumes}...")
ocean.assets.pay_for_access_service(ddo, alice)
#don't need to call e.g. ocean.assets.download_asset() since wash-consuming

Let’s review what this code does:

  1. Alice is going to buy tokens from herself
  2. We first make sure that Alice can afford to buy her own datatokens from the exchange. She then approves for the exchange to use her OCEAN to buy the datatokens.
  3. We then iterate through each item we want to consume, and buy it from the exchange using Alice’s wallet.
  4. Finally, we validate that we purchased the datatokens we wanted.
  5. Alice is going to send datatokens to pay for the service, and consume them.
  6. We iterate through all the datatokens we’re going to consume, and consume them.

Let’s review what happens economically:

  1. Alice published her own datatoken.
  2. Alice is buying her own data.
  3. Alice receives most of her money back.
  4. Alice consumes her own datatoken, causing her datatoken DCV to go up.
  5. Because Alice owns veOCEAN and has allocated to her data_NFT, she can game the rewards.

7. Collect OCEAN rewards

In the same Python console:

#simulate passage of time, until next Thursday, which is the start of DF(X+1)
WEEK = 7 * 86400 # seconds in a week
t0 = chain.time()
t1 = t0 // WEEK * WEEK + WEEK
t2 = t1 + WEEK
chain.sleep(t1 - t0)
chain.mine()

#Rewards can be claimed via code or webapp, at your leisure. Let's do it now.
OCEAN_before = from_wei(OCEAN.balanceOf(alice))
ocean.ve_fee_distributor.claim({"from": alice})
OCEAN_after = from_wei(OCEAN.balanceOf(alice))
print(f"Just claimed {OCEAN_after - OCEAN_before} OCEAN rewards")

7. Repeat steps 1–6, for Eth mainnet

We leave this as an exercise to the reader :)

We have now simulated wash-consuming and manipulating of DF. Because Alice participated in DF by using her veOCEAN and helped to curate good datasets (her own dataNFT) she should receive some rewards.

Theoretically, you might be able to replicate this on ETH Mainnet and profit.

Hint #1: Repeat steps 1–6 but use the initial setup of simple-remote flow.

Hint #2: If Data Farming samples the week 50 times, how can you best capture DCV & veOCEAN allocated throughout the whole round?

We also need to think about users who will allocate to Alice’s data_NFT and dilute our efforts of capturing DCV & veAllocate. If we look at the table below, and we are operating in Alice’s NFT, we have to consider how other users might come to take advantage of our wash consuming.

The more users wash-trade, the more competitive this game becomes and margins are reduced further. The way to win the meta quickly evolves to building products that naturally drive the consumption, price, and allocation of veOCEAN towards datatokens.

As outlined above when describing the evolution of Data Farming, the parameters and mechanisms are changing. Any edge available from this will come to an end.

Our focus is on building a market full of healthy participants and are looking forward to everyone joining us there.

The work outlined in this blog post is definitely NOT financial advice.

Happy Data Farming!

Appendix: Further Reading

The Data Farming Series post collects key articles and related resources about DF.

Follow Ocean Protocol on Twitter, Telegram, LinkedIn, Reddit, GitHub & Newsletter for project updates and announcements. And chat directly with other developers on Discord.

--

--