ERC-4626: current APY of a vault
Here is a Python example how to estimate the ERC-4626 APY.
Reads the most recent APY of given ERC-4626 vault
The APY is calculated using the price difference of the vault share token
Only uses EVM JSON-RPC and archive node, no external services needed. Public RPC nodes won’t work, because they are not archive nodes. Get your Base node JSON-RPC access from dRPC or Ethereumnodes.com.
Supported vaults include all ERC-4626, including but not limited to: Morpho, Euler, Lagoon Finance, Superform, IPOR, Yearn, Fluid
Then to run this script:
# Get JSON-RPC archive node
export JSON_RPC_BASE=...
python scripts/erc-4626/read-live-apy.py
Output looks like:
Vault: IPOR USDC Lending Optimizer Base (0x45aa96f0b3188d47a1dafdbefce1db6b37f58216)
Estimated APY: 5.53%
Period: 2025-05-19 11:08:31 - 2025-05-26 11:08:31
Block range: 30,431,782 - 30,734,182
Share price at begin: 1.042212618930521299088288235 ipUSDCfusion / USDC
Share price at end: 1.043318675169052799414866657 ipUSDCfusion / USDC
Share price diff: 0.001106056238531500326578422 ipUSDCfusion / USDC
Further reading
See ERC-4626 API API documentation.
"""An example script to estimate the live APY of an ERC-4626 vault.
- Archive JSON-RPC node needed, public endpoint may not work.
To run:
.. code-block:: shell
python scripts/erc-4626/read-live-apy.py
"""
import os
import datetime
from eth_defi.chain import get_chain_name
from eth_defi.erc_4626.classification import create_vault_instance
from eth_defi.erc_4626.profit_and_loss import estimate_4626_recent_profitability
from eth_defi.provider.multi_provider import create_multi_provider_web3
def main():
JSON_RPC_BASE = os.environ.get("JSON_RPC_BASE")
assert JSON_RPC_BASE, "Please set JSON_RPC_BASE environment variable to your JSON-RPC endpoint."
web3 = create_multi_provider_web3(JSON_RPC_BASE)
chain_id = web3.eth.chain_id
assert chain_id == 8453, "This script is designed to run on Base chain (chain ID 8453)."
# IPOR USDC Base
# Lending Optimizer
# https://app.ipor.io/fusion/base/0x45aa96f0b3188d47a1dafdbefce1db6b37f58216
vault_address = "0x45aa96f0b3188d47a1dafdbefce1db6b37f58216"
vault = create_vault_instance(web3, vault_address)
profitability_data = estimate_4626_recent_profitability(vault, lookback_window=datetime.timedelta(days=7))
estimated_apy = profitability_data.calculate_profitability(annualise=True)
start_block, end_block = profitability_data.get_block_range()
start_at, end_at = profitability_data.get_time_range()
start_price, end_price = profitability_data.get_share_price_range()
diff = end_price - start_price
print(f"Vault: {vault.name} ({vault_address})")
print(f"Chain: {get_chain_name(chain_id)}")
print(f"Estimated APY: {estimated_apy:.2%}")
print(f"Period: {start_at} - {end_at} ({(end_at - start_at).days} days)")
print(f"Block range: {start_block:,} - {end_block:,}")
print(f"Share price at begin: {start_price} {vault.share_token.symbol} / {vault.denomination_token.symbol}")
print(f"Share price at end: {end_price} {vault.share_token.symbol} / {vault.denomination_token.symbol}")
print(f"Share price diff: {diff} {vault.share_token.symbol} / {vault.denomination_token.symbol}")
if __name__ == "__main__":
main()