Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OCT-1867: Add a rewards rate value for the server #421

Merged
merged 6 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion backend/app/infrastructure/routes/epochs.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@

from app.extensions import api, epochs
from app.infrastructure import OctantResource, graphql
from app.modules.octant_rewards.controller import get_octant_rewards
from app.modules.octant_rewards.controller import (
get_octant_rewards,
get_epoch_rewards_rate,
)

ns = Namespace("epochs", description="Octant epochs")
api.add_namespace(ns)
Expand Down Expand Up @@ -113,6 +116,15 @@ def get(self):
},
)

epoch_rewards_rate_model = api.model(
"EpochRewardsRate",
{
"rewardsRate": fields.Float(
required=True, description="Rewards rate for the given epoch."
)
},
)


@ns.route("/info/<int:epoch>")
@ns.doc(
Expand All @@ -131,3 +143,18 @@ def get(self, epoch: int):
app.logger.debug(f"Got: {stats}")

return stats.to_dict()


@ns.route("/rewards-rate/<int:epoch>")
@ns.doc(
description="Returns a rewards rate for given epoch. Returns data for all states of epochs.",
params={
"epoch": "Epoch number",
},
)
class EpochRewardsRate(OctantResource):
@ns.marshal_with(epoch_rewards_rate_model)
@ns.response(200, "Epoch's rewards rate successfully retrieved.")
def get(self, epoch: int):
app.logger.debug(f"Getting rewards rate for epoch {epoch}")
return {"rewardsRate": get_epoch_rewards_rate(epoch)}
6 changes: 6 additions & 0 deletions backend/app/modules/octant_rewards/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from app.exceptions import NotImplementedForGivenEpochState
from app.modules.dto import OctantRewardsDTO
from app.modules.registry import get_services
from app.modules.octant_rewards import core


def get_octant_rewards(epoch_num: int) -> OctantRewardsDTO:
Expand All @@ -24,3 +25,8 @@ def get_last_finalized_epoch_leverage() -> float:
service = get_services(context.epoch_state).octant_rewards_service

return service.get_leverage(context)


def get_epoch_rewards_rate(epoch_num: int) -> float:
context = epoch_context(epoch_num)
return core.get_rewards_rate(context.epoch_details.epoch_num)
9 changes: 9 additions & 0 deletions backend/app/modules/octant_rewards/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from app.engine.octant_rewards.operational_cost import OperationalCostPayload
from app.engine.octant_rewards.ppf import PPFPayload
from app.engine.octant_rewards.total_and_individual import TotalAndAllIndividualPayload
from app.modules.staking.proceeds.core import ESTIMATED_STAKING_REWARDS_RATE


@dataclass
Expand Down Expand Up @@ -66,3 +67,11 @@ def calculate_rewards(
ppf_value=ppf_value,
community_fund=cf_value,
)


def get_rewards_rate(_: int) -> float:
"""
Returns the rewards rate for the given epoch.
"""
# TODO Staking Rewards Rate is a static value for now but it may be calculated dynamically in the future: https://linear.app/golemfoundation/issue/OCT-1916/make-apr-a-dynamically-computed-one
return ESTIMATED_STAKING_REWARDS_RATE
6 changes: 3 additions & 3 deletions backend/app/modules/staking/proceeds/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@
ESTIMATED_STAKED_AMOUNT = 100000_000000000_000000000

# TODO call an API to get a real value instead of hardcoding: https://linear.app/golemfoundation/issue/OCT-902/api-call-to-get-validators-api
ESTIMATED_STAKING_APR = 0.038
ESTIMATED_STAKING_REWARDS_RATE = 0.038


def estimate_staking_proceeds(
epoch_duration_sec: int,
staked_amount=ESTIMATED_STAKED_AMOUNT,
apr=ESTIMATED_STAKING_APR,
staking_rewards=ESTIMATED_STAKING_REWARDS_RATE,
) -> int:
if epoch_duration_sec <= 0:
return 0
return int(int(staked_amount * apr) / 31536000 * epoch_duration_sec)
return int(int(staked_amount * staking_rewards) / 31536000 * epoch_duration_sec)


def sum_mev(
Expand Down
17 changes: 17 additions & 0 deletions backend/tests/modules/octant_rewards/test_apr_core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import pytest

from app.modules.octant_rewards.core import get_rewards_rate
from app.modules.staking.proceeds.core import ESTIMATED_STAKING_REWARDS_RATE


@pytest.fixture(autouse=True)
def before(app):
pass


@pytest.mark.parametrize("epoch_num", [1, 2, 3, 4, 5])
def test_get_epoch_rewards_rate_return_valid_value(epoch_num: int):
actual_result = get_rewards_rate(epoch_num)
expected_result = ESTIMATED_STAKING_REWARDS_RATE

assert actual_result == expected_result