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

Predictoor 5X Boost #824

Merged
merged 25 commits into from
Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8c5526b
Add boost for predictoor assets in reward calculation
trizin Mar 22, 2024
9bf25f8
Resolve division by 0 and rename var
trizin Mar 24, 2024
77ed088
Fix indent
trizin Mar 24, 2024
6a8a27a
Fix var names
trizin Mar 24, 2024
b3856e2
Linter and black
trizin Mar 24, 2024
ebdbd7e
Refactor reward calculation to limit boost per asset
trizin Mar 24, 2024
38331b1
Add test_volume_reward_calculator_pdr_boost test
trizin Mar 24, 2024
212505d
Formatting
trizin Mar 24, 2024
b33b9fe
Refactor volume reward calculator tests to use SAPPHIRE_MAINNET constant
trizin Mar 24, 2024
b3c11b8
Update volume rewards calculation for predictoor assets
trizin Mar 24, 2024
7fa082d
Black
trizin Mar 24, 2024
cc5153a
Create a constant for sapphire mainnet chainid
trizin Mar 24, 2024
280481e
Merge branch 'main' into issue822-5x-predictoor-boost
trizin Mar 24, 2024
5b8b763
Fix import order
trizin Mar 24, 2024
36d46f2
Enable conftest
trizin Mar 24, 2024
1598e0d
Revert changes
trizin Mar 27, 2024
baa815d
x5 multiplier
trizin Mar 27, 2024
d71d18e
Add test for volume_reward_calculator_pdr_multiplier function
trizin Mar 27, 2024
e38b4b3
Merge branch 'issue822-5x-predictoor-boost' of https://github.com/oce…
trizin Mar 27, 2024
211e0ca
Update test_calc_dcv_multiplier and add new cases
trizin Mar 27, 2024
0590c4e
Black
trizin Mar 27, 2024
43dcccf
Remove unused import
trizin Mar 27, 2024
d6efbf0
Update test volume
trizin Mar 27, 2024
64ccbb2
Remove parametrization
trizin Mar 27, 2024
8a365b0
Fix DF_week
trizin Mar 27, 2024
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
1 change: 1 addition & 0 deletions df_py/util/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
PREDICTOOR_RELEASE_WEEK = 62
PREDICTOOR_OCEAN_BUDGET = 37_500
PREDICTOOR_DF_FIRST_DATE = datetime(2023, 11, 9)
SAPPHIRE_MAINNET_CHAINID = 23294

# volume
# Weekly Percent Yield needs to be 1.5717%., for max APY of 125%
Expand Down
5 changes: 2 additions & 3 deletions df_py/util/dftool_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from df_py.util import blockrange, dispense, get_rate, networkutil, oceantestutil
from df_py.util.base18 import from_wei, to_wei
from df_py.util.blocktime import get_fin_block, timestr_to_timestamp
from df_py.util.constants import SAPPHIRE_MAINNET_CHAINID
from df_py.util.contract_base import ContractBase
from df_py.util.dftool_arguments import (
CHAINID_EXAMPLES,
Expand Down Expand Up @@ -437,12 +438,10 @@ def do_calc():
calc_volume_rewards_from_csvs(csv_dir, start_date, tot_ocean)

if arguments.SUBSTREAM == "predictoor_rose":
SAPPHIRE_MAINNET_ID = 23294

predictoor_data = load_predictoor_data_csv(csv_dir)
print("Loaded predictoor data:", predictoor_data)
predictoor_rewards = calc_predictoor_rewards(
predictoor_data, arguments.TOT_OCEAN, SAPPHIRE_MAINNET_ID
predictoor_data, arguments.TOT_OCEAN, SAPPHIRE_MAINNET_CHAINID
)
print("Calculated rewards:", predictoor_rewards)

Expand Down
3 changes: 2 additions & 1 deletion df_py/util/dispense.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from web3.main import Web3

from df_py.util.base18 import to_wei
from df_py.util.constants import SAPPHIRE_MAINNET_CHAINID
from df_py.util.contract_base import ContractBase
from df_py.util.logger import logger
from df_py.util.multisig import send_multisig_tx
Expand Down Expand Up @@ -63,7 +64,7 @@ def dispense(
sts = list(range(N))[::batch_size] # send in batches to avoid gas issues

LEGACY_TX = False
if web3.eth.chain_id == 23294:
if web3.eth.chain_id == SAPPHIRE_MAINNET_CHAINID:
LEGACY_TX = True

def approveAmt(amt):
Expand Down
46 changes: 42 additions & 4 deletions df_py/volume/reward_calculator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@
from enforce_typing import enforce_types

from df_py.predictoor.queries import query_predictoor_contracts
from df_py.util.constants import DEPLOYER_ADDRS, TARGET_WPY
from df_py.util.constants import (
DEPLOYER_ADDRS,
PREDICTOOR_MULTIPLIER,
PREDICTOOR_OCEAN_BUDGET,
SAPPHIRE_MAINNET_CHAINID,
TARGET_WPY,
)
from df_py.util.dcv_multiplier import calc_dcv_multiplier
from df_py.volume import cleancase as cc
from df_py.volume.rank import rank_based_allocate
Expand Down Expand Up @@ -176,6 +182,20 @@ def calc_rewards__usd(self) -> np.ndarray:

# compute rewards
R = np.zeros((N_i, N_j), dtype=float)

OCEAN_boost_limit_predictoor = 0.0
# Boost is limited to Sapphire mainnet only
if SAPPHIRE_MAINNET_CHAINID in self.predictoor_feed_addrs:
# Total boost is limited by PREDICTOOR_OCEAN_BUDGET
# Get the number of predictoor assets and calculate the limit per asset
n_predictoor_assets = len(
self.predictoor_feed_addrs[SAPPHIRE_MAINNET_CHAINID]
)
if n_predictoor_assets != 0:
OCEAN_boost_limit_predictoor = (
PREDICTOOR_OCEAN_BUDGET / n_predictoor_assets
)

trentmc marked this conversation as resolved.
Show resolved Hide resolved
for j in range(N_j):
stake_j = sum(S[:, j])
multiplier = self.M[j]
Expand All @@ -193,10 +213,28 @@ def calc_rewards__usd(self) -> np.ndarray:

# main formula!
# reward amount in OCEAN
rewards = perc_at_j * perc_at_ij * self.OCEAN_avail
apy_bound = TARGET_WPY * ocean_locked_ij
dcv_bound = DCV_OCEAN_j * perc_at_ij * multiplier

# check if predictoor asset and apply boost
# NOTE another asset might have the same multiplier value in the future
# Find a better way to check if the asset is a predictoor asset
if multiplier == PREDICTOOR_MULTIPLIER:
# amount of dcv boosted
boosted_dcv = min(OCEAN_boost_limit_predictoor, DCV_OCEAN_j)
# amount of dcv remaining
remaining_dcv = max(0, DCV_OCEAN_j - OCEAN_boost_limit_predictoor)
boosted_reward_bound = boosted_dcv * multiplier * 5 # 5X BOOST
remaining_reward_bound = remaining_dcv * multiplier # Remaining
dcv_bound = (
boosted_reward_bound + remaining_reward_bound
) * perc_at_ij

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Like mentioned above, remove all these changes.)

R[i, j] = min(
perc_at_j * perc_at_ij * self.OCEAN_avail,
ocean_locked_ij * TARGET_WPY, # bound rewards by max APY
DCV_OCEAN_j * perc_at_ij * multiplier, # bound rewards by DCV
rewards,
apy_bound,
dcv_bound,
)

# filter negligible values
Expand Down
93 changes: 92 additions & 1 deletion df_py/volume/test/test_calc_rewards.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
from enforce_typing import enforce_types
from pytest import approx

from df_py.util.constants import ZERO_ADDRESS
from df_py.util.constants import (
PREDICTOOR_OCEAN_BUDGET,
SAPPHIRE_MAINNET_CHAINID,
ZERO_ADDRESS,
)
from df_py.volume import csvs
from df_py.volume.calc_rewards import calc_volume_rewards_from_csvs
from df_py.volume.reward_calculator import TARGET_WPY, RewardCalculator
Expand Down Expand Up @@ -752,3 +756,90 @@ def mock_multipliers(DF_week, is_predictoor): # pylint: disable=unused-argument
assert rewards_info[C1][NA][LP1] == approx(60.3, abs=1e-5)
assert rewards_info[C2][NB][LP2] == 300
assert rewards_info[C2][NB][LP3] == 300


@enforce_types
def test_volume_reward_calculator_pdr_boost(tmp_path):
trentmc marked this conversation as resolved.
Show resolved Hide resolved
chain_id = SAPPHIRE_MAINNET_CHAINID
stakes = {
chain_id: {NA: {LP1: 2e8}, NB: {LP2: 1e8}},
}
locked_amts = {
chain_id: {NA: {LP1: 1e8}, NB: {LP2: 1e8}},
}
volumes = {
chain_id: {
OCN_ADDR: {
NA: PREDICTOOR_OCEAN_BUDGET / 2 - 1,
NB: PREDICTOOR_OCEAN_BUDGET * 2,
}
},
}
owners = {chain_id: {NA: LP5, NB: LP2}}
symbols = {chain_id: {OCN_ADDR: OCN_SYMB}}
rates = {OCN_SYMB: 1.0}

predictoor_contracts = {NA: {}, NB: {}}

def mock_multipliers(DF_week, is_predictoor): # pylint: disable=unused-argument
if not is_predictoor:
return MagicMock(return_value=1)
return 0.201

OCEAN_reward = 1e24

with patch(
"df_py.volume.allocations.load_stakes",
return_value=(stakes, locked_amts),
), patch("df_py.volume.csvs.load_nftvols_csvs", return_value=volumes), patch(
"df_py.volume.csvs.load_owners_csvs", return_value=owners
), patch(
"df_py.volume.csvs.load_symbols_csvs", return_value=symbols
), patch(
"df_py.volume.csvs.load_rate_csvs", return_value=rates
), patch(
"df_py.volume.reward_calculator.calc_dcv_multiplier", mock_multipliers
), patch(
"df_py.volume.reward_calculator.query_predictoor_contracts",
return_value=predictoor_contracts,
), patch(
"df_py.volume.reward_calculator.DEPLOYER_ADDRS",
{chain_id: ""},
), patch(
"df_py.util.dcv_multiplier.get_df_week_number", return_value=30
), patch(
"df_py.volume.calc_rewards.wait_to_latest_block"
), patch(
"web3.main.Web3.to_checksum_address"
) as mock:
mock.side_effect = lambda value: value

calc_volume_rewards_from_csvs(tmp_path, None, OCEAN_reward, True, False)

rewards_per_lp = csvs.load_volume_rewards_csv(str(tmp_path))

# OCEAN_reward was 1e24, it's a lot so it's not a constraint
# The predictoor boost per asset is limited at PREDICTOOR_BUDGET / 2
# NA and NB are predictoor assets

# NA has PREDICTOOR_OCEAN_BUDGET / 2 - 2 volume
# --> since the volume is smaller than boost limit, all DCV is boosted to 5x
# --> DCV bound = (PREDICTOOR_BUDGET / 2 - 1) * 0.201 * 5

# NB has PREDICTOOR_BUDGET * 2 volume
# Thus only the volume up to the budget is boosted
# --> DCV bound = PREDICTOOR_BUDGET / 2 * 0.201 * 5 + (PREDICTOOR_BUDGET / 2) * 0.201

vol1 = PREDICTOOR_OCEAN_BUDGET / 2 - 1
boosted = vol1 * 0.201 * 5
assert rewards_per_lp[chain_id][LP1] == approx(boosted, abs=1e-5)

vol2 = PREDICTOOR_OCEAN_BUDGET * 2
boosted_amt = (
PREDICTOOR_OCEAN_BUDGET / 2
) # divided by 2 because 2 predictoor assets
boosted = (boosted_amt) * 0.201 * 5 # 5x boost
remaining_dcv = (vol2 - boosted_amt) * 0.201
assert rewards_per_lp[chain_id][LP2] == approx(
boosted + remaining_dcv, abs=1e-5
)
Loading