Variable Rate GDAs

08.24.2022|transmissions11FrankieDave White

Overview

This paper introduces a novel token issuance mechanism. Variable Rate GDAs (VRGDAs), designed for Art Gobblers and used in 0xMonaco, let you sell tokens close to a custom schedule over time by raising prices when sales are ahead of schedule and lowering prices when sales are behind schedule — a generalization of the GDA mechanism.

We provide both an overview of the mechanism and a highly optimized, production-ready Solidity implementation of the core mechanism and several example schedules.

Motivation

Art Gobblers is a digital art experiment by Justin Roiland and Paradigm. An important objective of the project was to create a self-sustaining ecosystem that could thrive on its own without human intervention for years to come.

There are two core NFTs in this system, and we wanted anyone to be able to purchase either at any time.

We wanted to issue both relatively quickly at first. Over time, one tops out at a fixed supply, whereas the other is issued at a slow constant rate forever.

We sought to achieve these goals while maintaining a seamless user experience that would allow users to buy NFTs at any time, without having to, for example, wait for a scheduled auction.

Our solution was VRGDAs, a generalization of GDAs that allows for arbitrary scheduling of NFT issuance, as opposed to the uniform linear scheduling of standard GDAs.

Mechanism

Building Intuition

Imagine a simple schedule where we want to sell 10 NFTs per day. We set a starting price of 1 token for the first NFT.

Suppose it is currently day 5, so we should have sold 50 NFTs. However, demand has been high, and we have sold 70. We weren’t supposed to sell 70 NFTs until day 7, so we are two days ahead of schedule.

As a result, we want to charge a higher price going forward. We use an exponential curve to determine how much higher. This can vary based on parameters, but in this case, let’s say we use

2days ahead of schedule2^\text{days ahead of schedule}
, so that we increase our price by a factor
22=42^2=4
, so since our initial price was 1 token, the new price will be 4 tokens, making it harder to buy more NFTs.

Ten days later, on day 15, we should have sold 150 NFTs, but users have only bought 120, the amount they should have bought by day 12, meaning we are three days behind schedule. We adjust the price to , making it easier for users to buy more NFTs.

Ten days later, on day 15, we should have sold 150 NFTs, but users have only bought 120, the amount they should have bought by day 12, meaning we are three days behind schedule. We adjust the price to

23=0.1252^{-3}=0.125
, making it easier for users to buy more NFTs.

Construction

Parameters

p0p_0
- The price an NFT would sell for if sold perfectly on pace (the target price).

kk
-
The percentage an NFT’s price decreases in a unit of time with no purchases.

f(t)f(t)
- The issuance schedule: maps t to the number of NFTs to aim to sell by that time.

Objective

We want to issue NFTs on a particular schedule. The mechanism we will use to do this is to raise prices if NFTs are sold ahead of schedule and lower them if they are sold behind schedule. If sales are perfectly on schedule, the price to buy the next one will remain the same.

Definitions

Let’s say we want to sell NFTs at a schedule described by

f(t)f(t)
, which maps a point in time to the cumulative number of NFTs we want to have sold by that time. For example, if we want to sell one NFT every two days, we’d define 
f(t)f(t)
like so:

f(t)=t2f(t) = \frac{t}{2}

Let’s also say we want to sell our NFTs using a separate Dutch Auction per NFT. If we set each NFT’s starting price at 1, and let this price decay by a rate of per unit of time with no sales, its price if purchased at time 

tt
will be:

(1k)t(1-k)^t

To give ourselves the flexibility we need to achieve our objective, we can shift the starting point of the auction in time by some

sns_n
, which we will derive below, so that the price at time 
tt
is:

(1k)tsn(1-k)^{t-s_n}

If we want our target price to be different than 1, we can multiply by a constant

p0p_0
. We call this adjusted price
vrgdan(t)\texttt{vrgda}_n(t)
:

vrgdan(t)=p0(1k)tsn\texttt{vrgda}_n(t) = p_0(1-k)^{t-s_n}

Determining
sns_n

According to our issuance schedule

ff
, we want to sell the
nn
th NFT at time
tnt_n
. We can define 
tnt_n
by inverting 
ff
to get a mapping from 
nn
to the time it should be sold:

tn=f1(n)t_n = f^{-1}(n)

A consequence of the VRGDA objective is that if the

nn
th NFT is purchased exactly at the target time according to its issuance schedule, its price will be
p0p_0
. Expressed formally, this means that if we are selling at exactly the target rate, then at time
tnt_n
, the
nn
th NFT will be priced such that:

p0(1k)tnsn=p0p_0(1-k)^{t_n-s_n}=p_0

Simplifying by dividing out

p0p_0
, we know that the following should always hold true:

(1k)tnsn=1(1-k)^{t_n-s_n}=1

Which implies

tnsn=0t_n-s_n=0
or
sn=tns_n=t_n
. Using our definition of
tnt_n
from above, we know
sn=f1(n)s_n = f^{-1}(n)
.

Final Formula

By substituting this definition of

sns_n
into
vrgdan(t)\texttt{vrgda}_n(t)
, we end up with the final formula:

vrgdan(t)=p0(1k)tf1(n)\texttt{vrgda}_n(t) = p_0(1-k)^{t-f^{-1}(n)}

Simple Issuance Schedules

Below we demonstrate deriving some simple issuance schedules to use with the VRGDA formula.

Linear

Let’s say we want to sell

rr
NFTs per day. Then
f(t)=rtf(t) = rt
, so
f1(t)=trf^{-1}(t) = \frac{t}{r}


After plugging this

f1(t)f^{-1}(t)
into the VRGDA pricing formula, we end up with the following:

linear_vrgdan(t)=p0(1k)tnr\texttt{linear\_vrgda}_n(t) = p_0(1-k)^{t-\frac{n}{r}}

Note this is isomorphic to a GDA, which is why we call VRGDA a generalization of GDA.

Square Root

Let’s say that we want to issue NFTs at a rate proportional to the square root of time — for example, to issue NFTs more quickly at first, and then more slowly over time, but without ever stopping.

We can then set

f(t)=tf(t) = \sqrt{t}
, so that on day 1 we have sold 1 NFT, on day 4 we have sold 2, on day 9 we have sold 3, and so on.

In this case,
f1(n)=n2f^{-1}(n) = n^2
. Now we simply plug into the VRGDA pricing formula to get:

sqrt_vrgdan(t)=p0(1k)tn2\texttt{sqrt\_vrgda}_n(t) = p_0(1-k)^{t-n^2}

Logistic Issuance Schedule

The logistic issuance schedule is somewhat complex compared to the examples above. However, we have chosen to cover it in detail nonetheless as it provides a way to bootstrap initial growth without enforcing an infinite inflation regime.

Motivation

Let’s say we want to issue NFTs quickly at first, but then slow down until eventually some maximum number have been issued, as is the case in Art Gobblers.

One clean way to model this is using the logistic function with positive domain.

Deriving
ff

The logistic function is an S-shaped curve. We’ll simplify it slightly and define it as:



l(t)=11+etl(t) =\frac{1}{1 + e^{-t}}

This curve approaches 0 as

tt
approaches negative infinity, and 1 as
tt
approaches infinity.

For our particular application, we don’t want to use the full S curve (although it’s also possible to have a full logistic VRGDA that would start slow, speed up, and then slow down again). Instead, we want to use only the part of the curve where
tt
is positive.

Because
l(0)=0.5l(0)=0.5
, but we want our schedule to indicate selling 0 NFTs at time 0, we need to shift this function down by subtracting 0.5. This new curve will go from 0 to 0.5:

h(t)=11+et0.5h(t)=\frac{1}{1 + e^{-t}}-0.5

We want to issue

L1L-1
NFTs (we choose this for notational convenience since the function will asymptote out before it hits
LL
), so we will need to scale this function by a factor of
2L2L
.

We can also introduce a time-scaling parameter
ss
to adjust the speed at which to issue the NFTs:

f(t)=2L1+estLf(t)=\frac{2L}{1 + e^{-st}}-L

To pick

ss
, observe that:

f(t)L=21+est1\frac{f(t)}{L}=\frac{2}{1 + e^{-st}}-1

Furthermore:

f(1s)L=21+e110.46\frac{f(\frac{1}{s})}{L}=\frac{2}{1 + e^{-1}}-1\approx0.46

This means we can pick

ss
by picking the time by which we want about 46% of the NFTs to be issued. For example, if we want 46% of the NFTs to be issued after 100 time units, that means
1s=100\frac{1}{s}=100
, so that
s=1100s=\frac{1}{100}
.

Formula

Taking the inverse of 

f(t)f(t)
from above yields:

f1(n)=ln(2LL+n1)sf^{-1}(n) = - \frac{\text{ln}\left(\frac{2L}{L+ n} - 1\right)}{s}

Putting this all together, we end up with the following formula:

logistic_vrgdan(t)=p0(1k)t+ln(2LL+n1)s\texttt{logistic\_vrgda}_n(t) = p_0(1-k)^{t+ \frac{\text{ln}\left(\frac{2L}{L+ n} - 1\right)}{s}}

Implementation

A highly optimized, production ready, and permissively licensed (MIT) implementation of VRGDAs and an assortment of issuance schedules can be found at transmission11/VRGDAs. Pull requests with improvements are welcome.

Conclusion

VRGDAs provide a way to issue NFTs using nearly any schedule you would like while still allowing users to seamlessly buy them at any time.

In the case of Art Gobblers, they allowed us to customize our community growth and UGC dynamics. In the case of 0xMonaco, it created a challenging and highly competitive game loop.

We believe there many other potential applications across NFTs, on-chain gaming, DeFi, and beyond. If you’d like to explore them, we’d love to hear from you. You can reach us on Twitter at @transmissions11, @FrankieIsLost and @_Dave__White_.

We can’t wait to see what you build.

Written by

Biography

Transmissions is a Research Associate at Paradigm. Transmissions works to push the effiency frontier of smart contracts by developing optimized libraries and primitives. He is also interested in intepreting and programmatically steering large language models. He currently attends high school in California.

Frankie

Partner, Investing & Research

Biography

Frankie is a Partner at Paradigm. Previously, Frankie was a machine learning engineer, quantitative developer, and trader. He holds a degree in computer science and econometrics.

Biography

Dave White is a Research Partner at Paradigm. Previously, Dave was a quantitative trader and researcher at firms including Headlands, Two Sigma, and Cutler Group. He is three credits shy of an A.B. in Mathematics from Harvard University.

Disclaimer: This post is for general information purposes only. It does not constitute investment advice or a recommendation or solicitation to buy or sell any investment and should not be used in the evaluation of the merits of making any investment decision. It should not be relied upon for accounting, legal or tax advice or investment recommendations. This post reflects the current opinions of the authors and is not made on behalf of Paradigm or its affiliates and does not necessarily reflect the opinions of Paradigm, its affiliates or individuals associated with Paradigm. The opinions reflected herein are subject to change without being updated.

Copyright © 2024 Paradigm Operations LP All rights reserved. “Paradigm” is a trademark, and the triangular mobius symbol is a registered trademark of Paradigm Operations LP