Better Reward Distribution

Pierrick
PoolTogether
Published in
5 min readJan 19, 2022

--

The PoolTogether protocol enables depositors to save money while winning prizes. In addition to prizes, the protocol also distributes tokens providing a fixed return for all depositors.

Historically these tokens were distributed in a simplistic way — accruing and claimable at any moment. This was easy to take advantage of by short term depositors who just claimed tokens and left (in crypto speak “farmers”). Because of this, fixed token distribution in the V3 protocol was ended when the V4 protocol launched.

The new V4 protocol is capable of distributing fixed returns in far better way with the “TWAB Rewards Contract”. TWAB stands for “time weighted average balance” and is a mechanism for distributing fixed return for all depositors based on their average balance over a period of time.

It’s a simple and extremely powerful primitive, the benefits are:

  • The ability for anyone to distribute any token based on a users average deposit over a period of time.
  • The ability to set when a reward is claimable (i.e. every two weeks, or four weeks, etc).
  • The ability to distribute these rewards without requiring staking

The contract provides a brand new primitive for rewarding depositors into the PoolTogether protocol. These rewards can be provided by POOL governance or any third party!

The TWAB contract is live and has been audited in a $25,000 Code Arena security competition. Read more about how it works in the documentation or check out the technical overview below!

Technical Overview

TWAB, or Time-Weighted Average Balance, is a concept wholly inspired by Uniswap’s Time-Weighted Average Price. It is described here. We use TWAB to calculate the average deposit held by a user during a specific time period.

Here’s how it works.

Users deposit ERC20 tokens, usually a stablecoin like USDC, into a prize pool and then receive tokens to represent their deposit. When the tokens are minted a new TWAB is recorded.

A TWAB record is a tuple made with an amount and a timestamp. The amount stores the cumulative Time-Weighted Balance. This value is always increasing. The timestamp is taken from the block in which the transaction is mined and the TWAB recorded. The TWAB is recorded before a user balance changes. Which gives us the following formula:

new TWAB amount = last TWAB amount + current balance * (current time - last TWAB timestamp)
new TWAB timestamp = current block timestamp

Let’s review a concrete example:

For the sake of simplicity, we will base our example on a 24 hour timeline, also called epoch, that starts at block 0 and ends at block 5,760 since a new block is mined every 15 seconds.

Our user decides to deposit at block 1,440, or 6 hours into our timeframe. At this time, the recorded amount is still 0. Remember, the TWAB amount is recorded before a user balance changes and the current block timestamp is 21,600.

We then retrieve the user balance at the end of the 24 hour timeframe, block 5,760. Using the formula above, the TWAB amount is:

TWAB amount = 0 + 1000 * (86400 - 21600) = 64800000

With this new recorded TWAB amount we can calculate the user average balance during this 24 hour timeframe with the following formula:

average balance = (last TWAB amount - first TWAB amount) / (last TWAB timestamp - first TWAB timestamp)

Which gives us:

average balance = (64800000 - 0) / (86400 - 0) = 750

How to calculate rewards

Now that we have reviewed how to compute a TWAB, we can easily calculate the rewards for our user.

Let’s take our previous example with a reward pot of $1,000 and two users that deposit $1,000 into the pool at different timestamps.

The following formula is used to compute how many rewards a user is entitled to receive:

reward amount = (reward pot * user average balance) / average total supply;

At block 5,760 Bob has an average balance of $750 and Alice has $250. Since they are the only two users who deposited, the average total supply during the 24 hour period is $1000.

Knowing this, we can easily calculate the amount of rewards per user:

bob rewards = (1000 * 750) / 1000 = 750
alice rewards = (1000 * 250) / 1000 = 250

But sir, what about gas cost?

As you may have guessed by now, the TWAB calculation and recording incurs an overhead to Ticket mint, transfer and burn costs. Assuming a cold account is an address that has not held any tokens, and a hot account is one that has held tokens in the past, we have some approximate gas usage:

  • mint (cold): 140k
  • transfer (hot -> cold): 120k
  • transfer (hot -> hot): 90k

After testing transactions on Rinkeby, we observe the following results:

So we can safely assume that the base cost to claim an epoch is 94k gas and 16k gas for each additional epoch claimed.

Contribute to the PoolTogether Protocol via the DAO Grants Program

PoolTogetherDAO is searching for experienced React/Web3 developers to make meaningful contributions. Serious contributors can be compensated via the PoolTogether DAO Grants Program.

Documentation

PoolTogether V4 documentation is available at docs.pooltogether.com

Have a feature request or just want to ask questions?

Join the PoolTogether Discord or leave a comment.

--

--