Skip to content
Merged
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
4 changes: 2 additions & 2 deletions .github/workflows/query.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: "18"
node-version: "20"
cache: "yarn"
- name: Install
run: |
Expand Down Expand Up @@ -91,7 +91,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: "18"
node-version: "20"
cache: "yarn"
# Looks for an existing comment, so it can be updated
- name: Find Existing Comment
Expand Down
5 changes: 5 additions & 0 deletions subgraphs/ethereum/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Subgraph Changelog

## 5.6.4 (2025-04-16)

- Adds support for Guardian Olympus sUSDS Vault
- Exclude balances from the Convex Allocator going forward (bricked)

## 5.5.4 (2025-02-18)

- Adds support for indexing native ETH
Expand Down
4 changes: 2 additions & 2 deletions subgraphs/ethereum/config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "QmebupLuGiu5wcS7P9BYpKCFsAFEjFR3dybb3xELqttSv5",
"id": "QmdeAd2f79EHqki57gBcd8jbNK2xGyaYCHSV4YK4vouPCe",
"org": "olympusdao",
"name": "olympus-protocol-metrics",
"version": "5.5.4"
"version": "5.6.4"
}
4 changes: 4 additions & 0 deletions subgraphs/ethereum/src/utils/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ ERC20_TOKENS.set(NATIVE_ETH, new TokenDefinition(NATIVE_ETH, TokenCategoryVolati

export const ERC4626_SDAI = "0x83F20F44975D03b1b09e64809B757c47f942BEeA".toLowerCase();
export const ERC4626_SUSDS = "0xa3931d71877C0E7a3148CB7Eb4463524FEc27fbD".toLowerCase();
export const ERC4626_GAUNTLET_SUSDS_VAULT = "0x3365184e87d2Bd75961780454A5810BEc956F0dD".toLowerCase();

/**
* Mapping between the contract address of an ERC4626 token and the TokenDefinition.
Expand All @@ -325,6 +326,7 @@ export const ERC4626_SUSDS = "0xa3931d71877C0E7a3148CB7Eb4463524FEc27fbD".toLowe
export const ERC4626_TOKENS = new Map<string, TokenDefinition>();
ERC4626_TOKENS.set(ERC4626_SDAI, new TokenDefinition(ERC4626_SDAI, TokenCategoryStable, true, false));
ERC4626_TOKENS.set(ERC4626_SUSDS, new TokenDefinition(ERC4626_SUSDS, TokenCategoryStable, true, false));
ERC4626_TOKENS.set(ERC4626_GAUNTLET_SUSDS_VAULT, new TokenDefinition(ERC4626_GAUNTLET_SUSDS_VAULT, TokenCategoryStable, true, false));

/**
* Mapping between the non-staked token and the token staked in Convex.
Expand Down Expand Up @@ -571,6 +573,7 @@ LIQUIDITY_POOL_TOKEN_LOOKUP.set(ERC4626_SDAI, [new PairHandler(PairHandlerTypes.
LIQUIDITY_POOL_TOKEN_LOOKUP.set(ERC20_SUSHI, [new PairHandler(PairHandlerTypes.UniswapV2, PAIR_UNISWAP_V2_SUSHI_ETH)]);
LIQUIDITY_POOL_TOKEN_LOOKUP.set(ERC20_STETH, [new PairHandler(PairHandlerTypes.Curve, PAIR_CURVE_ETH_STETH)]);
LIQUIDITY_POOL_TOKEN_LOOKUP.set(ERC4626_SUSDS, [new PairHandler(PairHandlerTypes.ERC4626, ERC4626_SUSDS)]);
LIQUIDITY_POOL_TOKEN_LOOKUP.set(ERC4626_GAUNTLET_SUSDS_VAULT, [new PairHandler(PairHandlerTypes.ERC4626, ERC4626_GAUNTLET_SUSDS_VAULT)]);
LIQUIDITY_POOL_TOKEN_LOOKUP.set(ERC20_SYN, [new PairHandler(PairHandlerTypes.UniswapV2, PAIR_UNISWAP_V2_SYN_FRAX)]);
LIQUIDITY_POOL_TOKEN_LOOKUP.set(ERC20_THOR, [new PairHandler(PairHandlerTypes.UniswapV2, PAIR_UNISWAP_V2_THOR_ETH)]);
LIQUIDITY_POOL_TOKEN_LOOKUP.set(ERC20_TOKE, [new PairHandler(PairHandlerTypes.UniswapV2, PAIR_UNISWAP_V2_TOKE_ETH)]);
Expand Down Expand Up @@ -1048,6 +1051,7 @@ CONTRACT_NAME_MAP.set(ERC20_WSTETH, "wstETH");
CONTRACT_NAME_MAP.set(ERC20_XSUSHI, "SUSHI - Staked");
CONTRACT_NAME_MAP.set(ERC4626_SDAI, "Savings DAI");
CONTRACT_NAME_MAP.set(ERC4626_SUSDS, "Savings USDS");
CONTRACT_NAME_MAP.set(ERC4626_GAUNTLET_SUSDS_VAULT, "Gauntlet sUSDS Vault");
CONTRACT_NAME_MAP.set(ETHBOND_CONTRACT1, "ETH Bond 1");
CONTRACT_NAME_MAP.set(EULER_ADDRESS, "Euler Finance");
CONTRACT_NAME_MAP.set(EULER_ADDRESS, "Euler Protocol");
Expand Down
4 changes: 2 additions & 2 deletions subgraphs/ethereum/src/utils/ContractHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ import {
TOKE_STAKING,
} from "./Constants";
import { getUSDRate } from "./Price";
import { CONVEX_ALLOCATORS, getWalletAddressesForContract } from "./ProtocolAddresses";
import { getConvexAllocators, getWalletAddressesForContract } from "./ProtocolAddresses";

/**
* The Graph recommends only binding a contract once
Expand Down Expand Up @@ -1767,7 +1767,7 @@ export function getConvexStakedRecords(
const records: TokenRecord[] = [];

// Loop through allocators
const convexAllocators = CONVEX_ALLOCATORS;
const convexAllocators = getConvexAllocators(blockNumber);
for (let i = 0; i < convexAllocators.length; i++) {
const allocatorAddress = convexAllocators[i];

Expand Down
2 changes: 2 additions & 0 deletions subgraphs/ethereum/src/utils/Price.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ function getPairHandlerNonOhmValue(
const result = getUniswapV3PairTotalValue(pairHandler.getContract(), true, blockNumber);
const totalValue = result.totalValue;
const ohmBalance = result.ohmBalance;
log.debug("getPairHandlerNonOhmValue: totalValue {}, ohmBalance {}", [totalValue.toString(), ohmBalance.toString()]);

if (totalValue.equals(BigDecimal.zero())) {
return null;
}
Expand Down
39 changes: 39 additions & 0 deletions subgraphs/ethereum/src/utils/ProtocolAddresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,26 @@ export const CONVEX_ALLOCATORS = [
DAO_WALLET,
];

export const getConvexAllocators = (blockNumber: BigInt): string[] => {
// If before the exclusion block, return all allocators
if (blockNumber.lt(BigInt.fromString(CONVEX_ALLOCATOR_DEATH))) {
return CONVEX_ALLOCATORS;
}

// Otherwise remove the bricked allocator
const allocators = CONVEX_ALLOCATORS.slice(0);
for (let i = 0; i < allocators.length; i++) {
if (allocators[i].toLowerCase() == CONVEX_CVX_ALLOCATOR.toLowerCase()) {
log.debug("getConvexAllocators: removing bricked allocator: {}", [CONVEX_CVX_ALLOCATOR]);
allocators.splice(i, 1);
break;
}
}

// Return the allocators
return allocators;
}

/**
* This set of wallet addresses is common across many tokens,
* and can be used for balance lookups.
Expand Down Expand Up @@ -117,6 +137,8 @@ TREASURY_BLACKLIST.set(ERC20_SOHM_V1, PROTOCOL_ADDRESSES);
TREASURY_BLACKLIST.set(ERC20_SOHM_V2, PROTOCOL_ADDRESSES);
TREASURY_BLACKLIST.set(ERC20_SOHM_V3, PROTOCOL_ADDRESSES);

const CONVEX_ALLOCATOR_DEATH = "22278800";

/**
* Some wallets (e.g. {DAO_WALLET}) have specific treasury assets mixed into them.
* For this reason, the wallets to be used differ on a per-contract basis.
Expand Down Expand Up @@ -148,6 +170,23 @@ export const getWalletAddressesForContract = (contractAddress: string, blockNumb
walletAddresses.push(clearinghouseAddresses[i].toHexString().toLowerCase());
}

// If after the exclusion block, remove the convex allocator
// Reason: funds in it are bricked
if (blockNumber.ge(BigInt.fromString(CONVEX_ALLOCATOR_DEATH))) {
for (let i = 0; i < walletAddresses.length; i++) {
// Check address
if (walletAddresses[i].toLowerCase() != CONVEX_CVX_ALLOCATOR.toLowerCase()) continue;

// Check exclusion block
if (blockNumber.lt(BigInt.fromString(CONVEX_ALLOCATOR_DEATH))) continue;

// Remove the address in-place
walletAddresses.splice(i, 1);
log.debug("getWalletAddressesForContract: removed convex allocator: {}", [CONVEX_CVX_ALLOCATOR]);
break;
}
}

// If the contract isn't on the blacklist, return as normal
if (!TREASURY_BLACKLIST.has(contractAddress.toLowerCase())) {
log.debug("getWalletAddressesForContract: token {} is not on treasury blacklist", [contractAddress]);
Expand Down
4 changes: 2 additions & 2 deletions subgraphs/ethereum/subgraph.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ repository: https://github.com/OlympusDAO/olympus-protocol-metrics-subgraph
features:
- grafting
graft:
base: QmdGqRrQD4FehyTYTmoK9RvveuR3e4vPDsyuqAYF4Nrmfv # 5.4.10
block: 21810000 # Inclusion of native ETH
base: QmebupLuGiu5wcS7P9BYpKCFsAFEjFR3dybb3xELqttSv5 # 5.5.4
block: 22270000 # Exclusion of Convex Allocator
schema:
file: ../../schema.graphql
dataSources:
Expand Down
7 changes: 6 additions & 1 deletion subgraphs/ethereum/tests/erc4626.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { assert, beforeEach, clearStore, createMockedFunction, describe, log,tes

import { toBigInt, toDecimal } from "../../shared/src/utils/Decimals";
import { TREASURY_ADDRESS_V3 } from "../../shared/src/Wallets";
import { ERC20_USDS, ERC4626_SUSDS } from "../src/utils/Constants";
import { ERC20_USDS, ERC4626_GAUNTLET_SUSDS_VAULT, ERC4626_SUSDS } from "../src/utils/Constants";
import { getAllERC4626Balances } from "../src/utils/ERC4626";
import { getWalletAddressesForContract } from "../src/utils/ProtocolAddresses";
import { mockClearinghouseRegistryAddressNull, mockTreasuryAddressNull } from "./bophadesHelper";
Expand Down Expand Up @@ -51,6 +51,7 @@ const mockERC4626Token = (
const mockERC4626Tokens = (): void => {
mockERC4626Token(SDAI, DAI, SDAI_ASSETS_TO_SHARES, 18);
mockERC4626Token(ERC4626_SUSDS, ERC20_USDS, SUSDS_ASSETS_TO_SHARES, 18);
mockERC4626Token(ERC4626_GAUNTLET_SUSDS_VAULT, ERC20_USDS, SUSDS_ASSETS_TO_SHARES, 18);
};

const mockPriceFeeds = (): void => {
Expand All @@ -74,6 +75,9 @@ describe("ERC4626", () => {
mockZeroWalletBalances(
ERC4626_SUSDS,
getWalletAddressesForContract(ERC4626_SUSDS, BLOCK_NUMBER));
mockZeroWalletBalances(
ERC4626_GAUNTLET_SUSDS_VAULT,
getWalletAddressesForContract(ERC4626_GAUNTLET_SUSDS_VAULT, BLOCK_NUMBER));
});

test("handles contract revert", () => {
Expand All @@ -83,6 +87,7 @@ describe("ERC4626", () => {
// ERC4626 contract reverts
mockERC4626Reverts(SDAI);
mockERC4626Reverts(ERC4626_SUSDS);
mockERC4626Reverts(ERC4626_GAUNTLET_SUSDS_VAULT);

// Mock balance
mockWalletBalance(SDAI, TREASURY_ADDRESS_V3, toBigInt(BigDecimal.fromString("100"), 18));
Expand Down
3 changes: 3 additions & 0 deletions subgraphs/ethereum/tests/pairHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import {
ERC20_USDC,
ERC20_WETH,
ERC20_WSTETH,
ERC4626_SUSDS,
FRAX_LOCKING_CONTRACTS,
getContractName,
LQTY_STAKING,
Expand All @@ -82,6 +83,7 @@ import {
PAIR_UNISWAP_V3_LQTY_LUSD,
PAIR_UNISWAP_V3_LQTY_WETH,
PAIR_UNISWAP_V3_LUSD_USDC,
PAIR_UNISWAP_V3_OHM_SUSDS,
PAIR_UNISWAP_V3_WETH_BTRFLY_V1,
PAIR_UNISWAP_V3_WETH_BTRFLY_V2,
PAIR_UNISWAP_V3_WETH_OHM,
Expand Down Expand Up @@ -336,6 +338,7 @@ export const mockUniswapV3PairsZero = (): void => {
mockRateUniswapV3(PAIR_UNISWAP_V3_WETH_BTRFLY_V1, BigInt.zero(), ERC20_WETH, ERC20_BTRFLY_V1, ERC20_STANDARD_DECIMALS, ERC20_STANDARD_DECIMALS, BigInt.zero(), BigInt.zero(), true);
mockRateUniswapV3(PAIR_UNISWAP_V3_WETH_BTRFLY_V2, BigInt.zero(), ERC20_WETH, ERC20_BTRFLY_V2, ERC20_STANDARD_DECIMALS, ERC20_STANDARD_DECIMALS, BigInt.zero(), BigInt.zero(), true);
mockRateUniswapV3(PAIR_UNISWAP_V3_WETH_OHM, BigInt.zero(), ERC20_WETH, ERC20_OHM_V2, ERC20_STANDARD_DECIMALS, OHM_V2_DECIMALS, BigInt.zero(), BigInt.zero(), true);
mockRateUniswapV3(PAIR_UNISWAP_V3_OHM_SUSDS, BigInt.zero(), ERC20_OHM_V2, ERC4626_SUSDS, OHM_V2_DECIMALS, ERC20_STANDARD_DECIMALS, BigInt.zero(), BigInt.zero(), true);
}

export const mockFxsEthRate = (): void => {
Expand Down
1 change: 1 addition & 0 deletions subgraphs/ethereum/tests/price.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ describe("OHM-USD rate", () => {
mockERC20Balance(ERC20_WETH, PAIR_UNISWAP_V3_WETH_OHM, toBigInt(ethBalance, ERC20_STANDARD_DECIMALS));

// 919.574080927401380445 * 1898.01397374 / 130454.081369749 = 13.3791479512
// TODO figure out why this is not being returned
const calculatedRate = BigDecimal.fromString("13.3835");

assert.stringEquals(
Expand Down
Loading