From 2c006999e5be448a774aaea8dfa42243318212d9 Mon Sep 17 00:00:00 2001 From: MirthFutures Date: Mon, 21 Oct 2024 14:39:58 -0400 Subject: [PATCH] Add Nuri --- .../address-book/scroll/platforms/index.ts | 1 + .../src/address-book/scroll/platforms/nuri.ts | 4 ++ .../src/address-book/scroll/tokens/tokens.ts | 46 ++++++++++++++++++- scripts/add-solidly.ts | 14 ++++-- src/api/stats/getAmmPrices.ts | 3 ++ src/api/stats/getNonAmmPrices.ts | 2 + src/api/stats/scroll/getNuriApys.js | 18 ++++++++ src/api/stats/scroll/getNuriStablePrices.js | 9 ++++ src/api/stats/scroll/index.js | 3 +- src/data/scroll/nuriStablePools.json | 22 +++++++++ src/data/scroll/nuriVolatilePools.json | 42 +++++++++++++++++ src/utils/fetchAmmPrices.js | 1 + src/utils/fetchSolidlyStableTokenPrices.ts | 15 ++++-- 13 files changed, 170 insertions(+), 10 deletions(-) create mode 100644 packages/address-book/src/address-book/scroll/platforms/nuri.ts create mode 100644 src/api/stats/scroll/getNuriApys.js create mode 100644 src/api/stats/scroll/getNuriStablePrices.js create mode 100644 src/data/scroll/nuriStablePools.json create mode 100644 src/data/scroll/nuriVolatilePools.json diff --git a/packages/address-book/src/address-book/scroll/platforms/index.ts b/packages/address-book/src/address-book/scroll/platforms/index.ts index 5f08327c0..e5bd87f95 100644 --- a/packages/address-book/src/address-book/scroll/platforms/index.ts +++ b/packages/address-book/src/address-book/scroll/platforms/index.ts @@ -1 +1,2 @@ export * from './beefyfinance.js'; +export * from './nuri.js'; diff --git a/packages/address-book/src/address-book/scroll/platforms/nuri.ts b/packages/address-book/src/address-book/scroll/platforms/nuri.ts new file mode 100644 index 000000000..bfedbc1e9 --- /dev/null +++ b/packages/address-book/src/address-book/scroll/platforms/nuri.ts @@ -0,0 +1,4 @@ +export const nuri = { + router: '0xAAA45c8F5ef92a000a121d102F4e89278a711Faa', + voter: '0xAAAf3D9CDD3602d117c67D80eEC37a160C8d9869', +} as const; diff --git a/packages/address-book/src/address-book/scroll/tokens/tokens.ts b/packages/address-book/src/address-book/scroll/tokens/tokens.ts index 4de1e5367..7caadf293 100644 --- a/packages/address-book/src/address-book/scroll/tokens/tokens.ts +++ b/packages/address-book/src/address-book/scroll/tokens/tokens.ts @@ -1,4 +1,3 @@ - import type { Token } from '../../../types/token.js'; const ETH = { @@ -7,7 +6,7 @@ const ETH = { symbol: 'WETH', oracleId: 'WETH', decimals: 18, - chainId: 534352, + chainId: 534352, website: 'https://weth.io/', description: 'Ether or ETH is the native currency built on the Ethereum blockchain.', bridge: 'scroll-canonical', @@ -61,4 +60,47 @@ export const tokens = { logoURI: 'https://hecoinfo.com/token/images/USDTHECO_32.png', documentation: 'https://tether.to/en/how-it-works', }, + NURI: { + name: 'NURI Token', + symbol: 'NURI', + oracleId: 'NURI', + address: '0xAAAE8378809bb8815c08D3C59Eb0c7D1529aD769', + chainId: 534352, + decimals: 18, + logoURI: '', + website: 'https://www.nuri.exchange/', + description: + 'NURI takes concentrated liquidity to the next level, optimizing for high frequency LPs and Layer 2 cost structures. The result is a hyper-efficient liquidity layer designed to attract the most effective liquidity providers, while delivering a clean and simple UX for traders.', + documentation: 'https://docs.nuri.exchange/', + bridge: 'native', + }, + loreUSD: { + name: 'Lore USD', + symbol: 'loreUSD', + oracleId: 'loreUSD', + address: '0x77fbf86399ed764A084F77B9acCb049F3DbC32d2', + chainId: 534352, + decimals: 18, + logoURI: '', + website: 'https://www.lore.finance/', + description: + 'Lore is a decentralized non-custodial liquidity market protocol on Scroll where users can participate as depositors or borrowers. Depositors provide liquidity to the market to earn a passive income, while borrowers are able to borrow in an overcollateralized (perpetually) or undercollateralized (one-block liquidity) fashion.', + documentation: 'https://docs.lore.finance/', + bridge: 'native', + risks: ['NO_TIMELOCK'], + }, + LORE: { + name: 'Lore Token', + symbol: 'LORE', + oracleId: 'LORE', + address: '0x549423E69576b80E91dC836ae37e04209660c4ec', + chainId: 534352, + decimals: 18, + logoURI: '', + website: 'https://www.lore.finance/', + description: + 'Lore is a decentralized non-custodial liquidity market protocol on Scroll where users can participate as depositors or borrowers. Depositors provide liquidity to the market to earn a passive income, while borrowers are able to borrow in an overcollateralized (perpetually) or undercollateralized (one-block liquidity) fashion.', + documentation: 'https://docs.lore.finance/', + bridge: 'native', + }, } as const satisfies Record; diff --git a/scripts/add-solidly.ts b/scripts/add-solidly.ts index a45f93dc8..ff023ffbe 100644 --- a/scripts/add-solidly.ts +++ b/scripts/add-solidly.ts @@ -48,6 +48,9 @@ const { fraxtal: { platforms: { ra }, }, + scroll: { + platforms: { nuri }, + }, } = addressBook; const projects = { @@ -175,6 +178,12 @@ const projects = { volatileFile: '../src/data/fraxtal/raPools.json', voter: ra.voter, }, + nuri: { + prefix: 'nuri', + stableFile: '../src/data/scroll/nuriStablePools.json', + volatileFile: '../src/data/scroll/nuriVolatilePools.json', + voter: nuri.voter, + }, }; const args = yargs.options({ @@ -290,10 +299,7 @@ async function main() { const newPools = [newPool, ...poolsJson]; - fs.writeFileSync( - path.resolve(__dirname, poolsJsonFile), - JSON.stringify(newPools, null, 2) + '\n' - ); + fs.writeFileSync(path.resolve(__dirname, poolsJsonFile), JSON.stringify(newPools, null, 2) + '\n'); console.log(newPool); } diff --git a/src/api/stats/getAmmPrices.ts b/src/api/stats/getAmmPrices.ts index 6e346456a..3f55cc844 100644 --- a/src/api/stats/getAmmPrices.ts +++ b/src/api/stats/getAmmPrices.ts @@ -85,6 +85,7 @@ import moePools from '../../data/mantle/moeLpPools.json'; import lynexPools from '../../data/linea/lynexVolatilePools.json'; import nilePools from '../../data/linea/nileVolatilePools.json'; import raPools from '../../data/fraxtal/raPools.json'; +import nuriPools from '../../data/scroll/nuriVolatilePools.json'; import velodromeModePools from '../../data/mode/velodromeModePools.json'; import { addressBookByChainId } from '../../../packages/address-book/src/address-book'; import { sleep } from '../../utils/time'; @@ -95,6 +96,7 @@ import { fetchVenusPrices } from './bsc/venus/getVenusPrices'; import { getLpBasedPrices } from './getLpBasedPrices'; import uniswapLpPools from '../../data/ethereum/uniswapV2LpPools.json'; import { fetchDexScreenerPriceOracles, OraclePriceRequest } from '../../utils/fetchDexScreenerPrices'; +import { nuri } from '../../../packages/address-book/src/address-book/scroll/platforms'; const INIT_DELAY = 2 * 1000; const REFRESH_INTERVAL = 5 * 60 * 1000; @@ -103,6 +105,7 @@ const REFRESH_INTERVAL = 5 * 60 * 1000; // Implement in case of emergency -> https://github.com/beefyfinance/beefy-api/issues/103 const pools = normalizePoolOracleIds([ ...velodromeModePools, + ...nuriPools, ...raPools, ...moePools, ...equalizerBasePools, diff --git a/src/api/stats/getNonAmmPrices.ts b/src/api/stats/getNonAmmPrices.ts index f20f0e1f2..b68c197b8 100644 --- a/src/api/stats/getNonAmmPrices.ts +++ b/src/api/stats/getNonAmmPrices.ts @@ -76,6 +76,7 @@ import getArbitrumSiloPrices from './arbitrum/getArbitrumSiloPrices'; import getAcrossPrices from './ethereum/getAcrossPrices'; import getGammaMoonbeamPrices from './moonbeam/getGammaMoonbeamPrices'; import getVelodromeModeStablePrices from './mode/getVelodromeModeStablePrices'; +import getNuriStablePrices from './scroll/getNuriStablePrices'; import { ARBITRUM_CHAIN_ID as ARB_CHAIN_ID, BASE_CHAIN_ID, @@ -239,6 +240,7 @@ export async function getNonAmmPrices(tokenPrices: Record): Prom getMellowVeloPrices(BASE_CHAIN_ID, require('../../data/base/mellowAeroPools.json'), tokenPrices), getPearlTridentPrices(tokenPrices), getBaseSiloPrices(tokenPrices), + getNuriStablePrices(tokenPrices), ]; // Setup error logs diff --git a/src/api/stats/scroll/getNuriApys.js b/src/api/stats/scroll/getNuriApys.js new file mode 100644 index 000000000..a5f5ef82f --- /dev/null +++ b/src/api/stats/scroll/getNuriApys.js @@ -0,0 +1,18 @@ +const { SCROLL_CHAIN_ID: chainId } = require('../../../constants'); +const { getSolidlyGaugeApys } = require('../common/getSolidlyGaugeApys'); +const stablePools = require('../../../data/scroll/nuriStablePools.json'); +const volatilePools = require('../../../data/scroll/nuriVolatilePools.json'); + +const pools = [...stablePools, ...volatilePools]; +export const getNuriApys = async () => { + return getSolidlyGaugeApys({ + chainId: chainId, + pools: pools, + oracleId: 'NURI', + oracle: 'tokens', + decimals: '1e18', + reward: '0xAAAE8378809bb8815c08D3C59Eb0c7D1529aD769', + ramses: true, + // log: true, + }); +}; diff --git a/src/api/stats/scroll/getNuriStablePrices.js b/src/api/stats/scroll/getNuriStablePrices.js new file mode 100644 index 000000000..b3bf059c6 --- /dev/null +++ b/src/api/stats/scroll/getNuriStablePrices.js @@ -0,0 +1,9 @@ +const getSolidlyStablePrices = require('../common/getSolidlyStablePrices'); +const pools = require('../../../data/scroll/nuriStablePools.json'); +const { SCROLL_CHAIN_ID: chainId } = require('../../../constants'); + +const getNuriStablePrices = async tokenPrices => { + return await getSolidlyStablePrices(chainId, pools, tokenPrices); +}; + +module.exports = getNuriStablePrices; diff --git a/src/api/stats/scroll/index.js b/src/api/stats/scroll/index.js index 6249492b8..db2f923d2 100644 --- a/src/api/stats/scroll/index.js +++ b/src/api/stats/scroll/index.js @@ -1,6 +1,7 @@ const { getBeefyCowScrollApys } = require('./getBeefyCowScrollApys'); +const { getNuriApys } = require('./getNuriApys'); -const getApys = [getBeefyCowScrollApys]; +const getApys = [getBeefyCowScrollApys, getNuriApys]; const getScrollApys = async () => { const start = Date.now(); diff --git a/src/data/scroll/nuriStablePools.json b/src/data/scroll/nuriStablePools.json new file mode 100644 index 000000000..a7ee249c6 --- /dev/null +++ b/src/data/scroll/nuriStablePools.json @@ -0,0 +1,22 @@ +[ + { + "name": "nuri-usdc-loreusd", + "address": "0x4775dFFd8762eE4C8DE49f4FD6D02A1f0d8f1698", + "gauge": "0x261205218a35286C8A2aaF48070Afc8d72856C54", + "decimals": "1e18", + "chainId": 534352, + "beefyFee": 0.095, + "lp0": { + "address": "0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4", + "oracle": "tokens", + "oracleId": "USDC", + "decimals": "1e6" + }, + "lp1": { + "address": "0x77fbf86399ed764A084F77B9acCb049F3DbC32d2", + "oracle": "tokens", + "oracleId": "loreUSD", + "decimals": "1e18" + } + } +] diff --git a/src/data/scroll/nuriVolatilePools.json b/src/data/scroll/nuriVolatilePools.json new file mode 100644 index 000000000..a5e44079f --- /dev/null +++ b/src/data/scroll/nuriVolatilePools.json @@ -0,0 +1,42 @@ +[ + { + "name": "nuri-weth-lore", + "address": "0x740EE3Ca03CA3f744CD510927b23A1F56966EBab", + "gauge": "0xd58F6FfEA0Eb4C7f1366F0c30F874d498Fe082E8", + "decimals": "1e18", + "chainId": 534352, + "beefyFee": 0.095, + "lp0": { + "address": "0x5300000000000000000000000000000000000004", + "oracle": "tokens", + "oracleId": "WETH", + "decimals": "1e18" + }, + "lp1": { + "address": "0x549423E69576b80E91dC836ae37e04209660c4ec", + "oracle": "tokens", + "oracleId": "LORE", + "decimals": "1e18" + } + }, + { + "name": "nuri-weth-nuri", + "address": "0x8aE1C699C9c62fac468a1E253e15B571b69a7ffe", + "gauge": "0x52edC4da8423266D81F5CdA947F2d1B438d479a1", + "decimals": "1e18", + "chainId": 534352, + "beefyFee": 0.095, + "lp0": { + "address": "0x5300000000000000000000000000000000000004", + "oracle": "tokens", + "oracleId": "WETH", + "decimals": "1e18" + }, + "lp1": { + "address": "0xAAAE8378809bb8815c08D3C59Eb0c7D1529aD769", + "oracle": "tokens", + "oracleId": "NURI", + "decimals": "1e18" + } + } +] diff --git a/src/utils/fetchAmmPrices.js b/src/utils/fetchAmmPrices.js index 913fd5ff4..6cacd7bf1 100644 --- a/src/utils/fetchAmmPrices.js +++ b/src/utils/fetchAmmPrices.js @@ -34,6 +34,7 @@ const MULTICALLS = { 34443: '0x448a3539a591dE3Fb9D5AAE407471D21d40cD315', 169: '0xD4F05538e8e79f3413B4A4E693eC0299E03e3151', 1329: '0xD535BDbc82cc04Ccc360E9f948cD8F9f76084088', + 534352: '0xD985027E547a34d4F7E569B365F24aB87c5a9F73', }; const BATCH_SIZE = 128; diff --git a/src/utils/fetchSolidlyStableTokenPrices.ts b/src/utils/fetchSolidlyStableTokenPrices.ts index 5d691ab23..f688af281 100644 --- a/src/utils/fetchSolidlyStableTokenPrices.ts +++ b/src/utils/fetchSolidlyStableTokenPrices.ts @@ -56,6 +56,17 @@ const tokens: Partial> secondTokenAddress: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', }, ], + scroll: [ + { + oracleId: 'loreUSD', + pool: '0x4775dFFd8762eE4C8DE49f4FD6D02A1f0d8f1698', + firstToken: 'loreUSD', + firstTokenDecimals: '1e18', + secondToken: 'USDC', + secondTokenDecimals: 1e6, + secondTokenAddress: '0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4', + }, + ], }; async function getStablePoolPrices( @@ -77,9 +88,7 @@ async function getStablePoolPrices( const prices = {}; tokenPrice.forEach((v, i) => { const second = chainTokens[i].secondToken; - const amount = new BigNumber(v) - .dividedBy(new BigNumber(chainTokens[i].firstTokenDecimals)) - .toNumber(); + const amount = new BigNumber(v).dividedBy(new BigNumber(chainTokens[i].firstTokenDecimals)).toNumber(); prices[chainTokens[i].oracleId] = tokenPrices[second] / amount; }); return Object.values(prices);