Skip to content

Instantly share code, notes, and snippets.

@ilap
Last active April 27, 2023 00:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ilap/9b5a79cf1179a3f06bb57fca5d94cd3b to your computer and use it in GitHub Desktop.
Save ilap/9b5a79cf1179a3f06bb57fca5d94cd3b to your computer and use it in GitHub Desktop.
Plot RSS with and without cost

Plot RSS with and without cost

#!/usr/bin/env python3

import math

import matplotlib.pyplot as plt
import numpy as np

class RSS:
    def __init__(self):
        self.max_roi         = 10.0 # Max ROI in % to show in graph
        self.k               = 500
        self.epoch_days      = 5
        self.total           = 35340386993 # epoch 386
        self.supply          = 45000000000
        self.expansion       = 0.003 # rho
        self.treasury        = 0.2   # tau
        self.cost            = 340.0 # in ADA
        self.margin          = 0.0299
        self.a0              = 0.3
        self.epochs          = 365 // self.epoch_days

    def f(self, pledge, total_stake):
        z0 = 1 / self.k
        a = self.a0
        p = min(pledge,z0)
        s = min(total_stake,z0)
        R = self.R()
        r = R/(1+a) * (s+p*a*(s-p*((z0-s)/z0))/z0)
        return r
    
    # r_op=c+(f-c)(m+(1-m)p/s)
    def op_reward(self, pledge, total_stake):

        if total_stake == 0:
            return 0.0;
        
        r = self.f(pledge, total_stake)
        c = self.cost
        m = self.margin
        return c if r <= c else c+(r-c)*(m+(1-m)*(pledge/total_stake))
    
    # r_mem=(f-c)*(1-m)(s-p)/s
    def member_reward(self, pledge, total_stake):
        if total_stake == 0:
            return 0.0;
        
        r = self.f(pledge, total_stake)
        c = self.cost
        m = self.margin
        mrev = 0.0 if r <= c else (r-c)*(1-m)*((total_stake-pledge)/total_stake)
        return mrev
    
    def R(self):
        t = self.treasury
        e = self.expansion
        s = self.supply
        c = self.total
        # If  (1 - t) * e *(math.e ** (-e*self.epoch))  * (s - c)
        return (1 - t) * e * (s - c)
    
    def o_roi(self, pledge, total_stake):
  
        if pledge > total_stake:
            return
       
        pledge_as_ada = 1 if pledge == 0.0 else pledge * self.total
        
        roi = self.op_reward(pledge, total_stake) * self.epochs * 100 / pledge_as_ada
        m = self.max_roi
        return roi if roi <= m else m
    
    def m_roi(self, pledge, total_stake):

        if pledge >= total_stake:
            return

        mstak_as_ada = (total_stake - pledge) * self.total
        
        er = self.member_reward(pledge, total_stake)
        tr = er * self.epochs
        roi =  tr * 100 / mstak_as_ada
        m = self.max_roi
        return roi if roi <= m else m

# Main
rss = RSS()

z0 = 1 / rss.k
s=z0 / 100

# 0.0001 means 3.4m pledge
# 0.00001 means 340k pledge
# 0.000001 means 34k pledge
min_p = 0.0   # Min pledge

# You can simulate the reward decay when y i.e., delegation is larger than z0 e.g., 2*z0+s
max_s = z0+s  # Max total_stake

# x is pledge
x = np.arange(min_p, max_s, s)
y = np.arange(min_p, max_s, s)

fig = plt.figure(figsize=plt.figaspect(0.5))
ax = fig.add_subplot(1, 2, 1, projection='3d')

# Cost 340
X, Y = np.meshgrid(x,y)

f = np.vectorize(rss.o_roi)
ZO = f(X, Y)

f = np.vectorize(rss.m_roi)
ZM = f(X, Y)

ax.plot_surface(X, Y, ZO)
ax.plot_surface(X, Y, ZM)
ax.set(xlabel="Pledge", ylabel="Delegations", zlabel="ROI in %", title="With Cost 340")
ax.set_zlim(-0.01, rss.max_roi)

# No cost
rss.cost = 0.0
f = np.vectorize(rss.o_roi)
ZO = f(X, Y)

f = np.vectorize(rss.m_roi)
ZM = f(X, Y)

ax = fig.add_subplot(1, 2, 2, projection='3d')
ax.plot_surface(X, Y, ZO)
ax.plot_surface(X, Y, ZM)
ax.set(xlabel="Pledge", ylabel="Delegations", zlabel="ROI in %", title="Without Cost")
ax.set_zlim(-0.01, rss.max_roi)

plt.show()
@ccgarant
Copy link

Wow! Awesome. A while back I was trying to make a jupyter notebook of the RSS curve and include slider widgets. I was messing up the equations and values though. This will be a big help. Great work. Feel free to take anything you may need here to make a notebook...

https://github.com/ccgarant/cardano-cip-50-draft-liesenfelt-supporting-work/blob/main/new_rewards/cip-50-analysis-and-viz.ipynb

@ccgarant
Copy link

If you're interested, a bunch of us from the cardano forum have created a Cardano Professional Society in the decentralized privacy focused "discord" of Matrix.org Space. We have a room where we discuss RSSv2. Definitely welcome to join, it's open of course. Cheers. I just shared this link in the room, Phillipee Le Long gave you high regards.

https://matrix.to/#/#Cardano_Professional_Society:matrix.org

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment