Skip to content

Commit 2c2d413

Browse files
committed
feat: add integration tests for lazy oracle
1 parent fc01b1d commit 2c2d413

File tree

9 files changed

+128
-96
lines changed

9 files changed

+128
-96
lines changed

src/modules/accounting/accounting.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,13 @@ def _handle_vaults_report(self, blockstamp: ReferenceBlockStamp) -> VaultsReport
433433
block_identifier=blockstamp.block_hash,
434434
)
435435

436+
vaults_total_values = self.staking_vaults.get_vaults_total_values(
437+
vaults=vaults,
438+
validators=validators,
439+
pending_deposits=pending_deposits,
440+
validator_stages=validator_stages,
441+
)
442+
436443
core_apr_ratio = calculate_gross_core_apr(
437444
pre_total_ether=simulation.pre_total_pooled_ether,
438445
pre_total_shares=simulation.pre_total_shares,
@@ -442,13 +449,6 @@ def _handle_vaults_report(self, blockstamp: ReferenceBlockStamp) -> VaultsReport
442449
time_elapsed_seconds=self._get_time_elapsed_seconds_from_prev_report(blockstamp),
443450
)
444451

445-
vaults_total_values = self.staking_vaults.get_vaults_total_values(
446-
vaults=vaults,
447-
validators=validators,
448-
pending_deposits=pending_deposits,
449-
validator_stages=validator_stages,
450-
)
451-
452452
latest_onchain_ipfs_report_data = self.staking_vaults.get_latest_onchain_ipfs_report_data(blockstamp.block_hash)
453453
vaults_fees = self.staking_vaults.get_vaults_fees(
454454
blockstamp=blockstamp,

src/providers/execution/contracts/lazy_oracle.py

Lines changed: 42 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,11 @@
1313
from src.providers.execution.base_interface import ContractInterface
1414
from src.utils.abi import named_tuple_to_dataclass
1515
from src.utils.cache import global_lru_cache as lru_cache
16-
from src.utils.types import hex_str_to_bytes
1716

1817
logger = logging.getLogger(__name__)
1918

2019

21-
class VaultsLazyOracleContract(ContractInterface):
20+
class LazyOracleContract(ContractInterface):
2221
abi_path = './assets/LazyOracle.json'
2322

2423
@lru_cache(maxsize=1)
@@ -28,28 +27,24 @@ def get_vaults_count(self, block_identifier: BlockIdentifier = 'latest') -> int:
2827
"""
2928
response = self.functions.vaultsCount.call(block_identifier=block_identifier)
3029

31-
logger.info(
32-
{
33-
'msg': 'Call `vaultsCount().',
34-
'value': response,
35-
'block_identifier': repr(block_identifier),
36-
'to': self.address,
37-
}
38-
)
30+
logger.info({
31+
'msg': 'Call `vaultsCount().',
32+
'value': response,
33+
'block_identifier': repr(block_identifier),
34+
'to': self.address,
35+
})
3936

4037
return response
4138

4239
def get_latest_report_data(self, block_identifier: BlockIdentifier = 'latest') -> OnChainIpfsVaultReportData:
4340
response = self.functions.latestReportData.call(block_identifier=block_identifier)
4441

45-
logger.info(
46-
{
47-
'msg': 'Call `latestReportData()`.',
48-
'value': response,
49-
'block_identifier': repr(block_identifier),
50-
'to': self.address,
51-
}
52-
)
42+
logger.info({
43+
'msg': 'Call `latestReportData()`.',
44+
'value': response,
45+
'block_identifier': repr(block_identifier),
46+
'to': self.address,
47+
})
5348

5449
response = named_tuple_to_dataclass(response, OnChainIpfsVaultReportData)
5550
return response
@@ -62,33 +57,29 @@ def get_vaults(self, offset: int, limit: int, block_identifier: BlockIdentifier
6257

6358
out: list[VaultInfo] = []
6459
for vault in response:
65-
out.append(
66-
VaultInfo(
67-
vault=vault.vault,
68-
aggregated_balance=vault.aggregateBalance,
69-
in_out_delta=vault.inOutDelta,
70-
withdrawal_credentials=Web3.to_hex(vault.withdrawalCredentials),
71-
liability_shares=vault.liabilityShares,
72-
max_liability_shares=vault.maxLiabilityShares,
73-
mintable_st_eth=vault.mintableStETH,
74-
share_limit=vault.shareLimit,
75-
reserve_ratio_bp=vault.reserveRatioBP,
76-
forced_rebalance_threshold_bp=vault.forcedRebalanceThresholdBP,
77-
infra_fee_bp=vault.infraFeeBP,
78-
liquidity_fee_bp=vault.liquidityFeeBP,
79-
reservation_fee_bp=vault.reservationFeeBP,
80-
pending_disconnect=vault.pendingDisconnect,
81-
)
82-
)
83-
84-
logger.info(
85-
{
86-
'msg': f'Call `batchVaultsInfo({offset}, {limit}).',
87-
'value': response,
88-
'block_identifier': repr(block_identifier),
89-
'to': self.address,
90-
}
91-
)
60+
out.append(VaultInfo(
61+
vault=vault.vault,
62+
aggregated_balance=vault.aggregateBalance,
63+
in_out_delta=vault.inOutDelta,
64+
withdrawal_credentials=Web3.to_hex(vault.withdrawalCredentials),
65+
liability_shares=vault.liabilityShares,
66+
max_liability_shares=vault.maxLiabilityShares,
67+
mintable_st_eth=vault.mintableStETH,
68+
share_limit=vault.shareLimit,
69+
reserve_ratio_bp=vault.reserveRatioBP,
70+
forced_rebalance_threshold_bp=vault.forcedRebalanceThresholdBP,
71+
infra_fee_bp=vault.infraFeeBP,
72+
liquidity_fee_bp=vault.liquidityFeeBP,
73+
reservation_fee_bp=vault.reservationFeeBP,
74+
pending_disconnect=vault.pendingDisconnect,
75+
))
76+
77+
logger.info({
78+
'msg': f'Call `batchVaultsInfo({offset}, {limit}).',
79+
'value': response,
80+
'block_identifier': repr(block_identifier),
81+
'to': self.address,
82+
})
9283

9384
return out
9485

@@ -126,14 +117,12 @@ def get_validator_stages(
126117
batch = list(map(HexBytes, pubkeys[i : i + batch_size]))
127118
response = self.functions.batchValidatorStages(batch).call(block_identifier=block_identifier)
128119

129-
logger.debug(
130-
{
131-
'msg': 'Call `batchValidatorStages()`.',
132-
'count': len(batch),
133-
'block_identifier': repr(block_identifier),
134-
'to': self.address,
135-
}
136-
)
120+
logger.debug({
121+
'msg': 'Call `batchValidatorStages()`.',
122+
'count': len(batch),
123+
'block_identifier': repr(block_identifier),
124+
'to': self.address,
125+
})
137126

138127
# Assume response is a list of ints corresponding to ValidatorStage enum values
139128
for pubkey, stage in zip(batch, response):

src/services/staking_vaults.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def get_vaults_total_values(
125125
# For not-yet-eligible validators, use lazy oracle stages:
126126
# - PREDEPOSITED: add 1 ETH (guaranteed)
127127
# - ACTIVATED: add full balance + pending deposits
128-
# All other stages are skipped as not related to the non eligible for activation validators
128+
# All other stages are skipped as not related to the non-eligible for activation validators
129129
else:
130130
stage = validator_stages.get(pubkey)
131131
if stage == ValidatorStage.PREDEPOSITED:

src/web3py/extensions/contracts.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,23 @@
1212
from src.providers.execution.contracts.accounting_oracle import AccountingOracleContract
1313
from src.providers.execution.contracts.burner import BurnerContract
1414
from src.providers.execution.contracts.exit_bus_oracle import ExitBusOracleContract
15+
from src.providers.execution.contracts.lazy_oracle import LazyOracleContract
1516
from src.providers.execution.contracts.lido import LidoContract
1617
from src.providers.execution.contracts.lido_locator import LidoLocatorContract
17-
from src.providers.execution.contracts.oracle_daemon_config import OracleDaemonConfigContract
18-
from src.providers.execution.contracts.oracle_report_sanity_checker import OracleReportSanityCheckerContract
18+
from src.providers.execution.contracts.oracle_daemon_config import (
19+
OracleDaemonConfigContract,
20+
)
21+
from src.providers.execution.contracts.oracle_report_sanity_checker import (
22+
OracleReportSanityCheckerContract,
23+
)
1924
from src.providers.execution.contracts.staking_router import StakingRouterContract
20-
from src.providers.execution.contracts.lazy_oracle import VaultsLazyOracleContract
2125
from src.providers.execution.contracts.vault_hub import VaultHubContract
22-
23-
from src.providers.execution.contracts.withdrawal_queue_nft import WithdrawalQueueNftContract
24-
from src.types import BlockStamp, SlotNumber, WithdrawalVaultBalance, ELVaultBalance
26+
from src.providers.execution.contracts.withdrawal_queue_nft import (
27+
WithdrawalQueueNftContract,
28+
)
29+
from src.types import BlockStamp, ELVaultBalance, SlotNumber, WithdrawalVaultBalance
2530
from src.utils.cache import global_lru_cache as lru_cache
2631

27-
2832
logger = logging.getLogger(__name__)
2933

3034

@@ -41,7 +45,7 @@ class LidoContracts(Module):
4145
oracle_daemon_config: OracleDaemonConfigContract
4246
burner: BurnerContract
4347
accounting: AccountingContract
44-
lazy_oracle: VaultsLazyOracleContract
48+
lazy_oracle: LazyOracleContract
4549
vault_hub: VaultHubContract
4650

4751
def __init__(self, w3: Web3):

tests/integration/conftest.py

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,30 @@
88
from src.providers.execution.contracts.accounting_oracle import AccountingOracleContract
99
from src.providers.execution.contracts.burner import BurnerContract
1010
from src.providers.execution.contracts.cs_accounting import CSAccountingContract
11-
from src.providers.execution.contracts.cs_fee_distributor import CSFeeDistributorContract
11+
from src.providers.execution.contracts.cs_fee_distributor import (
12+
CSFeeDistributorContract,
13+
)
1214
from src.providers.execution.contracts.cs_fee_oracle import CSFeeOracleContract
1315
from src.providers.execution.contracts.cs_module import CSModuleContract
14-
from src.providers.execution.contracts.cs_parameters_registry import CSParametersRegistryContract
16+
from src.providers.execution.contracts.cs_parameters_registry import (
17+
CSParametersRegistryContract,
18+
)
1519
from src.providers.execution.contracts.cs_strikes import CSStrikesContract
1620
from src.providers.execution.contracts.exit_bus_oracle import ExitBusOracleContract
21+
from src.providers.execution.contracts.lazy_oracle import LazyOracleContract
1722
from src.providers.execution.contracts.lido import LidoContract
1823
from src.providers.execution.contracts.lido_locator import LidoLocatorContract
19-
from src.providers.execution.contracts.oracle_daemon_config import OracleDaemonConfigContract
20-
from src.providers.execution.contracts.oracle_report_sanity_checker import OracleReportSanityCheckerContract
24+
from src.providers.execution.contracts.oracle_daemon_config import (
25+
OracleDaemonConfigContract,
26+
)
27+
from src.providers.execution.contracts.oracle_report_sanity_checker import (
28+
OracleReportSanityCheckerContract,
29+
)
2130
from src.providers.execution.contracts.staking_router import StakingRouterContract
22-
from src.providers.execution.contracts.lazy_oracle import VaultsLazyOracleContract
23-
from src.providers.execution.contracts.withdrawal_queue_nft import WithdrawalQueueNftContract
31+
from src.providers.execution.contracts.vault_hub import VaultHubContract
32+
from src.providers.execution.contracts.withdrawal_queue_nft import (
33+
WithdrawalQueueNftContract,
34+
)
2435

2536

2637
@pytest.fixture
@@ -136,11 +147,20 @@ def burner_contract(web3_provider_integration, lido_locator_contract):
136147
def vault_hub_contract(web3_provider_integration, lido_locator_contract):
137148
return get_contract(
138149
web3_provider_integration,
139-
VaultsLazyOracleContract,
150+
VaultHubContract,
140151
lido_locator_contract.vault_hub(),
141152
)
142153

143154

155+
@pytest.fixture
156+
def lazy_oracle_contract(web3_provider_integration, lido_locator_contract):
157+
return get_contract(
158+
web3_provider_integration,
159+
LazyOracleContract,
160+
lido_locator_contract.lazy_oracle(),
161+
)
162+
163+
144164
# ╔══════════════════════════════════════════════════════════════════════════════════════════════════╗
145165
# ║ CSM contracts ║
146166
# ╚══════════════════════════════════════════════════════════════════════════════════════════════════╝

tests/integration/contracts/test_accounting.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import pytest
22
from web3.types import Wei
33

4-
from src.modules.accounting.types import ReportSimulationPayload, ReportSimulationResults
4+
from src.modules.accounting.types import (
5+
ReportSimulationPayload,
6+
ReportSimulationResults,
7+
)
58
from tests.integration.contracts.contract_utils import check_contract, check_value_type
69

710

811
@pytest.mark.testnet # TODO: Bounded to hoodie due to st. vaults task, move to mainnet after release
912
@pytest.mark.integration
10-
@pytest.mark.skip
13+
@pytest.mark.skip("Some real numbers required for simulation to pass")
1114
def test_accounting_contract_call(accounting_contract, caplog):
1215
check_contract(
1316
accounting_contract,
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import pytest
2+
from hexbytes import HexBytes
3+
4+
from src.modules.accounting.types import OnChainIpfsVaultReportData
5+
from tests.integration.contracts.contract_utils import check_contract, check_value_type
6+
7+
8+
@pytest.mark.mainnet
9+
@pytest.mark.integration
10+
@pytest.mark.skip("LazyOracle contract is not latest on Hoodi.")
11+
def test_lazy_oracle_contract_call(lazy_oracle_contract, caplog):
12+
check_contract(
13+
lazy_oracle_contract,
14+
[
15+
('get_vaults_count', None, lambda response: check_value_type(response, int)),
16+
('get_latest_report_data', None, lambda response: check_value_type(response, OnChainIpfsVaultReportData)),
17+
('get_vaults', (0, 10), lambda response: check_value_type(response, list)),
18+
(
19+
'get_validator_stages',
20+
(
21+
[
22+
"0x862d53d9e4313374d202f2b28e6ffe64efb0312f9c2663f2eef67b72345faa8932b27f9b9bb7b476d9b5e418fea99124",
23+
"0xa5d9411ef615c74c9240634905d5ddd46dc40a87a09e8cc0332afddb246d291303e452a850917eefe09b3b8c70a307ce",
24+
],
25+
5,
26+
),
27+
lambda response: check_value_type(response, dict),
28+
),
29+
],
30+
caplog,
31+
)

tests/integration/contracts/test_vault_hub.py

Lines changed: 0 additions & 15 deletions
This file was deleted.

tests/providers/test_staking_vaults.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
@pytest.mark.integration
77
class TestStakingVaultsContractsSmoke:
88

9-
@pytest.mark.skip
9+
@pytest.mark.skip("No events in the range, need to update the test")
1010
def test_get_burned_events(self, web3_integration):
1111
events = web3_integration.lido_contracts.vault_hub.get_burned_events(
1212
BlockNumber(1272666 - 1_000), BlockNumber(1272666)
1313
)
1414
assert len(events) != 0
1515

16-
@pytest.mark.skip
16+
@pytest.mark.skip("No events in the range, need to update the test")
1717
def test_get_minted_events(self, web3_integration):
1818
events = web3_integration.lido_contracts.vault_hub.get_minted_events(
1919
BlockNumber(1272666 - 1_000), BlockNumber(1272666)
@@ -26,7 +26,7 @@ def test_get_updated_events(self, web3_integration):
2626
)
2727
assert len(events) == 0
2828

29-
@pytest.mark.skip
29+
@pytest.mark.skip("Distribution disabled on devnet")
3030
def test_staking_fee_aggregate_distribution(self, web3_integration):
3131
out = web3_integration.lido_contracts.staking_router.get_staking_fee_aggregate_distribution()
3232
assert 0 != out.lido_fee_bp()

0 commit comments

Comments
 (0)