Skip to content
Draft
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ CLAUDE.md
.env

**/*.toml
!py_project.toml
!pyproject.toml
55 changes: 55 additions & 0 deletions src/tq_oracle/abi.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

ABIS_DIR = Path(__file__).parent / "abis"

CORE_VAULTS_COLLECTOR_PATH = ABIS_DIR / "CoreVaultsCollector.json"
MULTICALL_ABI_PATH = ABIS_DIR / "Multicall.json"
ORACLE_ABI_PATH = ABIS_DIR / "IOracle.json"
ORACLE_HELPER_ABI_PATH = ABIS_DIR / "OracleHelper.json"
VAULT_ABI_PATH = ABIS_DIR / "Vault.json"
Expand All @@ -20,6 +22,7 @@
FEE_MANAGER_ABI_PATH = ABIS_DIR / "FeeManager.json"
STAKEWISE_VAULT_ABI_PATH = ABIS_DIR / "StakeWiseVault.json"
STAKEWISE_OS_TOKEN_VAULT_ESCROW_ABI_PATH = ABIS_DIR / "StakeWiseOsTokenVaultEscrow.json"
OSTOKEN_VAULT_CONTROLLER_ABI_PATH = ABIS_DIR / "OsTokenVaultController.json"


def load_abi(path: str | Path) -> list[dict]:
Expand All @@ -42,6 +45,15 @@ def load_abi(path: str | Path) -> list[dict]:
return data["abi"]


def load_core_vaults_collector_abi() -> list[dict]:
return load_abi(CORE_VAULTS_COLLECTOR_PATH)


def load_multicall_abi() -> list[dict]:
"""Load the Multicall ABI."""
return load_abi(MULTICALL_ABI_PATH)


def load_oracle_abi() -> list[dict]:
"""Load the Oracle ABI."""
return load_abi(ORACLE_ABI_PATH)
Expand Down Expand Up @@ -87,6 +99,11 @@ def load_stakewise_os_token_vault_escrow_abi() -> list[dict]:
return load_abi(STAKEWISE_OS_TOKEN_VAULT_ESCROW_ABI_PATH)


def load_ostoken_vault_controller_abi() -> list[dict]:
"""Load the OsToken Vault Controller ABI."""
return load_abi(OSTOKEN_VAULT_CONTROLLER_ABI_PATH)


def get_oracle_address_from_vault(settings: OracleSettings) -> ChecksumAddress:
"""Fetch the oracle address from the vault contract.

Expand Down Expand Up @@ -119,3 +136,41 @@ def get_oracle_address_from_vault(settings: OracleSettings) -> ChecksumAddress:
return oracle_addr
except Exception as e:
raise ValueError(f"Failed to fetch oracle address from vault: {e}") from e


def fetch_subvault_addresses(settings: OracleSettings) -> list[str]:
"""Fetch all subvault addresses from the vault contract.

Args:
settings: Oracle settings containing vault_address, vault_rpc, and block_number

Returns:
List of subvault addresses

Raises:
ConnectionError: If RPC connection fails
ValueError: If contract call fails
"""
rpc_url = settings.vault_rpc_required
vault_address = settings.vault_address_required
block_number = settings.block_number_required

w3 = Web3(Web3.HTTPProvider(URI(rpc_url)))
if not w3.is_connected():
raise ConnectionError(f"Failed to connect to RPC: {rpc_url}")

vault_abi = load_vault_abi()
checksum_vault = w3.to_checksum_address(vault_address)
vault_contract = w3.eth.contract(address=checksum_vault, abi=vault_abi)

try:
count: int = vault_contract.functions.subvaults().call(
block_identifier=block_number
)
subvaults: list[str] = [
vault_contract.functions.subvaultAt(i).call(block_identifier=block_number)
for i in range(count)
]
return subvaults
except Exception as e:
raise ValueError(f"Failed to fetch subvault addresses from vault: {e}") from e
84 changes: 84 additions & 0 deletions src/tq_oracle/abis/CoreVaultsCollector.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
{
"abi": [
{
"inputs": [
{
"internalType": "address",
"name": "queue",
"type": "address"
},
{
"internalType": "address",
"name": "holder",
"type": "address"
}
],
"name": "analyzeRequests",
"outputs": [
{
"internalType": "uint256",
"name": "assets",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "shares",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "holder",
"type": "address"
},
{
"internalType": "bytes",
"name": "deployment",
"type": "bytes"
},
{
"internalType": "address[]",
"name": "",
"type": "address[]"
}
],
"name": "getDistributions",
"outputs": [
{
"components": [
{
"internalType": "address",
"name": "asset",
"type": "address"
},
{
"internalType": "int256",
"name": "balance",
"type": "int256"
},
{
"internalType": "string",
"name": "metadata",
"type": "string"
},
{
"internalType": "address",
"name": "holder",
"type": "address"
}
],
"internalType": "struct IDistributionCollector.Balance[]",
"name": "balances",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
}
]
}
Loading