Subgraphs
Subgraphs index on-chain data from Euler V2 smart contracts and expose it through GraphQL. Euler's production subgraphs use a deliberately lightweight schema (euler-simple) designed to answer one question efficiently: which accounts have deposits or borrows in which vaults. This is the same source the Euler apps and the Euler SDK use for account position discovery.
The simple schema does not expose vault configuration, interest rates, APYs, prices, or health scores. For that data, take the vault and account addresses returned by the subgraph and query lens contracts or the Euler V3 API.
Source Code
The source code for the Euler simple subgraphs is open source and includes the GraphQL schema, entity definitions, and event handlers:
- Euler Subgraphs GitHub Repository (
simple-subgraphbranch)
Available Networks and Endpoints
Each production network has its own subgraph instance hosted by Goldsky — the same networks listed on the Contract Addresses page:
Schema
The simple subgraph indexes vaults deployed by the EVK vault factory, the EulerEarn factory, and the Securitize collateral vault factory, and tracks account activity from vault Transfer, Borrow, and Repay events. It exposes three entities:
| Entity | Keyed by | Purpose |
|---|---|---|
Vault | vault address | All indexed vaults and the factory that deployed them |
TrackingActiveAccount | address prefix (first 19 bytes) | Lists of active deposit and borrow positions for all sub-accounts sharing a prefix |
TrackingVaultBalance | account + vault (concatenated) | Internal data structure used to maintain the active position lists — do not rely on it |
The subgraph tells you where positions are, not their current size. TrackingVaultBalance holds raw values captured at the time of the last event and is immediately outdated — debt in particular accrues interest every second, but the subgraph only re-captures it when a new event touches the position. Read current balances, debt, and health through lens contracts or the Euler V3 API instead.
Address Prefixes
The key difference from the previous subgraphs: account activity is grouped by address prefix, not by account address. On Euler, every owner address controls 256 virtual sub-accounts via the EVC. All of them share the first 19 bytes of the address and differ only in the last byte. The subgraph keys TrackingActiveAccount by this shared prefix, so a single query returns positions across all of a user's sub-accounts.
To compute the prefix, lowercase the address and drop the last byte (the last two hex characters):
// 0x + 38 hex characters = first 19 bytes
const getAddressPrefix = (address) => address.toLowerCase().slice(0, 40);
getAddressPrefix("0x2B5A103a91B78E1352fDe6d3b7526bd932d1a2C4");
// => "0x2b5a103a91b78e1352fde6d3b7526bd932d1a2"How to Get Active Positions of an Account
This is the primary use case for the simple subgraph, and the exact flow used by the Euler apps and the Euler SDK.
Step 1: Query the Subgraph by Address Prefix
Use the trackingActiveAccount query with the address prefix as the id:
query AccountPositions($prefix: ID!) {
trackingActiveAccount(id: $prefix) {
deposits
borrows
}
}deposits and borrows are lists of active positions, each entry a concatenation of the sub-account address (20 bytes) and the vault address (20 bytes), e.g. 0x000000000000000000000000000000000000deade1ce9af672f8854845e5474400b6ddc7ae458a10.
To parse the entries in JavaScript:
import { getAddress } from "viem";
function parseEntry(entry) {
return {
subAccount: getAddress(entry.substring(0, 42)),
vault: getAddress(`0x${entry.substring(42)}`),
};
}subAccountis the sub-account holding the positionvaultis the vault the position is in
To look up several users in one request, batch the prefixes with trackingActiveAccounts:
query AccountVaults($ids: [String!]!) {
trackingActiveAccounts(where: { id_in: $ids }) {
id
deposits
borrows
}
}Step 2: Fetch Detailed Data Using Lens Contracts
Once you have the list of sub-accounts and vaults, use the lens contracts for detailed information:
- Use
AccountLensfor account-level data (balances, health, rewards, etc.) - Use
VaultLensfor vault-specific details (configuration, caps, rates, etc.)
Step 3: Filter for Known Vaults
Use the known-vault endpoints to check whether a vault is known and to fetch its metadata (name, curator, deprecation status). This helps filter out unknown or experimental vaults — note that a vault being known is not a safety guarantee; only its initial configuration was reviewed.
Other Queries
List Indexed Vaults
query Vaults {
vaults(first: 1000, orderBy: id, orderDirection: asc) {
id
factory
}
}Check Indexing Status
Use _meta to check how far the subgraph has indexed — useful for waiting until a recent transaction is reflected in query results:
{
_meta {
block {
number
}
}
}