-
Notifications
You must be signed in to change notification settings - Fork 87
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #26 from metavaultorg/main
add metavault adapter
- Loading branch information
Showing
20 changed files
with
1,436 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"name": "metavault", | ||
"version": "1.0.0", | ||
"description": "", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1", | ||
"start": "node dist/index.js", | ||
"compile": "tsc", | ||
"watch": "tsc -w", | ||
"clear": "rm -rf dist" | ||
}, | ||
"keywords": [], | ||
"author": "", | ||
"license": "ISC", | ||
"dependencies": { | ||
"@types/big.js": "^6.2.2", | ||
"big.js": "^6.2.1", | ||
"bignumber.js": "^9.1.2", | ||
"csv-parser": "^3.0.0", | ||
"decimal.js-light": "^2.5.1", | ||
"fast-csv": "^5.0.1", | ||
"jsbi": "^4.3.0", | ||
"tiny-invariant": "^1.3.1", | ||
"toformat": "^2.0.0", | ||
"viem": "^2.8.13" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^20.11.17", | ||
"typescript": "^5.3.3" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import { CHAINS, PROTOCOLS, AMM_TYPES } from "./sdk/config"; | ||
import { getPositionDetailsFromPosition, getPositionsForAddressByPoolAtBlock, getTimestampAtBlock, getTradeLiquidityForAddressByPoolAtBlock } from "./sdk/subgraphDetails"; | ||
(BigInt.prototype as any).toJSON = function () { | ||
return this.toString(); | ||
}; | ||
|
||
interface BlockData { | ||
blockNumber: number; | ||
blockTimestamp: number; | ||
} | ||
|
||
type OutputDataSchemaRow = { | ||
block_number: number; | ||
timestamp: number; | ||
user_address: string; | ||
token_address: string; | ||
token_balance: number; | ||
token_symbol?: string; | ||
usd_price: number; | ||
}; | ||
|
||
|
||
export const getUserTVLByBlock = async ({ | ||
blockNumber, | ||
blockTimestamp, | ||
}: BlockData): Promise<OutputDataSchemaRow[]> => { | ||
return await getPoolData({ blockNumber, blockTimestamp }); | ||
} | ||
|
||
export const getPoolData = async ({ | ||
blockNumber, | ||
blockTimestamp, | ||
}: BlockData): Promise<OutputDataSchemaRow[]> => { | ||
const allCsvRows: OutputDataSchemaRow[] = []; // Array to accumulate CSV rows for all blocks | ||
try { | ||
// const blockTimestamp = new Date(await getTimestampAtBlock(blockNumber)).toISOString(); | ||
const positions = await getPositionsForAddressByPoolAtBlock( | ||
blockNumber, "", "", CHAINS.L2_CHAIN_ID, PROTOCOLS.METAVAULT, AMM_TYPES.UNISWAPV3 | ||
); | ||
|
||
console.log(`Block: ${blockNumber}`); | ||
console.log("Positions: ", positions.length); | ||
|
||
// Assuming this part of the logic remains the same | ||
let positionsWithUSDValue = positions.map(getPositionDetailsFromPosition); | ||
// let lpValueByUsers = getLPValueByUserAndPoolFromPositions(positionsWithUSDValue); | ||
|
||
positionsWithUSDValue.forEach((value, key) => { | ||
// Accumulate CSV row data | ||
if (value.token0DecimalValue > 0) { | ||
allCsvRows.push({ | ||
block_number: blockNumber, | ||
timestamp: blockTimestamp, | ||
user_address: value.owner, | ||
token_address: value.token0.id, | ||
token_balance: value.token0DecimalValue, | ||
usd_price: 0, | ||
}); | ||
} | ||
if (value.token1DecimalValue > 0) { | ||
allCsvRows.push({ | ||
block_number: blockNumber, | ||
timestamp: blockTimestamp, | ||
user_address: value.owner, | ||
token_address: value.token1.id, | ||
token_balance: value.token1DecimalValue, | ||
usd_price: 0, | ||
}); | ||
} | ||
}); | ||
const liquidities = await getTradeLiquidityForAddressByPoolAtBlock( | ||
blockNumber, "", "", CHAINS.L2_CHAIN_ID, PROTOCOLS.METAVAULT, AMM_TYPES.TRADE | ||
); | ||
liquidities.forEach((value, key) => { | ||
if (value.amount > 0) { | ||
allCsvRows.push({ | ||
block_number: blockNumber, | ||
timestamp: blockTimestamp, | ||
user_address: value.user, | ||
token_address: value.asset, | ||
token_balance: value.amount, | ||
usd_price: 0, | ||
}); | ||
} | ||
}); | ||
|
||
} catch (error) { | ||
console.error(`An error occurred for block ${blockNumber}:`, error); | ||
} | ||
return allCsvRows | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
export const readBlocksFromApi = async (startTime: number, endTime: number): Promise<any[]> => { | ||
const results = [] | ||
for (let i = startTime; i <= endTime; i += 3600) { | ||
let response = await fetch(`https://api.lineascan.build/api?module=block&action=getblocknobytime×tamp=${i}&closest=after&apikey=ADD_API_KEY`, { | ||
headers: { "Content-Type": "application/json" }, | ||
}); | ||
|
||
const json = await response.json() | ||
// sleep | ||
await new Promise(r => setTimeout(r, 1000)); | ||
results.push(Number(json.result)) | ||
} | ||
console.log(results); | ||
|
||
return results | ||
|
||
// daily blocks | ||
return [ | ||
1459540, 1473940, 1488339, 1502715, 1517109, 1531509, | ||
1545909, 1560309, 1574707, 1589104, 1603499, 1617898, | ||
1632296, 1646696, 1661096, 1675487, 1689885, 1704285, | ||
1718685, 1733085, 1747485, 1761885, 1779844, 1800972, | ||
1822511, 1844067, 1865652, 1887247, 1908844, 1930429, | ||
1951984, 1973539, 1994976, 2016544, 2038130, 2059720, | ||
2081313, 2102851, 2124303, 2145723, 2166829, 2188347, | ||
2209908, 2231357, 2252825, 2274361, 2295942, 2317539, | ||
2339139, 2360738, 2382328, 2403928, 2425521, 2447121, | ||
2468721, 2490321, 2511921, 2533521, 2555120, 2576720, | ||
2598320, 2619920, 2641520, 2663120, 2684720, 2706320, | ||
2727920, 2749520, 2771120, 2792720, 2814320, 2835920, | ||
2857520, 2879120, 2900720, 2922320, 2943907, 2965507, | ||
2987107, 3008707, 3030307, 3051907, 3073507, 3095107, | ||
3116707 | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
export const enum CHAINS{ | ||
L2_CHAIN_ID = 59144, | ||
} | ||
export const enum PROTOCOLS{ | ||
METAVAULT = 0, | ||
} | ||
|
||
export const enum AMM_TYPES{ | ||
UNISWAPV3 = 0, | ||
TRADE = 1 | ||
} | ||
|
||
export const SUBGRAPH_URLS = { | ||
[CHAINS.L2_CHAIN_ID]: { | ||
[PROTOCOLS.METAVAULT]: { | ||
[AMM_TYPES.UNISWAPV3]: "https://api.studio.thegraph.com/query/55804/linea-v3/version/latest", | ||
[AMM_TYPES.TRADE]: "https://api.studio.thegraph.com/query/55804/linea-trade/version/latest" | ||
} | ||
}, | ||
|
||
} | ||
export const RPC_URLS = { | ||
[CHAINS.L2_CHAIN_ID]: "https://rpc.linea.build" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { Q128 } from '../utils/internalConstants' | ||
import { subIn256 } from '../utils/tickLibrary' | ||
|
||
export abstract class PositionLibrary { | ||
/** | ||
* Cannot be constructed. | ||
*/ | ||
private constructor() {} | ||
|
||
// replicates the portions of Position#update required to compute unaccounted fees | ||
public static getTokensOwed( | ||
feeGrowthInside0LastX128: bigint, | ||
feeGrowthInside1LastX128: bigint, | ||
liquidity: bigint, | ||
feeGrowthInside0X128: bigint, | ||
feeGrowthInside1X128: bigint | ||
) { | ||
const tokensOwed0 = (subIn256(feeGrowthInside0X128, feeGrowthInside0LastX128) * liquidity) / Q128 | ||
|
||
const tokensOwed1 = (subIn256(feeGrowthInside1X128, feeGrowthInside1LastX128) * liquidity) / Q128 | ||
|
||
return [tokensOwed0, tokensOwed1] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { BigNumber } from 'bignumber.js'; | ||
|
||
export const getPrice = (sqrtPriceX96: BigNumber, Decimal0: number, Decimal1: number)=> { | ||
console.log("sqrtPriceX96 : " + sqrtPriceX96.toString()); | ||
console.log("Decimal0 : " + Decimal0); | ||
console.log("Decimal1 : " + Decimal1); | ||
|
||
const twoPower96 = new BigNumber(2).pow(96); | ||
const tenPowerDecimal0 = new BigNumber(10).pow(Decimal0); | ||
const tenPowerDecimal1 = new BigNumber(10).pow(Decimal1); | ||
|
||
// Perform calculations using BigNumber for high precision arithmetic | ||
const priceSquared = (sqrtPriceX96.dividedBy(twoPower96)).pow(2); | ||
|
||
console.log("priceSquared : " + priceSquared.toString()); | ||
const ratio = priceSquared.multipliedBy(tenPowerDecimal0).dividedBy(tenPowerDecimal1); | ||
console.log("ratio : " + ratio.toString()); | ||
// Convert to string with fixed decimal places for display | ||
const buyOneOfToken0 = ratio.toFixed(Decimal1); | ||
const buyOneOfToken1 = new BigNumber(1).div(ratio).toFixed(Decimal0); | ||
|
||
console.log(`price of token0 in value of token1 : ${buyOneOfToken0}`); | ||
console.log(`price of token1 in value of token0 : ${buyOneOfToken1}`); | ||
console.log(""); | ||
|
||
// Convert to lowest decimal representation for display | ||
const buyOneOfToken0Wei = ratio.multipliedBy(tenPowerDecimal1).toFixed(0); | ||
const buyOneOfToken1Wei = new BigNumber(1).div(ratio).multipliedBy(tenPowerDecimal0).toFixed(0); | ||
|
||
console.log(`price of token0 in value of token1 in lowest decimal : ${buyOneOfToken0Wei}`); | ||
console.log(`price of token1 in value of token1 in lowest decimal : ${buyOneOfToken1Wei}`); | ||
console.log(""); | ||
} | ||
|
||
// // Example usage with BigNumber inputs: | ||
// // Convert string inputs to BigNumber. Ensure the input values are strings to prevent precision loss. | ||
// getPrice(new BigNumber('3956146591263498000000000'), 18, 6); |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
function getTickAtSqrtPrice(sqrtPriceX96: bigint): number { | ||
const Q96: bigint = 2n ** 96n; | ||
return Math.floor(Math.log(Number(sqrtPriceX96 / Q96) ** 2) / Math.log(1.0001)); | ||
} | ||
|
||
export const getTokenAmounts = async( | ||
liquidity: bigint, | ||
sqrtPriceX96: bigint, | ||
tickLow: number, | ||
tickHigh: number, | ||
Decimal0: number, | ||
Decimal1: number | ||
)=> { | ||
const Q96: bigint = 2n ** 96n; | ||
const sqrtRatioA: number = Math.sqrt(1.0001 ** tickLow); | ||
const sqrtRatioB: number = Math.sqrt(1.0001 ** tickHigh); | ||
const currentTick: number = getTickAtSqrtPrice(sqrtPriceX96); | ||
const sqrtPrice: number = Number(sqrtPriceX96 / Q96); | ||
let amount0: bigint = 0n; | ||
let amount1: bigint = 0n; | ||
|
||
// print all the values | ||
console.log("liquidity : " + liquidity.toString()); | ||
console.log("sqrtPriceX96 : " + sqrtPriceX96.toString()); | ||
console.log("tickLow : " + tickLow); | ||
console.log("tickHigh : " + tickHigh); | ||
console.log("Decimal0 : " + Decimal0); | ||
console.log("Decimal1 : " + Decimal1); | ||
console.log("sqrtRatioA : " + sqrtRatioA); | ||
console.log("sqrtRatioB : " + sqrtRatioB); | ||
console.log("currentTick : " + currentTick); | ||
console.log("sqrtPrice : " + sqrtPrice); | ||
|
||
|
||
if (currentTick < tickLow) { | ||
amount0 = BigInt(Math.floor(Number(liquidity) * ((sqrtRatioB - sqrtRatioA) / (sqrtRatioA * sqrtRatioB)))); | ||
} else if (currentTick >= tickHigh) { | ||
amount1 = BigInt(Math.floor(Number(liquidity) * (sqrtRatioB - sqrtRatioA))); | ||
} else if (currentTick >= tickLow && currentTick < tickHigh) { | ||
amount0 = BigInt(Math.floor(Number(liquidity) * ((sqrtRatioB - sqrtPrice) / (sqrtPrice * sqrtRatioB)))); | ||
amount1 = BigInt(Math.floor(Number(liquidity) * (sqrtPrice - sqrtRatioA))); | ||
} | ||
let amount0Human: string = (Number(amount0) / 10 ** Decimal0).toFixed(Decimal0); | ||
let amount1Human: string = (Number(amount1) / 10 ** Decimal1).toFixed(Decimal1); | ||
|
||
console.log("Amount Token0 in lowest decimal: " + amount0.toString()); | ||
console.log("Amount Token1 in lowest decimal: " + amount1.toString()); | ||
console.log("Amount Token0 : " + amount0Human); | ||
console.log("Amount Token1 : " + amount1Human); | ||
return [amount0, amount1]; | ||
} |
Oops, something went wrong.