From 069036c0a75d1cb41ee99558e01935ee7aa9f8cc Mon Sep 17 00:00:00 2001 From: rolandpo Date: Fri, 22 Sep 2023 14:47:43 +0200 Subject: [PATCH 1/2] fix daily apy --- .../blockchain/harvest/transaction_history.py | 23 +++++++++++++++++-- eagleproject/scripts/backfill_daily_stats.py | 5 ++++ 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 eagleproject/scripts/backfill_daily_stats.py diff --git a/eagleproject/core/blockchain/harvest/transaction_history.py b/eagleproject/core/blockchain/harvest/transaction_history.py index cead596..02bc2fe 100644 --- a/eagleproject/core/blockchain/harvest/transaction_history.py +++ b/eagleproject/core/blockchain/harvest/transaction_history.py @@ -31,7 +31,8 @@ explode_log_data ) from core.blockchain.harvest.snapshots import ( - build_asset_block + build_asset_block, + latest_snapshot_block_number ) from core.blockchain.rpc import ( creditsBalanceOf, @@ -744,6 +745,24 @@ def backfill_subscribers(): sub.save() +def get_block_time_from_block_number(number): + result = Block.objects.filter(block_number__gte=number).order_by('block_time')[:1] + + if len(result) != 1: + raise Exception('Can not find block time for block number', START_OF_PROJECT) + + return result[0].block_time + + +def backfill_daily_stats(project=OriginTokens.OUSD): + START_OF_PROJECT = START_OF_OUSD_V2 if project == OriginTokens.OUSD else START_OF_OETH + start_time = get_block_time_from_block_number(START_OF_PROJECT) + latest_time = get_block_time_from_block_number(latest_snapshot_block_number(project)) + days = (latest_time - start_time).days + _daily_rows(int(days), latest_snapshot_block_number(project), project=project) + return + + # get all accounts that at some point held OUSD def fetch_all_holders(project=OriginTokens.OUSD): to_addresses = list(map(lambda log: log['to_address'], TokenTransfer.objects.filter(project=project).values('to_address').distinct())) @@ -1640,7 +1659,7 @@ def _daily_rows(steps, latest_block_number, project, start_at=0): s.apr = ( - Decimal(100) * change * (Decimal(365) * BLOCKS_PER_DAY) / blocks + Decimal(100) * change * Decimal(365) ) s.apy = to_apy(s.apr, 1) diff --git a/eagleproject/scripts/backfill_daily_stats.py b/eagleproject/scripts/backfill_daily_stats.py new file mode 100644 index 0000000..8cb840c --- /dev/null +++ b/eagleproject/scripts/backfill_daily_stats.py @@ -0,0 +1,5 @@ +from core.blockchain.harvest.transaction_history import backfill_daily_stats + +def run(*script_args): + project = script_args[0] if len(script_args) > 0 else None + backfill_daily_stats(project) \ No newline at end of file From 08d84be8873ea6b52e1b606ba0dac50fa0329239 Mon Sep 17 00:00:00 2001 From: rolandpo Date: Tue, 10 Oct 2023 13:18:33 +0200 Subject: [PATCH 2/2] add warnings for inaccurate intervals --- .../blockchain/harvest/transaction_history.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/eagleproject/core/blockchain/harvest/transaction_history.py b/eagleproject/core/blockchain/harvest/transaction_history.py index 02bc2fe..522191f 100644 --- a/eagleproject/core/blockchain/harvest/transaction_history.py +++ b/eagleproject/core/blockchain/harvest/transaction_history.py @@ -102,6 +102,8 @@ from core.coingecko import get_coin_history from core.defillama import get_stablecoin_market_cap +from core.logging import get_logger + import simplejson as json from django.core.exceptions import ObjectDoesNotExist @@ -109,6 +111,8 @@ from eth_abi import decode_single from eth_utils import decode_hex +log = get_logger(__name__) + ACCOUNT_ANALYZE_PARALLELISM=30 class rebase_log: @@ -1621,7 +1625,6 @@ def _daily_rows(steps, latest_block_number, project, start_at=0): block.block_time - timedelta(seconds=24 * 60 * 60) ).replace(tzinfo=timezone.utc) if last_snapshot: - contract_address = OUSD_VAULT if project == OriginTokens.OUSD else OETH_VAULT rebase_logs = get_rebase_logs(last_snapshot.block_number, block_number, project) @@ -1657,7 +1660,15 @@ def _daily_rows(steps, latest_block_number, project, start_at=0): # other_change = 1 - (s.rebasing_credits_per_token / last_snapshot.rebasing_credits_per_token) change = Decimal(sum(event['amount'] for event in s.rebase_events)) / (s.computed_supply - s.non_rebasing_supply) - + if change: + interval = block.block_time - last_snapshot.block_time + if (interval.total_seconds() > 90000): + log.warning("{}: daily stats interval too long ({})".format(last_snapshot.block_time, interval)) + elif (interval.total_seconds() < 82800): + log.warning("{}: daily stats interval too short ({})".format(last_snapshot.block_time, interval)) + + # apr based on cumulative yield from yield events taken after block.block_time, and before next snapshot + # the number of blocks in this period doesn't matter, as calculation includes all yield events in 24h period s.apr = ( Decimal(100) * change * Decimal(365) )