#!/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()
Last active
April 27, 2023 00:43
-
-
Save ilap/9b5a79cf1179a3f06bb57fca5d94cd3b to your computer and use it in GitHub Desktop.
Plot RSS with and without cost
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
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