Skip to content

Commit

Permalink
Nuri + nile + camelot + yay integration
Browse files Browse the repository at this point in the history
  • Loading branch information
batphonghan committed Nov 5, 2024
1 parent fa45345 commit b1ca2b6
Show file tree
Hide file tree
Showing 12 changed files with 8,028 additions and 5,425 deletions.
5 changes: 3 additions & 2 deletions adapters/kelp_gain_linea/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import {
import { rsETH } from "./lib/utils";
import BigNumber from "bignumber.js";
import { ethers } from "ethers";
import { getAllAgEthHodlers, UserBalanceSubgraphEntry } from "./lib/query";
import { getAllAgEthHodlers } from "./lib/query";
import { UserBalanceSubgraphEntry } from "./lib/models";
interface BlockData {
blockTimestamp: number;
blockNumber: number;
Expand Down Expand Up @@ -72,7 +73,7 @@ export const getUserTVLByBlock = async (blocks: BlockData) => {
getRsEthTVLInUSD(blockNumber),
agEthToRsEth(ethBlockNumber),
agETHTotalLiquid(ethBlockNumber),
getAllAgEthHodlers(ethBlockNumber, blockTimestamp)
getAllAgEthHodlers(ethBlockNumber, blockNumber, blockTimestamp)
]
);

Expand Down
28 changes: 28 additions & 0 deletions adapters/kelp_gain_linea/src/lib/camelot.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import BigNumber from "bignumber.js";
import {
getAllV3Positions,
getAllV3Share,
getPoolPosition,
getToken0And1
} from "./v3query";
import { CAMELOT_START_TIMESTAMP, NURI_START_TIMESTAMP } from "./utils";
import { getArbBlock } from "./fetcher";

const CAMELOT_SUBGRAPH_BY_GATEWAY =
"https://api.thegraph.com/subgraphs/id/QmUjsQpF3mewR2nNyWkpCeKqosaNbRefeqiJJtdEoHQpC7";
const CAMELOT_AGETH_RSETH_POOL = "0x8039cd846fd1f1fe3f560bdbea5f799e499f7873";

export async function getCamelotAgEthHodlers(timestamp: number) {
if (timestamp < CAMELOT_START_TIMESTAMP) {
return [];
}

const arbBlockNumber = await getArbBlock(timestamp);
const balances = await getAllV3Share(
arbBlockNumber,
CAMELOT_SUBGRAPH_BY_GATEWAY,
CAMELOT_AGETH_RSETH_POOL
);

return balances;
}
46 changes: 45 additions & 1 deletion adapters/kelp_gain_linea/src/lib/fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import {
dater,
agETHContract,
wrsETHContract,
agETH
agETH,
scrollDater,
arbDater
} from "./utils";

export async function getEtherumBlock(
Expand All @@ -22,6 +24,26 @@ export async function getEtherumBlock(
});
}

export async function getArbBlock(blockTimestampSecs: number): Promise<number> {
return retry({
fn: async () => {
return await _getArbBlock(blockTimestampSecs);
},
name: `_getARBBlock`
});
}

export async function getScrollBlock(
blockTimestampSecs: number
): Promise<number> {
return retry({
fn: async () => {
return await _getScrollBlock(blockTimestampSecs);
},
name: `_getScrollBlock`
});
}

export async function _getEtherumBlock(blockTimestampSecs: number) {
const blockTimestampInMill = blockTimestampSecs * 1000;
const date = new Date(blockTimestampInMill); //
Expand All @@ -33,6 +55,28 @@ export async function _getEtherumBlock(blockTimestampSecs: number) {
return blockNumber;
}

export async function _getScrollBlock(blockTimestampSecs: number) {
const blockTimestampInMill = blockTimestampSecs * 1000;
const date = new Date(blockTimestampInMill); //
// External API

const res = await scrollDater.getDate(date);
let blockNumber = res.block; // Try to get the exact block number

return blockNumber;
}

export async function _getArbBlock(blockTimestampSecs: number) {
const blockTimestampInMill = blockTimestampSecs * 1000;
const date = new Date(blockTimestampInMill); //
// External API

const res = await arbDater.getDate(date);
let blockNumber = res.block; // Try to get the exact block number

return blockNumber;
}

// Total supply - total agETH in the contract
export async function agETHTotalLiquid(blockNumber: number): Promise<bigint> {
const [totalSupply, locked] = await Promise.all([
Expand Down
36 changes: 36 additions & 0 deletions adapters/kelp_gain_linea/src/lib/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,39 @@ export type Row = {
block_number: string;
day: string;
};

export interface GraphQLQuery {
query: string;
collection: string;
}

export type UserBalanceSubgraphEntry = {
id: string;
balance: string;
};

export type PoolPositionSubgraphEntry = {
pool: {
token0Price: string;
token1Price: string;
totalValueLockedETH: string;
totalValueLockedToken0: string;
totalValueLockedToken1: string;
token0: {
symbol: string;
};
token1: {
symbol: string;
};
};
};

export type UserPositionSubgraphEntry = {
id: string;
liquidity: string;
owner: string;
depositedToken0: string;
depositedToken1: string;
withdrawnToken0: string;
withdrawnToken1: string;
};
27 changes: 27 additions & 0 deletions adapters/kelp_gain_linea/src/lib/nile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import BigNumber from "bignumber.js";
import {
getAllV3Positions,
getAllV3Share,
getPoolPosition,
getToken0And1
} from "./v3query";
import { NILE_START_BLOCK } from "./utils";

const NILE_AGETH_RSETH_POOL = "0x6d1ff6a6ea1b54dacd9609949593e7244aea8a4c";

const NILE_SUBGRAPH_BY_DEPLOY_ID =
"https://api.thegraph.com/subgraphs/id/QmPWcLm9K92GkSwD4UtikFqpHbrHgC2tRMUEiaZ8B7p2Xb";

export async function getNileAgEthHodlers(lineaBlockNumber: number) {
if (lineaBlockNumber < NILE_START_BLOCK) {
return [];
}

const balances = await getAllV3Share(
lineaBlockNumber,
NILE_SUBGRAPH_BY_DEPLOY_ID,
NILE_AGETH_RSETH_POOL
);

return balances;
}
28 changes: 28 additions & 0 deletions adapters/kelp_gain_linea/src/lib/nuri.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import BigNumber from "bignumber.js";
import {
getAllV3Positions,
getAllV3Share,
getPoolPosition,
getToken0And1
} from "./v3query";
import { NURI_START_TIMESTAMP } from "./utils";
import { getScrollBlock } from "./fetcher";

const NURI_AGETH_RSETH_POOL = "0x107d317617e82f1871906cf6fee702a5daa4d135";
const API_KEY = process.env.SUBGRAPH_API_KEY || "";
const NURI_SUBGRAPH_BY_GATEWAY = `https://gateway.thegraph.com/api/${API_KEY}/subgraphs/id/Eqr2CueSusTohoTsXCiQgQbaApjuK2ikFvpqkVTPo1y5`;

export async function getNuriAgEthHodlers(timestamp: number) {
if (timestamp < NURI_START_TIMESTAMP) {
return [];
}

const scrollBlockNumber = await getScrollBlock(timestamp);
const balances = await getAllV3Share(
scrollBlockNumber,
NURI_SUBGRAPH_BY_GATEWAY,
NURI_AGETH_RSETH_POOL
);

return balances;
}
84 changes: 68 additions & 16 deletions adapters/kelp_gain_linea/src/lib/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ import {
SPECTRA_YT_ADDRESS
} from "./spectra";
import { agEthToRsEth, rsEthToAgEth } from "./fetcher";
import { getYayAgEthHodlers } from "./yay";
import {
GraphQLQuery,
PoolPositionSubgraphEntry,
UserBalanceSubgraphEntry,
UserPositionSubgraphEntry
} from "./models";
import { getCamelotAgEthHodlers } from "./camelot";
import { getNileAgEthHodlers } from "./nile";
import { getNuriAgEthHodlers } from "./nuri";

const MULTICALL_BATCH_SIZE = 1000;

Expand Down Expand Up @@ -71,16 +81,6 @@ export async function subgraphFetchOne<T>(
return resp[collection];
}

interface GraphQLQuery {
query: string;
collection: string;
}

export type UserBalanceSubgraphEntry = {
id: string;
balance: string;
};

export const USER_BALANCES_QUERY: GraphQLQuery = {
query: gql`
query PositionsQuery($block: Int, $lastId: ID!, $blacklisted: [ID!]!) {
Expand All @@ -100,25 +100,41 @@ export const USER_BALANCES_QUERY: GraphQLQuery = {
};

export async function getAllAgEthHodlers(
blockNumber: number,
ethBlockNumber: number,
lineaBlockNumber: number,
timestamp: number
) {
if (blockNumber < AGETH_BLOCK) {
if (ethBlockNumber < AGETH_BLOCK) {
return [];
}
const positions = await subgraphFetchAllById<UserBalanceSubgraphEntry>(
agETHSubgraph,
USER_BALANCES_QUERY.query,
USER_BALANCES_QUERY.collection,
{
block: blockNumber,
block: ethBlockNumber,
lastId: "0x0000000000000000000000000000000000000000",
blacklisted: Blacklisted
}
);

const pendleShares = await fetchAllPendleShare(blockNumber, timestamp);
const balancerShares = await fetchAllBalancerShare(blockNumber);
const [
pendleShares,
balancerShares,
yayShares,
camelotShares,
nileShares,
nuriShares,
spectraShare
] = await Promise.all([
fetchAllPendleShare(ethBlockNumber, timestamp),
fetchAllBalancerShare(ethBlockNumber),
getYayAgEthHodlers(ethBlockNumber),
getCamelotAgEthHodlers(timestamp),
getNileAgEthHodlers(lineaBlockNumber),
getNuriAgEthHodlers(timestamp),
fetchSpectraPoolShares(ethBlockNumber)
]);

let agETHHodlers = positions.reduce((acc, s) => acc + BigInt(s.balance), 0n);

Expand All @@ -132,7 +148,6 @@ export async function getAllAgEthHodlers(
new BigNumber(0)
);

let spectraShare = await fetchSpectraPoolShares(blockNumber);
let spectraShare_ = spectraShare.reduce(
(acc, s) => acc.plus(BigNumber(s.balance)),
new BigNumber(0)
Expand All @@ -142,6 +157,22 @@ export async function getAllAgEthHodlers(
spectraShare_.toFixed().toString()
);

const nuriAgETHBalance = nuriShares
.reduce((acc, s) => acc.plus(BigNumber(s.balance)), new BigNumber(0))
.toFixed()
.toString();
const nileAgETHBalance = nileShares
.reduce((acc, s) => acc.plus(BigNumber(s.balance)), new BigNumber(0))
.toFixed()
.toString();
const camelotAgETHBalance = camelotShares
.reduce((acc, s) => acc.plus(BigNumber(s.balance)), new BigNumber(0))
.toFixed()
.toString();
const yayAgETHBalance = yayShares
.reduce((acc, s) => acc.plus(BigNumber(s.balance)), new BigNumber(0))
.toFixed()
.toString();
console.log(
`Hodlers agETH: ${ethers.utils.formatEther(agETHHodlers.toString())}`
);
Expand All @@ -155,6 +186,27 @@ export async function getAllAgEthHodlers(
);
console.log(`Spectra agETH: ${spectraAgETHBalance.toString()} `);

console.log(
`Nuri agETH: ${ethers.utils.formatEther(nuriAgETHBalance.toString())}`
);

console.log(
`Nile agETH: ${ethers.utils.formatEther(nileAgETHBalance.toString())}`
);

console.log(
`Camelot agETH: ${ethers.utils.formatEther(camelotAgETHBalance.toString())}`
);

console.log(
`yay agETH: ${ethers.utils.formatEther(yayAgETHBalance.toString())}`
);

positions.push(...yayShares);
positions.push(...nileShares);
positions.push(...nuriShares);
positions.push(...camelotShares);

positions.push(
...pendleShares.map((e) => {
return {
Expand Down
15 changes: 15 additions & 0 deletions adapters/kelp_gain_linea/src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,27 @@ export const SPECTRA_START_BLOCK = 20521549;
export const BALANCER_START_BLOCK = 20520908;
export const PENDLE_START_BLOCK = 20561468;
export const AGETH_BLOCK = 20483695;
export const YAY_START_BLOCK = 20833064;

export const NURI_START_TIMESTAMP = 1727716475; // scroll block 9751486 Sep-30-2024 05:14:35 PM UTC
export const NILE_START_BLOCK = 10144961; // linea block 10144961 Sep-30-2024 04:29:28 PM UTC
export const CAMELOT_START_TIMESTAMP = 1727719180; // arb block 258999746 Sep-30-2024 05:59:40 PM +UTC

const ethProvider = new ethers.providers.JsonRpcProvider(
"https://eth.llamarpc.com"
);

const scrollProvider = new ethers.providers.JsonRpcProvider(
"https://rpc.scroll.io/"
);

const arbProvider = new ethers.providers.JsonRpcProvider(
"https://arb1.arbitrum.io/rpc"
);

export const dater = new EthDater(ethProvider);
export const scrollDater = new EthDater(scrollProvider);
export const arbDater = new EthDater(arbProvider);

export const providerLinea = new ethers.providers.JsonRpcProvider(
"https://rpc.linea.build"
Expand Down
Loading

0 comments on commit b1ca2b6

Please sign in to comment.